Presentation is loading. Please wait.

Presentation is loading. Please wait.

Mobile Programming Dr. Mohsin Ali Memon.

Similar presentations


Presentation on theme: "Mobile Programming Dr. Mohsin Ali Memon."— Presentation transcript:

1 Mobile Programming Dr. Mohsin Ali Memon

2 Location APIs in Android
The location APIs make it easy for you to build location-aware applications, without needing to focus on the details of the underlying location technology. They also let you minimize power consumption by using all of the capabilities of the device hardware. Key features Fused Location provider Activity Recognition Geofencing

3 Fused location provider
The Fused Location Provider intelligently manages the underlying location technology and gives you the best location according to your needs. Simple APIs Immediately available: Gives your apps immediate access to the best, most recent location. Power-efficiency: Based on all incoming location requests and available sensors, fused location provider chooses the most efficient way to meet those needs. Versatility: Meets a wide range of needs, from foreground uses that need highly accurate location to background uses that need periodic location updates with negligible power impact.

4 Activity recognition The Activity recognition API makes it easy to check the user’s current activity— still, walking, cycling, and in-vehicle—with very efficient use of the battery. Optimized for battery: Uses low-power sensors to recognize the user's current physical activity. Enhances other services with context: Great for adding movement awareness to location awareness. Apps can adjust the amount of location awareness they provide, based on the current user movement. For example, a navigation app can request more frequent updates when the user is driving. Features for advanced applications: For advanced applications that want to do their own post-processing, this API also makes available confidence values for each of the activities.

5 Geofencing APIs Lets your app setup geographic boundaries around specific locations and then receive notifications when the user enters or leaves those areas. Simple but powerful APIs: Allows batch addition and removal of geofences. Ability to manage multiple geofences at the same time. Ability to filter alerts for both entry and exit or entry only or exit only. Optimized for battery: Adjusts location updates based on user’s proximity to the geofence and user’s modality (still, walking, driving, and so on).

6 Setting Up Google Play Services

7 Step 1: Downloading Google Play Services

8 Step 2: Copying the library and importing it
Copy the Play Services library into your workspace. Browse to it on your computer using a file explorer. You will find it in the folder you downloaded your Android SDK into, at /extras/google/google_play_services/libproject/google-play-services_lib/

9 Step 2 cont’d

10 Creating an android project and making reference to Google Play services
In Eclipse, select the project in your Package Explorer, right-click or select the Projectmenu, and choose Properties. Select the Android option on the left and click Add in the Library section.

11 Creating an android project and making reference to Google Play services cont’d
You might need to reconfigure eclipse.ini file to upsize the memory required to compile the app with this new API -Xms512m -Xmx1024m

12 Getting Last Known location using Google Play services

13 Fused Location Provider
We use the fused location provider to retrieve the device's last known location. The fused location provider is one of the location APIs in Google Play services. It manages the underlying location technology and provides a simple API so that you can specify requirements at a high level, like high accuracy or low power. It also optimizes the device's use of battery power.

14 Step 1: Specifying App Permission
Apps that use location services must request location permissions. Android offers two location permissions: ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION. The permission you choose determines the accuracy of the location returned by the API. If you specify ACCESS_COARSE_LOCATION, the API returns a location with an accuracy approximately equivalent to a city block. For this example we require only <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

15 Settings in the device and Manifest file
You need to have the updated version of Google Play Services on your device to run this API. You also need to add the following information in the Manifest file of the project (inside the application tag). <meta-data android:name="com.google.android.gms.version" />

16 Step 2: Connect to google play services
To connect to the API, you need to create an instance of the Google Play services API client. The sample app defines a buildGoogleApiClient() method, called from the activity's onCreate() method, which includes the following code. protected synchronized void buildGoogleApiClient() {     mGoogleApiClient = new GoogleApiClient.Builder(this)         .addConnectionCallbacks(this)         .addOnConnectionFailedListener(this)         .addApi(LocationServices.API)         .build(); }

17 Step 3: Get the Last Known Location
You also need to call mGoogleApiClient.connect() after creating the Api client. (maybe in onStart()) To request the last known location, call the getLastLocation() method, passing it your instance of the GoogleApiClient object public class MainActivity extends ActionBarActivity implements         ConnectionCallbacks, OnConnectionFailedListener {     ...       public void onConnected(Bundle connectionHint) {         mLastLocation = LocationServices.FusedLocationApi.getLastLocation(                 mGoogleApiClient);         if (mLastLocation != null) {             mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude()));             mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude()));         }     } }

18 Receiving Location Updates

19 Step 1: Requesting permission and setting up Location Request
You need to request the following permission first <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> To store parameters for requests to the fused location provider, create a LocationRequest. The parameters determine the levels of accuracy requested. setInterval() - This method sets the rate in milliseconds at which your app prefers to receive location updates. Note that the location updates may be faster than this rate if another app is receiving updates at a faster rate, or slower than this rate, or there may be no updates at all (if the device has no connectivity, for example).

20 Step 1 cont’d setFastestInterval() - This method sets the fastest rate in milliseconds at which your app can handle location updates. You need to set this rate because other apps also affect the rate at which updates are sent. setPriority() - This method sets the priority of the request, which gives the Google Play services location services a strong hint about which location sources to use. PRIORITY_BALANCED_POWER_ACCURACY PRIORITY_HIGH_ACCURACY PRIORITY_LOW_POWER

21 Method to set all the parameters
protected void createLocationRequest() {     LocationRequest mLocationRequest = new LocationRequest();     mLocationRequest.setInterval(10000);     mLocationRequest.setFastestInterval(5000);     mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); }

22 Step 2: Request Location Updates
After setting up location request containing your app's requirements for the location updates, you can start the regular updates by calling requestLocationUpdates(). LocationServices.FusedLocationApi.requestLocationUpdates( mGoogleApiClient, mLocationRequest, this); Location provider either invokes the LocationListener.onLocationChanged() callback method and passes it a Location object, or issues a PendingIntent that contains the location in its extended data.

23 Step 3: Define the Location Update Callback
The fused location provider invokes the LocationListener.onLocationChanged() callback method. public class MainActivity extends ActionBarActivity implements         ConnectionCallbacks, OnConnectionFailedListener, LocationListener {     ...       public void onLocationChanged(Location location) {         mCurrentLocation = location;         mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());         updateUI();     }     private void updateUI() {         mLatitudeTextView.setText(String.valueOf(mCurrentLocation.getLatitude()));         mLongitudeTextView.setText(String.valueOf(mCurrentLocation.getLongitude()));         mLastUpdateTimeTextView.setText(mLastUpdateTime);     } }

24 Step 4: Stop Location Updates
When the user switches to another app or to a different activity in the same app Handy to reduce power consumption, provided the app doesn't need to collect information even when it's running in the background.  @Override protected void onPause() {     super.onPause();     stopLocationUpdates(); } protected void stopLocationUpdates() {     LocationServices.FusedLocationApi.removeLocationUpdates(             mGoogleApiClient, this); }

25 Step 5: Resume Location updates
Use a boolean, mRequestingLocationUpdates, to track whether location updates are currently turned on. In the activity's onResume() method, check whether location updates are currently active, and activate them if not: @Override public void onResume() {     super.onResume();     if (mGoogleApiClient.isConnected() && !mRequestingLocationUpdates) {         startLocationUpdates(); //refer to the code of requesting     } // location updates }

