Step: 1
======
1) Generate a Google Maps API Key using this URL.
1.1) To generate a debug SHA1 key for testing apps for development use below command in windows command prompt.
keytool -list -v -keystore "C:\Users\pratap.kesaboyina\.android\debug.keystore" -alias androiddebugkey -storepass android -keypass android
1.2) To generate a release SHA1 key for production usage( when releasing your app to google play store, debug key will not work. You need a release SHA1 Key)
keytool -list -v -keystore "C:\AndroidFiles\AppKeyStore.jks" -alias "Your App Alias Name"
1.3) Go ahead and add Maps Api Key in the manifest file and also add Permissions in the manifest File.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.pratap.mapssample"> <uses-feature android:glEsVersion="0x00020000" android:required="true" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name="com.pratap.mapssample.MapsSampleActivity" android:label="@string/app_name" android:screenOrientation="portrait"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" /> <meta-data android:name="com.google.android.geo.API_KEY" android:value="@string/google_maps_debug_key" /> </application> </manifest>
3) Add dependencies to your app in build.gradle file
dependencies { compile 'com.google.android.gms:play-services-maps:8.1.0' compile 'com.google.android.gms:play-services-location:8.1.0' }
Step: 2
======
Create an xml layout file with MapFragment
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <fragment android:id="@+id/map" android:name="com.google.android.gms.maps.MapFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
Step: 3
======
Now create an Activity class
package com.pratap.mapssample; import android.app.Activity; import android.content.Intent; import android.content.IntentSender; import android.location.Location; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.util.Log; import android.widget.TextView; import android.widget.Toast; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.PendingResult; import com.google.android.gms.common.api.ResultCallback; import com.google.android.gms.common.api.Status; import com.google.android.gms.location.LocationListener; import com.google.android.gms.location.LocationRequest; import com.google.android.gms.location.LocationServices; import com.google.android.gms.location.LocationSettingsRequest; import com.google.android.gms.location.LocationSettingsResult; import com.google.android.gms.location.LocationSettingsStatusCodes; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.MapFragment; import com.google.android.gms.maps.OnMapReadyCallback; import com.google.android.gms.maps.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.CameraPosition; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.MarkerOptions; import java.text.DateFormat; import java.util.Date; /** * Created by pratap.kesaboyina on 18-12-2015. */ public class MapsSampleActivity extends AppCompatActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener, ResultCallback<LocationSettingsResult> { // UI Views private Toolbar toolbar; private TextView tvTitle; private MapFragment mMapFragment; private GoogleMap googleMap; // Map Settings private final int[] MAP_TYPES = {GoogleMap.MAP_TYPE_SATELLITE, GoogleMap.MAP_TYPE_NORMAL, GoogleMap.MAP_TYPE_HYBRID, GoogleMap.MAP_TYPE_TERRAIN, GoogleMap.MAP_TYPE_NONE}; private int MAP_TYPE_INDEX = 1; protected static final String TAG = "MapsSampleActivity"; /** * Constant used in the location settings dialog. */ protected static final int REQUEST_CHECK_SETTINGS = 0x1; /** * The desired interval for location updates. Inexact. Updates may be more or less frequent. */ public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000; /** * The fastest rate for active location updates. Exact. Updates will never be more frequent * than this value. */ public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = UPDATE_INTERVAL_IN_MILLISECONDS / 2; // Keys for storing activity state in the Bundle. protected final static String KEY_REQUESTING_LOCATION_UPDATES = "requesting-location-updates"; protected final static String KEY_LOCATION = "location"; protected final static String KEY_LAST_UPDATED_TIME_STRING = "last-updated-time-string"; /** * Provides the entry point to Google Play services. */ protected GoogleApiClient mGoogleApiClient; /** * Stores parameters for requests to the FusedLocationProviderApi. */ protected LocationRequest mLocationRequest; /** * Stores the types of location services the client is interested in using. Used for checking * settings to determine if the device has optimal location settings. */ protected LocationSettingsRequest mLocationSettingsRequest; /** * Represents a geographical location. */ protected Location mCurrentLocation; /** * Tracks the status of the location updates request. Value changes when the user presses the * Start Updates and Stop Updates buttons. */ protected Boolean mRequestingLocationUpdates; /** * Time when the location was updated represented as a String. */ protected String mLastUpdateTime; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mMapFragment = (MapFragment) getFragmentManager() .findFragmentById(R.id.map); mMapFragment.getMapAsync(this); mRequestingLocationUpdates = false; // Update values using data stored in the Bundle. updateValuesFromBundle(savedInstanceState); // Kick off the process of building the GoogleApiClient, LocationRequest, and // LocationSettingsRequest objects. buildGoogleApiClient(); createLocationRequest(); buildLocationSettingsRequest(); checkLocationSettings(); } /** * Updates fields based on data stored in the bundle. * * @param savedInstanceState The activity state saved in the Bundle. */ 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(KEY_REQUESTING_LOCATION_UPDATES)) { mRequestingLocationUpdates = savedInstanceState.getBoolean( KEY_REQUESTING_LOCATION_UPDATES); } // Update the value of mCurrentLocation from the Bundle and update the UI to show the // correct latitude and longitude. if (savedInstanceState.keySet().contains(KEY_LOCATION)) { // Since KEY_LOCATION was found in the Bundle, we can be sure that mCurrentLocation // is not null. mCurrentLocation = savedInstanceState.getParcelable(KEY_LOCATION); } // Update the value of mLastUpdateTime from the Bundle and update the UI. if (savedInstanceState.keySet().contains(KEY_LAST_UPDATED_TIME_STRING)) { mLastUpdateTime = savedInstanceState.getString(KEY_LAST_UPDATED_TIME_STRING); } } } /** * Builds a GoogleApiClient. Uses the {@code #addApi} method to request the * LocationServices API. */ protected synchronized void buildGoogleApiClient() { Log.i(TAG, "Building GoogleApiClient"); mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); } /** * Sets up the location request. Android has two location request settings: * {@code ACCESS_COARSE_LOCATION} and {@code ACCESS_FINE_LOCATION}. These settings control * the accuracy of the current location. This sample uses ACCESS_FINE_LOCATION, as defined in * the AndroidManifest.xml. * <p/> * When the ACCESS_FINE_LOCATION setting is specified, combined with a fast update * interval (5 seconds), the Fused Location Provider API returns location updates that are * accurate to within a few feet. * <p/> * These settings are appropriate for mapping applications that show real-time location * updates. */ protected void createLocationRequest() { mLocationRequest = new LocationRequest(); // Sets the desired interval for active location updates. This interval is // inexact. You may not receive updates at all if no location sources are available, or // you may receive them slower than requested. You may also receive updates faster than // requested if other applications are requesting location at a faster interval. mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS); // Sets the fastest rate for active location updates. This interval is exact, and your // application will never receive updates faster than this value. mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); } /** * Uses a {@link com.google.android.gms.location.LocationSettingsRequest.Builder} to build * a {@link com.google.android.gms.location.LocationSettingsRequest} that is used for checking * if a device has the needed location settings. */ protected void buildLocationSettingsRequest() { LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder(); builder.addLocationRequest(mLocationRequest); builder.setAlwaysShow(true); // To hide never button on the Popup dialog. mLocationSettingsRequest = builder.build(); } /** * Check if the device's location settings are adequate for the app's needs using the * {@link com.google.android.gms.location.SettingsApi#checkLocationSettings(GoogleApiClient, * LocationSettingsRequest)} method, with the results provided through a {@code PendingResult}. */ protected void checkLocationSettings() { PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings( mGoogleApiClient, mLocationSettingsRequest ); result.setResultCallback(this); } @Override public void onConnected(Bundle bundle) { Log.i(TAG, "Connected to GoogleApiClient"); mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation( mGoogleApiClient); if (mCurrentLocation != null) { /*mLatitudeText.setText(String.valueOf(mCurrentLocation.getLatitude())); mLongitudeText.setText(String.valueOf(mCurrentLocation.getLongitude()));*/ setCurrentLocation(mCurrentLocation); } } /** * Callback that fires when the location changes. */ @Override public void onLocationChanged(Location location) { mCurrentLocation = location; mLastUpdateTime = DateFormat.getTimeInstance().format(new Date()); // updateLocationUI(); setCurrentLocation(mCurrentLocation); Toast.makeText(this, getResources().getString(R.string.location_updated_message), Toast.LENGTH_SHORT).show(); } @Override public void onMapReady(GoogleMap gMap) { googleMap = gMap; } @Override public void onConnectionSuspended(int cause) { Log.i(TAG, "Connection suspended"); } @Override public void onConnectionFailed(ConnectionResult result) { // Refer to the javadoc for ConnectionResult to see what error codes might be returned in // onConnectionFailed. Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode()); } /** * The callback invoked when * {@link com.google.android.gms.location.SettingsApi#checkLocationSettings(GoogleApiClient, * LocationSettingsRequest)} is called. Examines the * {@link com.google.android.gms.location.LocationSettingsResult} object and determines if * location settings are adequate. If they are not, begins the process of presenting a location * settings dialog to the user. */ @Override public void onResult(LocationSettingsResult locationSettingsResult) { final Status status = locationSettingsResult.getStatus(); switch (status.getStatusCode()) { case LocationSettingsStatusCodes.SUCCESS: Log.i(TAG, "All location settings are satisfied."); startLocationUpdates(); break; case LocationSettingsStatusCodes.RESOLUTION_REQUIRED: Log.i(TAG, "Location settings are not satisfied. Show the user a dialog to" + "upgrade location settings "); try { // Show the dialog by calling startResolutionForResult(), and check the result // in onActivityResult(). status.startResolutionForResult(MapsSampleActivity.this, REQUEST_CHECK_SETTINGS); } catch (IntentSender.SendIntentException e) { Log.i(TAG, "PendingIntent unable to execute request."); } break; case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE: Log.i(TAG, "Location settings are inadequate, and cannot be fixed here. Dialog " + "not created."); break; } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { // Check for the integer request code originally supplied to startResolutionForResult(). case REQUEST_CHECK_SETTINGS: switch (resultCode) { case Activity.RESULT_OK: Log.i(TAG, "User agreed to make required location settings changes."); startLocationUpdates(); break; case Activity.RESULT_CANCELED: Log.i(TAG, "User chose not to make required location settings changes."); break; } break; } } private void setCurrentLocation(Location location) { LatLng mapCenter = new LatLng(location.getLatitude(), location.getLongitude()); googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mapCenter, 16)); // googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(position), null); googleMap.setMapType(MAP_TYPES[MAP_TYPE_INDEX]); //googleMap.setTrafficEnabled(true); googleMap.setMyLocationEnabled(true); googleMap.getUiSettings().setZoomControlsEnabled(true); // Flat markers will rotate when the map is rotated, // and change perspective when the map is tilted. //BitmapDescriptorFactory.fromResource(R.drawable.direction_arrow /*googleMap.addMarker(new MarkerOptions() .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)) .position(mapCenter) .flat(true) .rotation(90));*/ googleMap.clear(); googleMap.addMarker(new MarkerOptions() .title("My Location ") .position(mapCenter) .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)) ); CameraPosition cameraPosition = CameraPosition.builder() .target(new LatLng(location.getLatitude(), location.getLongitude())) .zoom(16f) .bearing(0.0f) .tilt(0.0f) .build(); // Animate the change in camera view over 2 seconds googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 2000, null); } @Override protected void onStart() { super.onStart(); mGoogleApiClient.connect(); } @Override public void onResume() { super.onResume(); // Within {@code onPause()}, we pause location updates, but leave the // connection to GoogleApiClient intact. Here, we resume receiving // location updates if the user has requested them. if (mGoogleApiClient.isConnected() && mRequestingLocationUpdates) { startLocationUpdates(); } } @Override protected void onPause() { super.onPause(); // Stop location updates to save battery, but don't disconnect the GoogleApiClient object. if (mGoogleApiClient.isConnected()) { stopLocationUpdates(); } } @Override protected void onStop() { super.onStop(); mGoogleApiClient.disconnect(); } /** * Requests location updates from the FusedLocationApi. */ protected void startLocationUpdates() { LocationServices.FusedLocationApi.requestLocationUpdates( mGoogleApiClient, mLocationRequest, this ).setResultCallback(new ResultCallback<Status>() { @Override public void onResult(Status status) { mRequestingLocationUpdates = true; //setButtonsEnabledState(); } }); } /** * Removes location updates from the FusedLocationApi. */ protected void stopLocationUpdates() { // It is a good practice to remove location requests when the activity is in a paused or // stopped state. Doing so helps battery performance and is especially // recommended in applications that request frequent location updates. LocationServices.FusedLocationApi.removeLocationUpdates( mGoogleApiClient, this ).setResultCallback(new ResultCallback<Status>() { @Override public void onResult(Status status) { mRequestingLocationUpdates = false; // setButtonsEnabledState(); } }); } /** * Stores activity data in the Bundle. */ public void onSaveInstanceState(Bundle savedInstanceState) { savedInstanceState.putBoolean(KEY_REQUESTING_LOCATION_UPDATES, mRequestingLocationUpdates); savedInstanceState.putParcelable(KEY_LOCATION, mCurrentLocation); savedInstanceState.putString(KEY_LAST_UPDATED_TIME_STRING, mLastUpdateTime); super.onSaveInstanceState(savedInstanceState); } }
ScreenShots
======
Demo:
References
https://developers.google.com/maps/documentation/android-api/code-samples
No comments:
Post a Comment