1
00:00:04,840 --> 00:00:10,380
Okay, let's continue where we left off in
the last video.

2
00:00:10,380 --> 00:00:17,580
The next step is to remove the about_weblink
widget from our about layout, and include

3
00:00:17,580 --> 00:00:23,480
the about_web_url layout at the position it was at.

4
00:00:23,480 --> 00:00:30,620
Open about in the designer

5
00:00:30,620 --> 00:00:36,500
and delete the textView about_weblink.

6
00:00:38,269 --> 00:00:44,449
Next, drag an include widget from the
containers section,

7
00:00:46,760 --> 00:00:53,940
and place it between about_copyright and about_email.

8
00:00:53,940 --> 00:00:58,520
It's easier to place it on the component tree,
rather than trying to position it in the

9
00:00:58,520 --> 00:01:11,620
design window. When the resources dialogue appears,
choose about_web_url.

10
00:01:11,620 --> 00:01:18,420
The layout_width should be set to match_parent
and the layout_height to wrap_content.

11
00:01:18,420 --> 00:01:23,530
Our layout's looking pretty good in
the designer now, but our included layout

12
00:01:23,530 --> 00:01:29,920
won't have a top margin. The "Instructions
available at" text appears too close to

13
00:01:29,920 --> 00:01:35,290
the copyright message. We can fix that by
setting the top margin on the include

14
00:01:35,290 --> 00:01:38,940
widget to 8dp.

15
00:01:48,530 --> 00:01:54,980
We're good to go, so I'll run the app on
my API 28 emulator, and the API 17

16
00:01:54,980 --> 00:01:58,390
emulator as well.

17
00:02:18,209 --> 00:02:23,129
You may struggle to have two emulators
running at the same time, in which case,

18
00:02:23,129 --> 00:02:26,790
run the one after the other, but that
looks pretty good.

19
00:02:26,790 --> 00:02:33,469
The about dialogue for both versions
look as similar as we can expect.

20
00:02:42,569 --> 00:02:49,680
The URL for the API 17 device still
isn't clickable. The final thing to fix

21
00:02:49,680 --> 00:02:55,730
that, is to add an onClickListener
to the TextView.

22
00:03:26,510 --> 00:03:31,700
It's just a standard onClickListener,
only we've attached it to a TextView

23
00:03:31,700 --> 00:03:37,970
instead of a button. When the TextView's
tapped we create a new intent, and use

24
00:03:37,970 --> 00:03:44,480
Intent.ACTION_VIEW as the
action. Control click on ACTION_VIEW,

25
00:03:44,480 --> 00:03:51,260
or command click on a
Mac,

26
00:03:51,260 --> 00:03:53,720
to view the source, and this is the

27
00:03:53,720 --> 00:03:58,579
most common action performed when
calling an intent with data. The comment

28
00:03:58,579 --> 00:04:03,680
in the code describes the behavior with
different types of data, such as opening

29
00:04:03,680 --> 00:04:08,840
the email program with the To address
filled in, or dialing a phone number.

30
00:04:08,840 --> 00:04:13,340
Back to our code.

31
00:04:13,340 --> 00:04:17,740
Next, we get the text from
the TextView converted to a string,

32
00:04:17,740 --> 00:04:24,960
and add it to the intent's data as a URI. In
the API 21 and above layout,

33
00:04:24,960 --> 00:04:32,280
the about_url TextView won't be found,
so the onClickListener won't be set.

34
00:04:32,280 --> 00:04:38,599
We get the URI by calling the uri.parse
function, and you'll have found almost

35
00:04:38,600 --> 00:04:44,860
identical code to this, when searching
for how to launch the browser using a URL.

36
00:04:44,860 --> 00:04:56,000
Okay, it won't quite work because we
haven't started the URL with either http:// or https://

37
00:04:56,000 --> 00:04:58,120
but we'll run it like this, so we

38
00:04:58,130 --> 00:05:04,010
can see which exception we need to catch.
Open the about dialogue on the API 17

39
00:05:04,010 --> 00:05:08,410
device and tap the URL.

40
00:05:20,860 --> 00:05:27,800
The app crashes as expected, because
there's no scheme in our URI.

41
00:05:38,580 --> 00:05:43,840
Crashing to find out that we get an
activity not found exception, was a lot

42
00:05:43,840 --> 00:05:50,910
quicker than reading the documentation.
We'll trap that exception in our code.

43
00:06:02,689 --> 00:06:09,129
and we'll test that it doesn't crash
before modifying the string resource.

44
00:06:21,640 --> 00:06:26,940
Now, we get a toast message instead of a
crash, which is much better.

45
00:06:26,940 --> 00:06:32,620
We're about to go into the strings resource file and
this message should really be coming

46
00:06:32,620 --> 00:06:37,599
from a string resource. At the moment,
Android Studio isn't giving a warning

47
00:06:37,599 --> 00:06:42,699
about that, but that may change in the
future. It's a good idea to put all

48
00:06:42,699 --> 00:06:48,610
messages that the user can see, into a
string resource. I'll cut that text into

