Skip to content
Snippets Groups Projects
Commit a458ad7f authored by Andrej Rasevic's avatar Andrej Rasevic
Browse files

added Lab10_LocationLab student distribution

parent 721c45c9
No related branches found
No related tags found
No related merge requests found
Showing
with 1234 additions and 0 deletions
File added
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
buildToolsVersion "26.0.1"
defaultConfig {
applicationId "course.labs.locationlab"
minSdkVersion 21
targetSdkVersion 26
testApplicationId "course.labs.locationlab.test"
testInstrumentationRunner "android.test.InstrumentationTestRunner"
testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
androidTestCompile 'com.jayway.android.robotium:robotium-solo:5.6.0'
androidTestCompile 'com.android.support.test:rules:0.5'
androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.1'
compile 'com.android.support:support-annotations:26.0.0'
compile 'com.android.support:support-v4:26.0.1'
}
configurations.all {
resolutionStrategy.force 'com.android.support:support-annotations:26.0.0'
}
\ No newline at end of file
File added
package course.labs.locationlab.tests;
import android.content.Context;
import android.content.Intent;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SdkSuppress;
import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.UiObjectNotFoundException;
import android.support.test.uiautomator.UiSelector;
import android.support.test.uiautomator.Until;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.regex.Pattern;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
@RunWith(AndroidJUnit4.class)
@SdkSuppress(minSdkVersion = 21)
public class PermGrantedTest {
private static final int LAUNCH_TIMEOUT = 10000;
private UiDevice mDevice;
private static final String BASIC_SAMPLE_PACKAGE
= "course.labs.locationlab";
@Before
public void startMainActivityFromHomeScreen() {
// Initialize UiDevice instance
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
// Start from the home screen
mDevice.pressHome();
// Wait for launcher
final String launcherPackage = mDevice.getLauncherPackageName();
assertThat(launcherPackage, is(notNullValue()));
mDevice.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)),
LAUNCH_TIMEOUT);
// Launch the app
Context context = InstrumentationRegistry.getContext();
final Intent intent = context.getPackageManager()
.getLaunchIntentForPackage(BASIC_SAMPLE_PACKAGE);
if (null == intent) fail();
// Clear out any previous instances
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
context.startActivity(intent);
// Wait for the app to appear
mDevice.wait(Until.hasObject(By.pkg(BASIC_SAMPLE_PACKAGE).depth(0)),
LAUNCH_TIMEOUT);
//Give permission if it is not given already
//
UiObject2 PermissionDialog = mDevice.wait(Until.findObject(By.text("ALLOW")), 2000);
if (PermissionDialog != null)
PermissionDialog.click();
}
@Test
public void testPermissionRequested() {
UiObject2 getNewPlace = mDevice.wait(Until.findObject(By.text("Get New Place")), 2000);
assertNotNull("Permission wasn't granted", getNewPlace);
getNewPlace.click();
}
}
package course.labs.locationlab.tests;
import android.test.ActivityInstrumentationTestCase2;
import com.robotium.solo.Solo;
import course.labs.locationlab.PlaceViewActivity;
public class TestNoCountryLocation extends
ActivityInstrumentationTestCase2<PlaceViewActivity> {
private Solo solo;
public TestNoCountryLocation() {
super(PlaceViewActivity.class);
}
public void setUp() throws Exception {
solo = new Solo(getInstrumentation(), getActivity());
PlaceViewActivity.sHasNetwork = false;
}
@Override
public void tearDown() throws Exception {
solo.finishOpenedActivities();
}
public void testRun() {
int delay = 2000;
int longDelay = 5000;
// Wait for activity: 'course.labs.locationlab.PlaceViewActivity'
solo.waitForActivity(course.labs.locationlab.PlaceViewActivity.class,
delay);
// Click on action bar item
solo.clickOnActionBarItem(course.labs.locationlab.R.id.place_no_country);
solo.sleep(delay);
// Click on Get New Place
solo.clickOnView(solo.getView(course.labs.locationlab.R.id.footer));
String noCountryString = solo
.getString(course.labs.locationlab.R.string.no_country_string);
// Assert that no country toast is shown
assertTrue(noCountryString + " is not shown!",
solo.waitForText(noCountryString, 1, longDelay));
}
}
package course.labs.locationlab.tests;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
import com.robotium.solo.Solo;
import course.labs.locationlab.PlaceViewActivity;
import course.labs.locationlab.R;
public class TestOneValidLocation extends
ActivityInstrumentationTestCase2<PlaceViewActivity> {
private Solo solo;
public TestOneValidLocation() {
super(PlaceViewActivity.class);
}
public void setUp() throws Exception {
solo = new Solo(getInstrumentation(), getActivity());
PlaceViewActivity.sHasNetwork = false;
}
@Override
public void tearDown() throws Exception {
solo.finishOpenedActivities();
}
public void testRun() {
int delay = 5000;
int longDelay = 8000;
// Wait for activity: 'course.labs.locationlab.PlaceViewActivity'
solo.waitForActivity(course.labs.locationlab.PlaceViewActivity.class,
2000);
// Click on action bar item
solo.clickOnActionBarItem(course.labs.locationlab.R.id.place_one);
solo.sleep(delay);
// Click on Get New Place
solo.clickOnView(solo.getView(course.labs.locationlab.R.id.footer));
// Assert that PlaceBadge is shown
assertTrue("PlaceBadge is not shown!", solo.waitForText(
solo.getString(R.string.the_greenhouse_string), 1, longDelay));
// Click on PlaceBadge
solo.clickOnText(solo.getString(R.string.the_greenhouse_string));
solo.sleep(delay);
assertTrue("Detail view not shown!", solo.waitForText("Date"));
}
}
package course.labs.locationlab.tests;
import android.test.ActivityInstrumentationTestCase2;
import com.robotium.solo.Solo;
import course.labs.locationlab.PlaceViewActivity;
import course.labs.locationlab.R;
public class TestSameLocation extends ActivityInstrumentationTestCase2<PlaceViewActivity> {
private Solo solo;
public TestSameLocation() {
super(PlaceViewActivity.class);
}
public void setUp() throws Exception {
solo = new Solo(getInstrumentation(), getActivity());
PlaceViewActivity.sHasNetwork = false;
}
@Override
public void tearDown() throws Exception {
solo.finishOpenedActivities();
}
public void testRun() {
int delay = 2000;
int longDelay = 5000;
// Wait for activity: 'course.labs.locationlab.PlaceViewActivity'
solo.waitForActivity(course.labs.locationlab.PlaceViewActivity.class, delay);
// Click on action bar item
solo.clickOnActionBarItem(course.labs.locationlab.R.id.place_one);
solo.sleep(delay);
// Click on Get New Place
solo.clickOnView(solo.getView(course.labs.locationlab.R.id.footer));
solo.sleep(2000);
// Assert that PlaceBadge is shown
assertTrue("PlaceBadge is not shown!", solo.waitForText(
solo.getString(R.string.the_greenhouse_string), 1, longDelay));
// Click on action bar item
solo.clickOnActionBarItem(course.labs.locationlab.R.id.place_one);
solo.sleep(delay);
// Click on Get New Place
solo.clickOnView(solo.getView(course.labs.locationlab.R.id.footer));
String samePlaceString = solo
.getString(course.labs.locationlab.R.string.duplicate_location_string);
// Assert that duplicate location Toast is shown
assertTrue(samePlaceString + " is not shown!",
solo.waitForText(samePlaceString, 1, longDelay));
}
}
package course.labs.locationlab.tests;
import course.labs.locationlab.PlaceViewActivity;
import course.labs.locationlab.R;
import com.robotium.solo.*;
import android.test.ActivityInstrumentationTestCase2;
import org.junit.Test;
public class TestTwoValidLocations extends
ActivityInstrumentationTestCase2<PlaceViewActivity> {
private Solo solo;
public TestTwoValidLocations() {
super(PlaceViewActivity.class);
}
public void setUp() throws Exception {
solo = new Solo(getInstrumentation(), getActivity());
PlaceViewActivity.sHasNetwork = false;
}
@Override
public void tearDown() throws Exception {
solo.finishOpenedActivities();
}
@Test
public void testRun() {
int delay = 2000;
int longDelay = 5000;
// Wait for activity: 'course.labs.locationlab.PlaceViewActivity'
solo.waitForActivity(course.labs.locationlab.PlaceViewActivity.class,
2000);
// Click on action bar item
solo.clickOnActionBarItem(course.labs.locationlab.R.id.place_one);
solo.sleep(delay);
// Click on Get New Place
solo.clickOnView(solo.getView(course.labs.locationlab.R.id.footer));
solo.sleep(delay);
// Assert that PlaceBadge is shown
assertTrue("PlaceBadge is not shown!", solo.waitForText(
solo.getString(R.string.the_greenhouse_string), 1, longDelay));
// Click on action bar item
solo.clickOnActionBarItem(course.labs.locationlab.R.id.place_two);
solo.sleep(delay);
// Click on Get New Place
solo.clickOnView(solo.getView(course.labs.locationlab.R.id.footer));
solo.sleep(delay);
// Assert that PlaceBadge is shown
assertTrue("PlaceBadge is not shown!", solo.waitForText(
solo.getString(R.string.berwyn_string), 1, longDelay));
// Click on PlaceBadge
solo.clickOnText(solo.getString(R.string.berwyn_string));
solo.sleep(delay);
assertTrue("Detail view not shown!", solo.waitForText("Date"));
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="course.labs.locationlab"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-sdk
android:minSdkVersion="17"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="course.labs.locationlab.PlaceViewActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="course.labs.locationlab.PlaceBadgeDetailActivity"
android:label="@string/badge_detail" >
</activity>
</application>
</manifest>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="course.labs.locationlab"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-sdk
android:minSdkVersion="17"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="course.labs.locationlab.PlaceViewActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="course.labs.locationlab.PlaceBadgeDetailActivity"
android:label="@string/badge_detail" >
</activity>
</application>
</manifest>
\ No newline at end of file
package course.labs.locationlab;
// Adapted from code found at:
// http://mobiarch.wordpress.com/2012/07/17/testing-with-mock-location-data-in-android/
import android.content.Context;
import android.location.Location;
import android.location.LocationManager;
import android.os.SystemClock;
public class MockLocationProvider {
private String mProviderName;
private LocationManager mLocationManager;
private static float mockAccuracy = 5;
public MockLocationProvider(String name, Context ctx) {
this.mProviderName = name;
mLocationManager = (LocationManager) ctx
.getSystemService(Context.LOCATION_SERVICE);
mLocationManager.addTestProvider(mProviderName, false, false, false,
false, true, true, true, 0, 5);
mLocationManager.setTestProviderEnabled(mProviderName, true);
}
public void pushLocation(double lat, double lon) {
Location mockLocation = new Location(mProviderName);
mockLocation.setLatitude(lat);
mockLocation.setLongitude(lon);
mockLocation.setAltitude(0);
mockLocation.setTime(System.currentTimeMillis());
mockLocation
.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
mockLocation.setAccuracy(mockAccuracy);
mLocationManager.setTestProviderLocation(mProviderName, mockLocation);
}
public void shutdown() {
mLocationManager.removeTestProvider(mProviderName);
}
}
package course.labs.locationlab;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;
public class PlaceBadgeDetailActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// TODO - implement the Activity
//Hint: You will get the PlacePadge info from the intent
//Hint: The layout file for this activity is the place_badge detail
}
}
package course.labs.locationlab;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Locale;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.location.Location;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.util.Log;
public class PlaceDownloaderTask extends AsyncTask<Location, Void, PlaceRecord> {
// False if you don't have network access
private boolean mHasNetwork = false;
// TODO - put your www.geonames.org account name here instead of "aporter".
private static String USERNAME = "aporter";
private HttpURLConnection mHttpUrl;
private WeakReference<PlaceViewActivity> mParent;
private static final Location sMockLoc1 = new Location(
LocationManager.NETWORK_PROVIDER);
private static final Location sMockLoc2 = new Location(
LocationManager.NETWORK_PROVIDER);
private static final Location sMockLoc3 = new Location(
LocationManager.NETWORK_PROVIDER);
private static String sMockCountryName1, sMockCountryNameInvalid,
sMockPlaceName1, sMockPlaceName2, sMockPlaceNameInvalid;
private static Bitmap sStubBitmap = null;
public PlaceDownloaderTask(PlaceViewActivity parent, boolean hasNetwork) {
super();
mParent = new WeakReference<PlaceViewActivity>(parent);
mHasNetwork = hasNetwork;
if (null != parent) {
sStubBitmap = BitmapFactory.decodeResource(parent.getResources(),
R.drawable.stub);
sMockLoc1.setLatitude(37.422);
sMockLoc1.setLongitude(-122.084);
sMockCountryName1 = parent
.getString(R.string.mock_name_united_states_string);
sMockPlaceName1 = parent.getString(R.string.the_greenhouse_string);
sMockLoc2.setLatitude(38.996667);
sMockLoc2.setLongitude(-76.9275);
sMockPlaceName2 = parent.getString(R.string.berwyn_string);
sMockLoc3.setLatitude(0);
sMockLoc3.setLongitude(0);
sMockCountryNameInvalid = "";
sMockPlaceNameInvalid = "";
}
}
@Override
protected PlaceRecord doInBackground(Location... location) {
PlaceRecord place = null;
if (mHasNetwork) {
// Get the PlaceBadge information
place = getPlaceFromURL(generateURL(USERNAME, location[0]));
place.setLocation(location[0]);
if ("" != place.getCountryName()) {
place.setFlagBitmap(getFlagFromURL(place.getFlagUrl()));
} else {
place.setFlagBitmap(sStubBitmap);
}
} else {
place = new PlaceRecord();
place.setLocation(location[0]);
place.setFlagBitmap(sStubBitmap);
if (place.intersects(sMockLoc1)) {
place.setCountryName(sMockCountryName1);
place.setPlace(sMockPlaceName1);
} else if (place.intersects(sMockLoc2)) {
place.setCountryName(sMockCountryName1);
place.setPlace(sMockPlaceName2);
} else {
place.setCountryName(sMockCountryNameInvalid);
place.setPlace(sMockPlaceNameInvalid);
}
}
return place;
}
@Override
protected void onPostExecute(PlaceRecord result) {
if (null != result && null != mParent.get()) {
mParent.get().addNewPlace(result);
}
}
private PlaceRecord getPlaceFromURL(String... params) {
String result = null;
BufferedReader in = null;
try {
URL url = new URL(params[0]);
mHttpUrl = (HttpURLConnection) url.openConnection();
in = new BufferedReader(new InputStreamReader(
mHttpUrl.getInputStream()));
StringBuffer sb = new StringBuffer("");
String line = "";
while ((line = in.readLine()) != null) {
sb.append(line + "\n");
}
result = sb.toString();
} catch (MalformedURLException e) {
} catch (IOException e) {
} finally {
try {
if (null != in) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
mHttpUrl.disconnect();
}
return placeDataFromXml(result);
}
private Bitmap getFlagFromURL(String flagUrl) {
InputStream in = null;
Log.i("temp", flagUrl);
try {
URL url = new URL(flagUrl);
mHttpUrl = (HttpURLConnection) url.openConnection();
in = mHttpUrl.getInputStream();
return BitmapFactory.decodeStream(in);
} catch (MalformedURLException e) {
Log.e("DEBUG", e.toString());
} catch (IOException e) {
Log.e("DEBUG", e.toString());
} finally {
try {
if (null != in) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
mHttpUrl.disconnect();
}
return BitmapFactory.decodeResource(mParent.get().getResources(),
R.drawable.stub);
}
private static PlaceRecord placeDataFromXml(String xmlString) {
DocumentBuilder builder;
String countryName = "";
String countryCode = "";
String placeName = "";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
builder = factory.newDocumentBuilder();
Document document = builder.parse(new InputSource(new StringReader(
xmlString)));
NodeList list = document.getDocumentElement().getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Node curr = list.item(i);
NodeList list2 = curr.getChildNodes();
for (int j = 0; j < list2.getLength(); j++) {
Node curr2 = list2.item(j);
if (curr2.getNodeName() != null) {
if (curr2.getNodeName().equals("countryName")) {
countryName = curr2.getTextContent();
} else if (curr2.getNodeName().equals("countryCode")) {
countryCode = curr2.getTextContent();
} else if (curr2.getNodeName().equals("name")) {
placeName = curr2.getTextContent();
}
}
}
}
} catch (DOMException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return new PlaceRecord(generateFlagURL(countryCode.toLowerCase(Locale.US)),
countryName, placeName);
}
private static String generateURL(String username, Location location) {
return "http://www.geonames.org/findNearbyPlaceName?username="
+ username + "&style=full&lat=" + location.getLatitude()
+ "&lng=" + location.getLongitude();
}
private static String generateFlagURL(String countryCode) {
return "http://www.geonames.org/flags/x/" + countryCode + ".gif";
}
}
package course.labs.locationlab;
import java.util.Date;
import android.content.Intent;
import android.graphics.Bitmap;
import android.location.Location;
import android.util.Log;
public class PlaceRecord {
private String mFlagUrl;
private String mCountryName;
private String mPlaceName;
private Bitmap mFlagBitmap;
private Location mLocation;
private Date mDateVisited;
public PlaceRecord(String flagUrl, String country, String place) {
this.mFlagUrl = flagUrl;
this.mCountryName = country;
this.mPlaceName = place;
}
public PlaceRecord(Location location) {
mLocation = location;
}
public PlaceRecord() {
}
public PlaceRecord(Intent intent) {
this.mFlagUrl = intent.getStringExtra("mFlagUrl");
this.mCountryName = intent.getStringExtra("mCountryName");
this.mPlaceName = intent.getStringExtra("mPlaceName");
this.mFlagBitmap = (Bitmap) intent.getParcelableExtra("mFlagBitmap");
this.mLocation = (Location) intent.getParcelableExtra("mLocation");
this.mDateVisited = (Date) intent.getSerializableExtra("mDateVisited");
}
public Intent packageToIntent() {
Intent intent = new Intent();
intent.putExtra("mFlagUrl", mFlagUrl);
intent.putExtra("mCountryName", mCountryName);
intent.putExtra("mPlaceName", mPlaceName);
intent.putExtra("mFlagBitmap", mFlagBitmap);
intent.putExtra("mLocation", mLocation);
intent.putExtra("mDateVisited", mDateVisited);
return intent;
}
public String getFlagUrl() {
return mFlagUrl;
}
public void setFlagUrl(String flagUrl) {
this.mFlagUrl = flagUrl;
}
public String getCountryName() {
return mCountryName;
}
public void setCountryName(String country) {
this.mCountryName = country;
}
public String getPlace() {
return mPlaceName;
}
public void setPlace(String place) {
this.mPlaceName = place;
}
public Bitmap getFlagBitmap() {
return mFlagBitmap;
}
public void setFlagBitmap(Bitmap mFlagBitmap) {
this.mFlagBitmap = mFlagBitmap;
}
public boolean intersects(Location location) {
double tolerance = 1000;
return (mLocation.distanceTo(location) <= tolerance);
}
public void setLocation(Location location) {
mLocation = location;
}
public Location getLocation() {
return mLocation;
}
public Date getDateVisited() {
return mDateVisited;
}
public void setDateVisited(Date mDateVisited) {
this.mDateVisited = mDateVisited;
}
@Override
public String toString() {
return "Place: " + mPlaceName + " Country: " + mCountryName;
}
}
package course.labs.locationlab;
import java.util.Date;
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.Toast;
public class PlaceViewActivity extends ListActivity implements LocationListener {
private static final long FIVE_MINS = 5 * 60 * 1000;
private static String TAG = "Lab-Location";
public static String PACKAGE_NAME = "course.labs.locationlab.placerecord.PlaceDetail";
public static String PLACE_DETAIL = "place_detail";
public static String INTENT_DATA = "course.labs.locationlab.placerecord.IntentData";
private Location mLastLocationReading;
private PlaceViewAdapter mAdapter;
// False if you don't have network access
public static boolean sHasNetwork = true;
// default minimum time between new readings
private long mMinTime = 5000;
// default minimum distance between old and new readings.
private float mMinDistance = 1000.0f;
private LocationManager mLocationManager;
// A fake location provider used for testing
private MockLocationProvider mMockLocationProvider;
private boolean mockLocationOn = false;
private boolean returningFromActivity = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set up the app's user interface
// This class is a ListActivity, so it has its own ListView
// ListView's adapter should be a PlaceViewAdapter
// TODO - acquire reference to the LocationManager
mLocationManager = null;
ListView placesListView = getListView();
// TODO - Set an OnItemClickListener on the placeListView to open a detail view when the user
// clicks on a Place Badge.
// TODO - add a footerView to the ListView
// You can use footer_view.xml to define the footer
View footerView = null;
// Can remove once footerView is implemented
if (null == footerView) {
return;
}
footerView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO - When the footerView's onClick() method is called, it must
// issue the
// following log call
// Log.i(TAG,"Entered footerView.OnClickListener.onClick()");
// footerView must respond to user clicks.
// Must handle 3 cases:
// 1) The current location is new - download new Place Badge. Issue the
// following log call:
// Log.i(TAG,"Starting Place Download");
// 2) The current location has been seen before - issue Toast message.
// Issue the following log call:
// Log.i(TAG,"You already have this location badge");
// 3) There is no current location - response is up to you. The best
// solution is to disable the footerView until you have a location.
// Issue the following log call:
// Log.i(TAG,"Location data is not available");
}
});
placesListView.addFooterView(footerView);
mAdapter = new PlaceViewAdapter(getApplicationContext());
setListAdapter(mAdapter);
}
public final static int MY_PERMISSIONS_LOCATION= 4;
@Override
protected void onResume() {
super.onResume();
if (Build.VERSION.SDK_INT >= 23 &&
ContextCompat.checkSelfPermission(getApplicationContext(), "android.permission.ACCESS_FINE_LOCATION") != PackageManager.PERMISSION_GRANTED
||ContextCompat.checkSelfPermission(getApplicationContext(), "android.permission.ACCESS_COARSE_LOCATION") != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(PlaceViewActivity.this,
new String[]{"android.permission.ACCESS_FINE_LOCATION",
"android.permission.ACCESS_COARSE_LOCATION"},
MY_PERMISSIONS_LOCATION);
}else
getLocationUpdates();
}
private void getLocationUpdates()
{
try {
startMockLocationManager();
// TODO - Check NETWORK_PROVIDER and GPS_PROVIDER for an existing
// location reading.
// Only keep this last reading if it is fresh - less than 5 minutes old.
// TODO - register to receive location updates from NETWORK_PROVIDER
}catch (SecurityException e)
{
Log.d(TAG,e.getLocalizedMessage());
}
}
@Override
protected void onPause() {
shutdownMockLocationManager();
// TODO - unregister for location updates
super.onPause();
}
// Callback method used by PlaceDownloaderTask
public void addNewPlace(PlaceRecord place) {
Log.i(TAG, "Entered addNewPlace()");
if (place.getCountryName() == null || place.getCountryName().isEmpty()) {
showToast(getString(R.string.no_country_string));
} else if (!mAdapter.intersects(place.getLocation())) {
place.setDateVisited(new Date());
mAdapter.add(place);
mAdapter.notifyDataSetChanged();
} else {
showToast(getString(R.string.duplicate_location_string));
}
}
@Override
public void onLocationChanged(Location currentLocation) {
// TODO - Handle location updates
// Cases to consider
// 1) If there is no last location, keep the current location.
// 2) If the current location is older than the last location, ignore
// the current location
// 3) If the current location is newer than the last locations, keep the
// current location.
}
@Override
public void onProviderDisabled(String provider) {
// not implemented
}
@Override
public void onProviderEnabled(String provider) {
// not implemented
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// not implemented
}
private long ageInMilliseconds(Location location) {
return System.currentTimeMillis() - location.getTime();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.delete_badges:
mAdapter.removeAllViews();
return true;
case R.id.place_one:
mMockLocationProvider.pushLocation(37.422, -122.084);
return true;
case R.id.place_no_country:
mMockLocationProvider.pushLocation(0, 0);
return true;
case R.id.place_two:
mMockLocationProvider.pushLocation(38.996667, -76.9275);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void showToast(final String toast) {
Toast.makeText(PlaceViewActivity.this, toast, Toast.LENGTH_LONG)
.show();
}
private void shutdownMockLocationManager() {
if (mockLocationOn) {
mMockLocationProvider.shutdown();
mockLocationOn = false;
}
}
private void startMockLocationManager() {
if (!mockLocationOn) {
mMockLocationProvider = new MockLocationProvider(
LocationManager.NETWORK_PROVIDER, this);
mockLocationOn = true;
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_LOCATION:
int g = 0;
Log.d(TAG,"Perm?: "+permissions.length+" -? "+grantResults.length);
for(String perm: permissions)
Log.d(TAG,"Perm: "+perm+" --> "+grantResults[g++]);
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED)
getLocationUpdates();
else {
Log.i(TAG, "Permission was not granted to access location");
finish();
}
}
}
}
\ No newline at end of file
package course.labs.locationlab;
import java.util.ArrayList;
import android.content.Context;
import android.location.Location;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class PlaceViewAdapter extends BaseAdapter {
private ArrayList<PlaceRecord> list = new ArrayList<PlaceRecord>();
private static LayoutInflater inflater = null;
private Context mContext;
public PlaceViewAdapter(Context context) {
mContext = context;
inflater = LayoutInflater.from(mContext);
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View newView = convertView;
ViewHolder holder;
PlaceRecord curr = list.get(position);
if (null == convertView) {
holder = new ViewHolder();
newView = inflater.inflate(R.layout.place_badge_view, parent, false);
holder.flag = (ImageView) newView.findViewById(R.id.flag);
holder.country = (TextView) newView.findViewById(R.id.country_name);
holder.place = (TextView) newView.findViewById(R.id.place_name);
newView.setTag(holder);
} else {
holder = (ViewHolder) newView.getTag();
}
holder.flag.setImageBitmap(curr.getFlagBitmap());
holder.country.setText(curr.getCountryName());
holder.place.setText(curr.getPlace());
return newView;
}
static class ViewHolder {
ImageView flag;
TextView country;
TextView place;
}
public boolean intersects (Location location) {
for (PlaceRecord item : list) {
if (item.intersects(location)) {
return true;
}
}
return false;
}
public void add(PlaceRecord listItem) {
list.add(listItem);
notifyDataSetChanged();
}
public void removeAllViews(){
list.clear();
this.notifyDataSetChanged();
}
}
Lab10_LocationLab/app/src/main/res/drawable-hdpi/ic_launcher.png

7.48 KiB

Lab10_LocationLab/app/src/main/res/drawable-hdpi/stub.jpg

4.92 KiB

Lab10_LocationLab/app/src/main/res/drawable-mdpi/ic_launcher.png

3.69 KiB

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment