$34.99
Assignment 4 – Civil Advocacy App
Uses: Location Services, Internet, Google APIs, Images, Picasso Library, Implicit Intents, TextView Links App Highlights:
• This app will acquire and display an interactive list of political officials that represent the current location (or a specified location) at each level of government.
• Android Fused Location Provider services will be used to determine the user’s current location.
• The Google Civic Information API will be used to acquire the government official data (via REST service and JSON results).
• You will need to use a different layout for landscape orientation for 2 of the activities in this application. Those details are specified later in the document.
• Clicking on an official’s list entry opens a detailed view of that individual government representative.
• Clicking on the photo of an official will display a Photo Activity, showing a larger version of the photo.
• Your manifest should add permissions for ACCESS_FINE_LOCATION (and ACCESS_COARSE_LOCATION) and INTERNET
• The application is made up of 4 activities, shown below:
1) Main Activity
information and manual location
user-specified location)
officials (List scrolls up & down)
entry to open a new activity
© Christopher Hield
CS 442 Mobile Applications
Development (Android Section)
2) Official Activity Scrolls information does not completely fit on the visible A ScrollView must be used here in case the
-Office
-Name
-Party
party:
© Christopher Hield
CS 442 Mobile Applications
Development (Android Section)
© Christopher Hield
CS 442 Mobile Applications
Development (Android Section)
4) About Activity
App Title
API Attribution (clickable link to
https://developers.google.com/civic-
information/). Note: This is a TextView
with the text underlined, and an onClick
defined to go to the Google Civic
Information URL).
Full-sized background image
data & Version)
© Christopher Hield
CS 442 Mobile Applications
Development (Android Section)
Internet Data:
Downloading data for the government officials requires a download via the Google Civic Information API. The Civic Information API lets you enter an address, a city/state, or a zip code to look up the data properties for the elected officials in those districts.
NOTE: You MUST sign up with Google to get an API key. Your API KEY must be supplied with all Google Civic Information API queries. You can get a free API key by following the instructions at:
https://developers.google.com/civic-information/docs/using_api
Follow the instructions for “Acquiring and using an API key”. The type of credential you need to create is “API Key” (not “OAuth client ID” and not “Service account key”). This is a very quick and easy process. The API key will be a long string of characters. The results of Civic Information API calls are returned in JSON format. The content of the returned results is described later in this section.
Query Format: https://www.googleapis.com/civicinfo/v2/representatives?key=Your-API-Key&address=address
For example, if your API Key was “ABC123xyz” and the address was “1600 N Wells St, Chicago, IL”, your full URL would be:
https://www.googleapis.com/civicinfo/v2/representatives?key=ABC123xyz&address=1600 W North Ave, Chicago, IL
For example, if your API Key was “ABC123xyz” and the address was “Denver, CO”, your full URL would be:
https://www.googleapis.com/civicinfo/v2/representatives?key=ABC123xyz&address=Denver, CO NOTE: Internet calls must be made using Android Volley Google Civic Information API Results Example:
The JSON Object results you receive contains 4 sections, described in detail below. The normalizedInput section contains location details for the results provided. The divisions section lists political geographic divisions, like a country, state, county, or legislative district (we do not need this section for our application). The offices section lists the political positions governing the specified location. The officials section lists people presently serving in the offices specified in the offices section.
High-level view of JSON Object results:
{
"normalizedInput": { We need this section, it is accessed as a JSONObject (described later)
… Data will be here
},
"kind": "civicinfo#representativeInfoResponse", We do not need this "divisions": { We do not need this
… Data will be here, we do not need this section
},
"offices": [ We need this section, it is accessed as a JSONArray (described later)
… Data will be here
],
"officials": [ We need this section, it is accessed as a JSONArray (described later)
… Data will be here
]
}
© Christopher Hield
CS 442 Mobile Applications
Development (Android Section)
JSON Section Details (omitting those sections we will not use):
1) The “normalizedInput” JSONObject contains the following: "normalizedInput": {
"line1": "1350 N Wells St", We want this for the location display in our activities
"city": "Chicago", We want this for the location display in our activities
"state": "IL", We want this for the location display in our activities
"zip": "60610" We want this for the location display in our activities
},
2) The “offices” JSONArray contains the following:
"offices": [
{ We want this, the “office” title
"name": "President of the United States",
"divisionId": "ocd-division/country:us",
"levels": [
"country"
],
"roles": [ We want this, it is the index into the “officials” JSONArray (see
"headOfState", the next section) which contains the details of the person that
"headOfGovernment"
holds this office.
],
"officialIndices": [
0 NOTE: There can be more than one index as time offices have
] multiple representatives.
},
{
We want this, the “office” title
"name": "United States Senate",
"divisionId": "ocd-division/country:us/state:il",
"levels": [
"country"
],
"roles": [
"legislatorUpperBody" We want this, it is the index into the “officials” JSONArray (see
], the next section) which contains the details of the person that
"officialIndices": [
2, holds this office.
3
] NOTE: There can be more than one index as time offices have
}, multiple representatives.
… The above sections repeat many times, once per government office
],
© Christopher Hield
CS 442 Mobile Applications
Development (Android Section)
3) The “officials” JSONArray contains the following:
"officials": [ This is the first JSONObject is the first official (index 0). This index
{ corresponds to the "officialIndices" we found in the "offices"
"name": "Joseph R. Biden", section This is the name of the earlier. person that holds this office.
"address": [
{ This is the Address (check for possible line1, line2 & line3 –
"line1": "The White House",
concatenate them into one String), City, State & Zip Code of this
"line2": "1600 Pennsylvania Avenue NW",
person’s office
"city": "Washington",
"state": "DC",
This is the political party of this person: “Republican”,
"zip": "20500"
“Democratic/Democrat”, or “Unknown”. Note this section might
} also be omitted – consider that as party “Unknown”.
],
"party": "Democratic Party",
"phones": [
– just use the first entry. Note this section might also be
"(202) 456-1111"
], omitted.
"urls": [
"http://www.whitehouse.gov/"
], use the first entry. Note this section might also be omitted.
"emails": [
"email@address.com"
] – use only the first entry. Note this section might also be
"photoUrl": "https://www.whitehouse.gov/sites/whitehouse.gov/files/images/45/SomePhoto.jpg",
"channels": [
This is the URL to the person’s photo. Note this section might also be
{
omitted. In this case, use a “place holder” photo.
"type": "Facebook",
"id": "whitehouse"
These are the user ids for the related social media channels. There will
},
be up to three entries. Possible entries are:
{
"type": "Twitter", • Facebook
"id": "whitehouse"
• Twitter
},
{ • YouTube
"type": "YouTube",
"id": "whitehouse" Some or all of these 3 social channel items might be omitted.
}
]
}, {
… The above section repeats many times, once per government official. Remember – the first official in the JSONArray is index 0. The second official in this JSONArray is index 1, the third second official in this JSONArray is index 2, and so on.
}
]
© Christopher Hield
CS 442 Mobile Applications
Development (Android Section)
Using Picasso for Photo Downloads
Downloading the photos of the officials in the Official Activity and the Photo Activity must use the Picasso library (as was discussed in class). Note that you can turn on the Picasso logging if necessary, to get info on what the Picasso library is doing by adding he following to your code once you have created the Picasso object:
picasso.setLoggingEnabled(true);
Social Media Implicit Intent Examples
The following are examples of how you should code the social-media implicit intents (some of these have been seen already in class examples, but are reproduced here for convenience):
Twitter (example onClick method to be associated with the Twitter ImageView icon):
public void twitterClicked(View v) {
Intent intent = null;
String name = <the official’s twitter id from download>; try {
// get the Twitter app if possible getPackageManager().getPackageInfo("com.twitter.android", 0); intent = new Intent(Intent.ACTION_VIEW, Uri.parse("twitter://user?screen_name=" + name)); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
} catch (Exception e) {
// no Twitter app, revert to browser intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://twitter.com/" + name));
} startActivity(intent);
}
Facebook (example onClick method to be associated with the Facebook ImageView icon):
public void facebookClicked(View v) {
String FACEBOOK_URL = "https://www.facebook.com/" + <the official’s facebook id>;
String urlToUse;
PackageManager packageManager = getPackageManager(); try { int versionCode = packageManager.getPackageInfo("com.facebook.katana", 0).versionCode; if (versionCode >= 3002850) { //newer versions of fb app urlToUse = "fb://facewebmodal/f?href=" + FACEBOOK_URL;
} else { //older versions of fb app urlToUse = "fb://page/" + channels.get("Facebook");
}
} catch (PackageManager.NameNotFoundException e) { urlToUse = FACEBOOK_URL; //normal web url
}
Intent facebookIntent = new Intent(Intent.ACTION_VIEW); facebookIntent.setData(Uri.parse(urlToUse)); startActivity(facebookIntent); }
© Christopher Hield
CS 442 Mobile Applications
Development (Android Section)
YouTube (example onClick method to be associated with the YouTube ImageView icon):
public void youTubeClicked(View v) {
String name = <the official’s youtube id from download>; Intent intent = null; try { intent = new Intent(Intent.ACTION_VIEW); intent.setPackage("com.google.android.youtube"); intent.setData(Uri.parse("https://www.youtube.com/" + name)); startActivity(intent);
} catch (ActivityNotFoundException e) { startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse("https://www.youtube.com/" + name)));
}
}
© Christopher Hield
CS 442 Mobile Applications
Development (Android Section)
Provided Icons
To insure a consistent and professional appearance of our application, the following image files are being provided to you for use in this assignment. You can simply download them, add them to your Android Studio project, and use them with your ImageViews.
About Activity Background Placeholder Image Launcher Icon
Democratic Party Logo
Separator Image (to add to the end of your list entry layout)
Facebook icon
Republican Party Logo
Twitter icon
Default Official Image
YouTube icon
Bad photo URL image
© Christopher Hield 10 of 16
CS 442 Mobile Applications
Development (Android Section)
Application Behavior Diagrams:
1) Main Activity On startup, the current location zip code to populate the list with application should use the device’s
officials.
© Christopher Hield 11 of 16
CS 442 Mobile Applications
Development (Android Section)
2) Manually setting the location
3) Opening the About Activity
© Christopher Hield 12 of 16
CS 442 Mobile Applications
Development (Android Section)
web browser.
© Christopher Hield 13 of 16
CS 442 Mobile Applications
Development (Android Section)
6) Viewing an individual Official’s Photo Activity:
7) If no location or no internet connection:
On StartUp or new specified
© Christopher Hield 14 of 16
CS 442 Mobile Applications
Development (Android Section)
Development Plan
1) Create the base app:
a. MainActivity with RecyclerView
b. Official Class
c. RecyclerView Adapter
d. RecyclerView ViewHolder
e. Create fake “dummy” officials to populate the list in the MainActivity onCreate.
f. Add the onClick methods. The onClick can open a Toast message for now.
g. Address options-menu item opens the dialog, on entry you can open a Toast message for now.
h. Create the About Activity – opens when MainActivity “About” options menu item is selected.
2) Add the location code.
a. Add the location code that determines the device’s zip code (this happens in onCreate).
b. Instead of using that zip code to make the Google API call, you can open a Toast message that displays the zip code for now.
3) Add the Official Activity:
a. This activity opens when an entry in the list of elected officials is clicked on.
b. You can use the data in your test (dummy) “official” objects to test this activity.
c. Any test data you don’t have (i.e., missing data) should be properly handled in your activity.
d. The social media ImageView onClick’s should open a Toast message that displays the name of the social media for now.
e. Remember to create the separate layout for landscape orientation.
4) Add the Google Civic Information API elements:
a. Create the Volley Google Civic Information API calls and parse the data creating a list of “official” objects.
b. Remove the use of dummy data from your app (now you will have real data).
c. Remove the location Toast message. Instead, here you use the device’s zip code (or a manually entered location) to make the API call.
d. This should result in a populated list of Official objects in your MainActivity that is then displayed in the RecyclerView.
e. Add the Photo Activity, opened when an official’s photo is clicked in the Official Activity
f. Remember to create the separate layout for landscape orientation.
5) Test the app very thoroughly and review your implementation against all requirements multiple times.
© Christopher Hield 15 of 16
CS 442 Mobile Applications
Development (Android Section)
Assignment Assistance
Submissions & Grading
1) Submissions must consist of your zipped project folder (please execute Build =>Clean Project before generating the zip file).
2) Submissions should reflect the concepts and practices we cover in class, and the requirements specified in this document.
4) Grading will be based upon the presence and proper functionality of all features and behaviors described in this document. NOTE: All descriptions and images constitute the requirements for this assignment.
5) Grading will be performed with the following SDK details:
o Project Compile & Target SDK Version: 30 o Project Minimum SDK Version: 25
6) Grading will be performed on emulator devices with the following characteristics:
Resolution Details Example Emulators
1080 x 1920 With Playstore Pixel, Pixel 2, Nexus 5, Nexus 5X
1080 x 2220 or 2280 With Playstore Pixel 3a, Pixel 4
If you do not understand anything in this handout, please ask.
Otherwise the assumption is that you understand the content.
Unsure? Ask!
© Christopher Hield 16 of 16