49
00:06:48,610 --> 00:07:12,900
my clipboard without the speech marks,
and replace it with the string resource ID.

50
00:07:12,900 --> 00:07:18,300
Okay, the final change to complete the
challenge, is to change our string

51
00:07:18,300 --> 00:07:23,699
resource to include the URL scheme. I'll
also create the error resource while

52
00:07:23,699 --> 00:07:26,120
we're there.

53
00:07:47,719 --> 00:07:53,589
I'll also put speech marks around the URL.

54
00:07:56,169 --> 00:08:01,879
Try it without the speech marks to see
why they're necessary. Pay careful

55
00:08:01,879 --> 00:08:06,979
attention to the display in the dialogue,
and also watch where the browser tries

56
00:08:06,979 --> 00:08:12,529
to go when you click the link. I won't do
that in the video, just get into the

57
00:08:12,529 --> 00:08:18,229
habit of enclosing URL string resources
in speech marks. Okay.

58
00:08:18,229 --> 00:08:22,809
Run the app and now it works fine.

59
00:08:32,070 --> 00:08:38,250
We can visit the webpage on our API 17
device. You may still get the warning

60
00:08:38,250 --> 00:08:44,800
that a secure connection could not be
established, but you can just click OK on that.

61
00:08:44,800 --> 00:08:49,560
On a real device that's receiving
updates, that message shouldn't appear.

62
00:08:49,560 --> 00:08:54,959
Alright, check that the link still
works in the API 28 emulator, to make

63
00:08:54,959 --> 00:08:58,970
sure that our changes haven't broken
anything.

64
00:09:17,170 --> 00:09:22,089
We can tell the different layouts are
being used, because the API 28 device

65
00:09:22,089 --> 00:09:29,559
doesn't have https: before the URL.
AutoLink takes care of inserting the

66
00:09:29,560 --> 00:09:36,000
schema for things it recognizes as web
addresses, so we didn't have to specify it.

67
00:09:36,000 --> 00:09:40,700
If you decided to use the same layout
for for all versions, then that's fine.

68
00:09:40,700 --> 00:09:48,060
You can include https:// in an autoLink
TextView and it'll work.

69
00:09:48,060 --> 00:09:53,220
And, that's our challenge completed, so
congratulations if you got it working.

70
00:09:53,220 --> 00:09:58,119
As we've seen, there can be a certain amount
of work involved in supporting earlier

71
00:09:58,119 --> 00:10:02,559
versions of Android, and giving our apps
the same features on these earlier

72
00:10:02,559 --> 00:10:08,319
versions. The code in this solution takes
advantage of the native capabilities of

73
00:10:08,319 --> 00:10:13,929
API 21 devices and above, and only uses
the onClickListener

74
00:10:13,929 --> 00:10:20,679
on devices before API 21. The clever and
helpful thing about different

75
00:10:20,679 --> 00:10:24,910
versions of resource files, is that we
don't have to include a load of tests

76
00:10:24,910 --> 00:10:30,129
for API versions. Android will
automatically use the correct variant,

77
00:10:30,129 --> 00:10:35,889
depending on the device our app's running
on. So just like it knows when to use the

78
00:10:35,889 --> 00:10:40,419
landscape and portrait variants of
layouts, it also knows when it should use

79
00:10:40,420 --> 00:10:48,160
our API 21 version of the about_web _url layout.

80
00:10:48,160 --> 00:10:52,700
I'll finish by addressing a question
that you may be wondering about.

81
00:10:52,700 --> 00:10:59,259
Why didn't I create a v21 version of strings.xml, and put the about_weblink

82
00:10:59,260 --> 00:11:06,840
string resource in there,
instead of creating about_weblink_21.

83
00:11:06,840 --> 00:11:10,860
You will sometimes
want to do that, but before you do,

84
00:11:10,860 --> 00:11:16,620
it's worth watching this video from
Google I/O 2016.

85
00:11:16,620 --> 00:11:20,200
The video's at the URL that you can read in the address bar.

86
00:11:20,200 --> 00:11:24,520
It's worth watching the whole talk, but the bit that's relevant here,

87
00:11:24,520 --> 00:11:30,200
is at about 32 minutes and 40 seconds into the video.

88
00:11:46,040 --> 00:11:50,460
Wojtek Kalicinski, one of
Google's engineers, explains about the

89
00:11:50,470 --> 00:11:55,360
impact this can have on the size of
your app. As we're creating a separate

90
00:11:55,360 --> 00:12:00,250
layout, there's no advantage to keeping
the string resource ID the same, and if

91
00:12:00,250 --> 00:12:04,779
you watch that video, you'll see that
there are potentially big disadvantages

92
00:12:04,779 --> 00:12:10,029
in terms of the size of your app. So
that's why I didn't create a v21 string

93
00:12:10,029 --> 00:12:15,820
resource file, just for a single string
resource. Even with a handful, I still

94
00:12:15,820 --> 00:12:21,040
wouldn't put them in their own resource
file. Okay, in the next section, we'll

95
00:12:21,040 --> 00:12:26,580
create a settings dialog for our app.
I'll see you then.