26 Step 6: Save the State of the Activity
A change to the device's configuration, such as a change in screen orientation or language, can cause the current activity to be destroyed.  Store any information it needs to recreate the activity. One way to do this is via an instance state stored in a Bundle object. public void onSaveInstanceState(Bundle savedInstanceState) {     savedInstanceState.putBoolean(REQUESTING_LOCATION_UPDATES_KEY,             mRequestingLocationUpdates);     savedInstanceState.putParcelable(LOCATION_KEY, mCurrentLocation);     savedInstanceState.putString(LAST_UPDATED_TIME_STRING_KEY, mLastUpdateTime);     super.onSaveInstanceState(savedInstanceState); }

27 Step 7: Define an updateValuesFromBundle() method to restore the saved values from the previous instance of the activity, if they're available. Call the method from the activity's onCreate() method, as shown in the following code sample: @Override public void onCreate(Bundle savedInstanceState) {     ...     updateValuesFromBundle(savedInstanceState); }

28 private void updateValuesFromBundle(Bundle savedInstanceState) {     if (savedInstanceState != null) {         // Update the value of mRequestingLocationUpdates from the Bundle, and         // make sure that the Start Updates and Stop Updates buttons are         // correctly enabled or disabled.         if (savedInstanceState.keySet().contains(REQUESTING_LOCATION_UPDATES_KEY)) {             mRequestingLocationUpdates = savedInstanceState.getBoolean(                     REQUESTING_LOCATION_UPDATES_KEY);             setButtonsEnabledState();         }         // Update the value of mCurrentLocation from the Bundle and update the         // UI to show the correct latitude and longitude.         if (savedInstanceState.keySet().contains(LOCATION_KEY)) {             // Since LOCATION_KEY was found in the Bundle, we can be sure that             // mCurrentLocationis not null.             mCurrentLocation = savedInstanceState.getParcelable(LOCATION_KEY);         }         // Update the value of mLastUpdateTime from the Bundle and update the UI.         if (savedInstanceState.keySet().contains(LAST_UPDATED_TIME_STRING_KEY)) {             mLastUpdateTime = savedInstanceState.getString(                     LAST_UPDATED_TIME_STRING_KEY);         }         updateUI();     } }

29 Getting Address of the Location

30 Setting up permission A street address is more meaningful than the geographic coordinates (latitude/longitude) of the location. In order for the fused location provider to retrieve a precise street address, set the location permission in your app manifest to ACCESS_FINE_LOCATION <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

31 Use of Geocoder class Using the Geocoder class in the Android framework location APIs, you can convert an address to the corresponding geographic coordinates. This process is called geocoding. Alternatively, you can convert a geographic location to an address. The address lookup feature is also known as reverse geocoding. The getFromLocation() method provided by the Geocoder class accepts a latitude and longitude, and returns a list of addresses. The method is synchronous, and may take a long time to do its work, so you should not call it from the main, user interface (UI) thread of your app.

32 Constants class public final class Constants { public static final int SUCCESS_RESULT = 0; public static final int FAILURE_RESULT = 1; public static final String PACKAGE_NAME = "com.google.android.gms.location.sample.locationaddress"; public static final String RECEIVER = PACKAGE_NAME + ".RECEIVER"; public static final String RESULT_DATA_KEY = PACKAGE_NAME + ".RESULT_DATA_KEY"; public static final String LOCATION_DATA_EXTRA = PACKAGE_NAME + ".LOCATION_DATA_EXTRA"; }

33 IntentService to run in background
public class FetchAddressIntentService extends IntentService { mReceiver = intent.getParcelableExtra(Constants.RECEIVER); // Check if receiver was properly registered. if (mReceiver == null) { Log.wtf(TAG, "No receiver received. There is nowhere to send the results."); return; } // Get the location passed to this service through an extra. Location location = intent.getParcelableExtra(Constants.LOCATION_DATA_EXTRA); <service android:name=".FetchAddressIntentService" android:exported="false"/>

34 Using Geocoder Geocoder geocoder = new Geocoder(this, Locale.getDefault()); // Address found using the Geocoder. List<Address> addresses = null; try { // Using getFromLocation() returns an array of Addresses for the area immediately // surrounding the given latitude and longitude. The results are a best guess and are // not guaranteed to be accurate. addresses = geocoder.getFromLocation( location.getLatitude(), location.getLongitude(), // In this sample, we get just a single address. 1);

35 cont’d } catch (IOException ioException) {
// Catch network or other I/O problems. errorMessage = getString(R.string.service_not_available); Log.e(TAG, errorMessage, ioException); } catch (IllegalArgumentException illegalArgumentException) { // Catch invalid latitude or longitude values. errorMessage = getString(R.string.invalid_lat_long_used); Log.e(TAG, errorMessage + ". " + "Latitude = " + location.getLatitude() + ", Longitude = " + location.getLongitude(), illegalArgumentException); }

36 cont’d if (addresses == null || addresses.size() == 0) { if (errorMessage.isEmpty()) { errorMessage = getString(R.string.no_address_found); Log.e(TAG, errorMessage); } deliverResultToReceiver(Constants.FAILURE_RESULT, errorMessage); else { Address address = addresses.get(0); ArrayList<String> addressFragments = new ArrayList<String>(); // Fetch the address lines using getAddressLine}, // join them, and send them to the thread. The android.location.address} // class provides other options for fetching address details that you may prefer // to use. Here are some examples:

37 Cont’d // getLocality() ("Mountain View", for example) // getAdminArea() ("CA", for example) // getPostalCode() ("94043", for example) // getCountryCode() ("US", for example) // getCountryName() ("United States", for example) for(int i = 0; i < address.getMaxAddressLineIndex(); i++) { addressFragments.add(address.getAddressLine(i)); } Log.i(TAG, getString(R.string.address_found)); deliverResultToReceiver(Constants.SUCCESS_RESULT, TextUtils.join(System.getProperty("line.separator"), addressFragments));

38 Cont’d private void deliverResultToReceiver(int resultCode, String message) { Bundle bundle = new Bundle(); bundle.putString(Constants.RESULT_DATA_KEY, message); mReceiver.send(resultCode, bundle); }

39 Main Activity @Override public void onConnected(Bundle connectionHint) { // Gets the best and most recent location currently available, // which may be null in rare cases when a location is not available. mLastLocation = LocationServices.FusedLocationApi.getLastLocation( mGoogleApiClient); if (mLastLocation != null) { // Determine whether a Geocoder is available. if (!Geocoder.isPresent()) { Toast.makeText(this, R.string.no_geocoder_available, Toast.LENGTH_LONG).show(); return; } if (mAddressRequested) { startIntentService(); } }

40 Cont’d protected void startIntentService() { // Create an intent for passing to the intent service responsible for fetching the address. Intent intent = new Intent(this, FetchAddressIntentService.class); // Pass the result receiver as an extra to the service. intent.putExtra(Constants.RECEIVER, mResultReceiver); // Pass the location data as an extra to the service. intent.putExtra(Constants.LOCATION_DATA_EXTRA, mLastLocation); // Start the service. If the service isn't already running, it is instantiated and started // (creating a process for it if needed); if it is running then it remains running. The // service kills itself automatically once all intents are processed. startService(intent); }

41 class AddressResultReceiver extends ResultReceiver { public AddressResultReceiver(Handler handler) { super(handler); } /** * Receives data sent from FetchAddressIntentService and updates the UI in MainActivity. protected void onReceiveResult(int resultCode, Bundle resultData) { // Display the address string or an error message sent from the intent service. mAddressOutput = resultData.getString(Constants.RESULT_DATA_KEY); displayAddressOutput(); // Show a toast message if an address was found. if (resultCode == Constants.SUCCESS_RESULT) { showToast(getString(R.string.address_found)); } // Reset. Enable the Fetch Address button and stop showing the progress bar. mAddressRequested = false; updateUIWidgets(); } }

42


Download ppt "Mobile Programming Dr. Mohsin Ali Memon."

Similar presentations


Ads by Google