Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package com.google.android.gms.location.sample.basiclocationsample; import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.location.Location; import android.net.Uri; import android.os.Bundle; import android.provider.Settings; import android.support.annotation.NonNull; import android.support.design.widget.Snackbar; import android.support.v4.app.ActivityCompat; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.TextView; import com.google.android.gms.location.FusedLocationProviderClient; import com.google.android.gms.location.LocationServices; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; import java.util.Locale; /** * Location sample. *
* Demonstrates use of the Location API to retrieve the last known location for a device. */ public class MainActivity extends AppCompatActivity { private static final String TAG = MainActivity.class.getSimpleName(); private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34; /** * Provides the entry point to the Fused Location Provider API. */ private FusedLocationProviderClient mFusedLocationClient; /** * Represents a geographical location. */ protected Location mLastLocation; private String mLatitudeLabel; private String mLongitudeLabel; private TextView mLatitudeText; private TextView mLongitudeText; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_activity); mLatitudeLabel = getResources().getString(R.string.latitude_label); mLongitudeLabel = getResources().getString(R.string.longitude_label); mLatitudeText = (TextView) findViewById((R.id.latitude_text)); mLongitudeText = (TextView) findViewById((R.id.longitude_text)); mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this); } @Override public void onStart() { super.onStart(); if (!checkPermissions()) { requestPermissions(); } else { getLastLocation(); } } /** * Provides a simple way of getting a device's location and is well suited for * applications that do not require a fine-grained location and that do not need location * updates. Gets the best and most recent location currently available, which may be null * in rare cases when a location is not available. *
* Note: this method should be called after location permission has been granted. */ @SuppressWarnings("MissingPermission") private void getLastLocation() { mFusedLocationClient.getLastLocation() .addOnCompleteListener(this, new OnCompleteListener() { @Override public void onComplete(@NonNull Task task) { if (task.isSuccessful() && task.getResult() != null) { mLastLocation = task.getResult(); mLatitudeText.setText(String.format(Locale.ENGLISH, "%s: %f", mLatitudeLabel, mLastLocation.getLatitude())); mLongitudeText.setText(String.format(Locale.ENGLISH, "%s: %f", mLongitudeLabel, mLastLocation.getLongitude())); } else { Log.w(TAG, "getLastLocation:exception", task.getException()); showSnackbar(getString(R.string.no_location_detected)); } } }); } /** * Shows a {@link Snackbar} using {@code text}. * * @param text The Snackbar text. */ private void showSnackbar(final String text) { View container = findViewById(R.id.main_activity_container); if (container != null) { Snackbar.make(container, text, Snackbar.LENGTH_LONG).show(); } } /** * Shows a {@link Snackbar}. * * @param mainTextStringId The id for the string resource for the Snackbar text. * @param actionStringId The text of the action item. * @param listener The listener associated with the Snackbar action. */ private void showSnackbar(final int mainTextStringId, final int actionStringId, View.OnClickListener listener) { Snackbar.make(findViewById(android.R.id.content), getString(mainTextStringId), Snackbar.LENGTH_INDEFINITE) .setAction(getString(actionStringId), listener).show(); } /** * Return the current state of the permissions needed. */ private boolean checkPermissions() { int permissionState = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION); return permissionState == PackageManager.PERMISSION_GRANTED; } private void startLocationPermissionRequest() { ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_PERMISSIONS_REQUEST_CODE); } private void requestPermissions() { boolean shouldProvideRationale = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION); // Provide an additional rationale to the user. This would happen if the user denied the // request previously, but didn't check the "Don't ask again" checkbox. if (shouldProvideRationale) { Log.i(TAG, "Displaying permission rationale to provide additional context."); showSnackbar(R.string.permission_rationale, android.R.string.ok, new View.OnClickListener() { @Override public void onClick(View view) { // Request permission startLocationPermissionRequest(); } }); } else { Log.i(TAG, "Requesting permission"); // Request permission. It's possible this can be auto answered if device policy // sets the permission in a given state or the user denied the permission // previously and checked "Never ask again". startLocationPermissionRequest(); } } /** * Callback received when a permissions request has been completed. */ @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { Log.i(TAG, "onRequestPermissionResult"); if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) { if (grantResults.length <= 0) { // If user interaction was interrupted, the permission request is cancelled and you // receive empty arrays. Log.i(TAG, "User interaction was cancelled."); } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Permission granted. getLastLocation(); } else { // Permission denied. // Notify the user via a SnackBar that they have rejected a core permission for the // app, which makes the Activity useless. In a real app, core permissions would // typically be best requested during a welcome-screen flow. // Additionally, it is important to remember that a permission might have been // rejected without asking the user for permission (device policy or "Never ask // again" prompts). Therefore, a user interface affordance is typically implemented // when permissions are denied. Otherwise, your app could appear unresponsive to // touches or interactions which have required permissions. showSnackbar(R.string.permission_denied_explanation, R.string.settings, new View.OnClickListener() { @Override public void onClick(View view) { // Build intent that displays the App settings screen. Intent intent = new Intent(); intent.setAction( Settings.ACTION_APPLICATION_DETAILS_SETTINGS); Uri uri = Uri.fromParts("package", BuildConfig.APPLICATION_ID, null); intent.setData(uri); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } }); } } } }