Android 每10公里获取一次位置更改

Android 每10公里获取一次位置更改,android,gps,Android,Gps,我想在距离最后知道的位置10公里后检查我的服务位置。是否可以不请求所有时间当前位置?(因为现在应用程序每次都试图获取当前位置)。如果是的话,怎么办?我所有的位置代码几乎等于应答代码,它从主活动中的服务开始尝试将服务类更改为IntentService 另一方面,我使用BroadcastReceiver每10秒提供一次显示当前位置更新的演示。 同样在这个演示中,我使用了位置更新时的通知显示 就像下面的代码 public class LocationUpdatesBroadcastReceiver e

我想在距离最后知道的位置10公里后检查我的服务位置。是否可以不请求所有时间当前位置?(因为现在应用程序每次都试图获取当前位置)。如果是的话,怎么办?我所有的位置代码几乎等于应答代码,它从主活动中的服务开始

尝试将服务类更改为IntentService

另一方面,我使用BroadcastReceiver每10秒提供一次显示当前位置更新的演示。 同样在这个演示中,我使用了位置更新时的通知显示

就像下面的代码

public class LocationUpdatesBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "LUBroadcastReceiver";

public static final String ACTION_PROCESS_UPDATES =
        "com.google.android.gms.location.sample.backgroundlocationupdates.action" +
                ".PROCESS_UPDATES";

@Override
public void onReceive(Context context, Intent intent) {
    if (intent != null) {
        final String action = intent.getAction();
        if (ACTION_PROCESS_UPDATES.equals(action)) {
            LocationResult result = LocationResult.extractResult(intent);
            if (result != null) {
                List<Location> locations = result.getLocations();
                LocationResultHelper locationResultHelper = new LocationResultHelper(
                        context, locations);
                // Save the location data to SharedPreferences.
                locationResultHelper.saveResults();
                // Show notification with the location data.
                locationResultHelper.showNotification();
                Log.i(TAG, LocationResultHelper.getSavedLocationResult(context));
            }
        }
    }
}
*此类用于显示通知并将位置数据存储到共享首选项中。 */

公共类位置结果器{

   final public static String KEY_LOCATION_UPDATES_RESULT = "location-     update-result";

final private static String PRIMARY_CHANNEL = "default";


private Context mContext;
private List<Location> mLocations;
private NotificationManager mNotificationManager;

/**
 * this constructor used to initialised this class.
 * @param context
 * @param locations
 */
public LocationResultHelper(Context context, List<Location> locations) {
    mContext = context;
    mLocations = locations;

    NotificationChannel channel = new NotificationChannel(PRIMARY_CHANNEL,
            context.getString(R.string.default_channel), NotificationManager.IMPORTANCE_DEFAULT);
    channel.setLightColor(Color.GREEN);
    channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
    getNotificationManager().createNotificationChannel(channel);
}

/**
 * this method used to report location with date and time.
 */
private String getLocationResultTitle() {
    String numLocationsReported = mContext.getResources().getQuantityString(
            R.plurals.num_locations_reported, mLocations.size(), mLocations.size());
    return numLocationsReported + ": " + DateFormat.getDateTimeInstance().format(new Date());
}

/**
 * this method used to give location data.
 * @return
 */
private String getLocationResultText() {
    if (mLocations.isEmpty()) {
        return mContext.getString(R.string.unknown_location);
    }
    StringBuilder sb = new StringBuilder();
    for (Location location : mLocations) {
        sb.append("(");
        sb.append(location.getLatitude());
        sb.append(", ");
        sb.append(location.getLongitude());
        sb.append(")");
        sb.append("\n");
    }
    return sb.toString();
}

/**
 * this method save data into shared preferences.
 */
public void saveResults() {
    PreferenceManager.getDefaultSharedPreferences(mContext)
            .edit()
            .putString(KEY_LOCATION_UPDATES_RESULT, getLocationResultTitle() + "\n" +
                    getLocationResultText())
            .apply();
}

/**
 * this method get shared preferences store location update.
 */
public static String getSavedLocationResult(Context context) {
    return PreferenceManager.getDefaultSharedPreferences(context)
            .getString(KEY_LOCATION_UPDATES_RESULT, "");
}

/**
 * Get the notification mNotificationManager.
 * <p>
 * Utility method as this helper works with it a lot.
 *
 * @return The system service NotificationManager
 */
private NotificationManager getNotificationManager() {
    if (mNotificationManager == null) {
        mNotificationManager = (NotificationManager) mContext.getSystemService(
                Context.NOTIFICATION_SERVICE);
    }
    return mNotificationManager;
}

/**
 * Displays a notification with the location results.
 */
}

然后,为请求位置数据创建第三个类

/** *此类用于保存为位置更新请求选择的用户和删除位置更新。 */

公共类LocationRequestHelper{

final static public String KEY_LOCATION_UPDATES_REQUESTED = "location-updates-requested";

public static void setRequesting(Context context, boolean value) {
    PreferenceManager.getDefaultSharedPreferences(context)
            .edit()
            .putBoolean(KEY_LOCATION_UPDATES_REQUESTED, value)
            .apply();
}

public static boolean getRequesting(Context context) {
    return PreferenceManager.getDefaultSharedPreferences(context)
            .getBoolean(KEY_LOCATION_UPDATES_REQUESTED, false);
}
}

然后制定主要活动并实施所有事项

public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener,
    SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = MainActivity.class.getSimpleName();
private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;
/**
 * The used for interval for location updates.
 */
private static final long UPDATE_INTERVAL = 10 * 1000;

/**
 * The fastest interval to update for active location updates.
 */
private static final long FASTEST_UPDATE_INTERVAL = UPDATE_INTERVAL / 2;

/**
 * The max time to wait for location update.
 */
private static final long MAX_WAIT_TIME = UPDATE_INTERVAL * 3;

/**
 * Stores parameters for requests to the FusedLocationProviderApi.
 */
private LocationRequest mLocationRequest;

/**
 * The entry point to Google Play Services.
 */
private GoogleApiClient mGoogleApiClient;

private Button mRequestUpdatesButton;
private Button mRemoveUpdatesButton;
private TextView mLocationUpdatesResultView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initView();
}

/**
 * this method initialized view control.
 */
private void initView() {
    mRequestUpdatesButton = (Button) findViewById(R.id.request_updates_button);
    mRemoveUpdatesButton = (Button) findViewById(R.id.remove_updates_button);
    mLocationUpdatesResultView = (TextView) findViewById(R.id.location_updates_result);

    // Check if the user revoked runtime permissions.
    if (!checkPermissions()) {
        requestPermissions();
    }

    buildGoogleApiClient();

}

@Override
protected void onStart() {
    super.onStart();
    PreferenceManager.getDefaultSharedPreferences(this)
            .registerOnSharedPreferenceChangeListener(this);
}


@Override
protected void onResume() {
    super.onResume();
    updateButtonsState(LocationRequestHelper.getRequesting(this));
    mLocationUpdatesResultView.setText(LocationResultHelper.getSavedLocationResult(this));
}

@Override
protected void onStop() {
    PreferenceManager.getDefaultSharedPreferences(this)
            .unregisterOnSharedPreferenceChangeListener(this);
    super.onStop();
}

/**
 * this method used to location data update settings.
 */
private void createLocationRequest() {
    mLocationRequest = new LocationRequest();

    mLocationRequest.setInterval(UPDATE_INTERVAL);

    // 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);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    // Sets the maximum time when batched location updates are delivered. Updates may be
    // delivered sooner than this interval.
    mLocationRequest.setMaxWaitTime(MAX_WAIT_TIME);
}

/**
 * this method used to invoke google location service.
 */
private void buildGoogleApiClient() {
    if (mGoogleApiClient != null) {
        return;
    }
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .enableAutoManage(this, this)
            .addApi(LocationServices.API)
            .build();
    createLocationRequest();
}

@Override
public void onConnected(@Nullable Bundle bundle) {
    Log.i(TAG, "GoogleApiClient connected");
}

/**
 * this method call particular class or services
 * if you used intent service then pass intent in class name LocationUpdatesIntentService
 *if you used Broadcast  service then pass intent in class name LocationUpdatesBroadcastReceiver
 * @return
 */
private PendingIntent getPendingIntent() {
    Intent intent = new Intent(this, LocationUpdatesBroadcastReceiver.class);
    intent.setAction(LocationUpdatesBroadcastReceiver.ACTION_PROCESS_UPDATES);
    return PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}

@Override
public void onConnectionSuspended(int i) {
    final String text = "Connection suspended";
    Log.w(TAG, text + ": Error code: " + i);
    showSnackbar("Connection suspended");
}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    final String text = "Exception while connecting to Google Play services";
    Log.w(TAG, text + ": " + connectionResult.getErrorMessage());
    showSnackbar(text);
}

/**
 * this method show snack bar notification.
 */
private void showSnackbar(final String text) {
    View container = findViewById(R.id.activity_main);
    if (container != null) {
        Snackbar.make(container, text, Snackbar.LENGTH_LONG).show();
    }
}

/**
 * this method check permission and return current state of permission need.
 */
private boolean checkPermissions() {
    int permissionState = ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION);
    return permissionState == PackageManager.PERMISSION_GRANTED;
}

/**
 * this method request to permission asked.
 */
private void requestPermissions() {
    boolean shouldProvideRationale =
            ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_FINE_LOCATION);

    if (shouldProvideRationale) {
        Log.i(TAG, "Displaying permission rationale to provide additional context.");
        Snackbar.make(
                findViewById(R.id.activity_main),
                R.string.permission_rationale,
                Snackbar.LENGTH_INDEFINITE)
                .setAction(R.string.ok, new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        // Request permission
                        ActivityCompat.requestPermissions(MainActivity.this,
                                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                                REQUEST_PERMISSIONS_REQUEST_CODE);
                    }
                })
                .show();
    } else {
        Log.i(TAG, "Requesting permission");
        // previously and checked "Never ask again".
        ActivityCompat.requestPermissions(MainActivity.this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                REQUEST_PERMISSIONS_REQUEST_CODE);
    }
}

/**
 * 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 was granted. Kick off the process of building and connecting
            // GoogleApiClient.
            buildGoogleApiClient();
        } else {
            // Permission denied.
            Snackbar.make(
                    findViewById(R.id.activity_main),
                    R.string.permission_denied_explanation,
                    Snackbar.LENGTH_INDEFINITE)
                    .setAction(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);
                        }
                    })
                    .show();
        }
    }
}

@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
    if (s.equals(LocationResultHelper.KEY_LOCATION_UPDATES_RESULT)) {
        mLocationUpdatesResultView.setText(LocationResultHelper.getSavedLocationResult(this));
    } else if (s.equals(LocationRequestHelper.KEY_LOCATION_UPDATES_REQUESTED)) {
        updateButtonsState(LocationRequestHelper.getRequesting(this));
    }
}

/**
 * Handles the Request Updates button and requests start of location updates also disable button after selected.
 */
public void requestLocationUpdates(View view) {
    try {
        Log.i(TAG, "Starting location updates");
        LocationRequestHelper.setRequesting(this, true);
        LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient, mLocationRequest, getPendingIntent());
    } catch (SecurityException e) {
        LocationRequestHelper.setRequesting(this, false);
        e.printStackTrace();
    }
}

/**
 * Handles the Remove Updates button, and requests removal of location updates also disable button after selected.
 */
public void removeLocationUpdates(View view) {
    Log.i(TAG, "Removing location updates");
    LocationRequestHelper.setRequesting(this, false);
    LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient,
            getPendingIntent());
}

/**
 * maintain button state is selected or not if selected then show disable.
 */
private void updateButtonsState(boolean requestingLocationUpdates) {
    if (requestingLocationUpdates) {
        mRequestUpdatesButton.setEnabled(false);
        mRemoveUpdatesButton.setEnabled(true);
    } else {
        mRequestUpdatesButton.setEnabled(true);
        mRemoveUpdatesButton.setEnabled(false);
    }
}
公共类MainActivity扩展AppCompative实现GoogleAppClient.ConnectionCallbacks,
GoogleAppClient.OnConnectionFailedListener,
SharedReferences.OnSharedPreferenceChangeListener{
私有静态最终字符串标记=MainActivity.class.getSimpleName();
私有静态最终整数请求\权限\请求\代码=34;
/**
*用于位置更新的间隔。
*/
私有静态最终长更新间隔=10*1000;
/**
*活动位置更新的最快更新间隔。
*/
私有静态最终长最快更新间隔=更新间隔/2;
/**
*等待位置更新的最长时间。
*/
私有静态最终长最大等待时间=更新间隔*3;
/**
*存储对FusedLocationProviderApi的请求的参数。
*/
私人位置请求mLocationRequest;
/**
*Google Play服务的入口点。
*/
私人GoogleapClient MGoogleapClient;
私有按钮mRequestUpdatesButton;
私有按钮mRemoveUpdatesButton;
私有文本视图mLocationUpdatesResultView;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
/**
*此方法初始化了视图控件。
*/
私有void initView(){
mRequestUpdatesButton=(按钮)findViewById(R.id.request\u updates\u按钮);
mRemoveUpdatesButton=(按钮)findViewById(R.id.remove\u updates\u按钮);
mlLocationUpdatesResultView=(TextView)findViewById(R.id.location\u updates\u result);
//检查用户是否已吊销运行时权限。
如果(!checkPermissions()){
请求权限();
}
buildGoogleAppClient();
}
@凌驾
受保护的void onStart(){
super.onStart();
PreferenceManager.GetDefaultSharedReferences(此)
.RegisterOnSharedReferenceChangeListener(此);
}
@凌驾
受保护的void onResume(){
super.onResume();
UpdateButtonState(LocationRequestHelper.getRequesting(this));
mLocationUpdatesResultView.setText(LocationResultPer.getSavedLocationResult(this));
}
@凌驾
受保护的void onStop(){
PreferenceManager.GetDefaultSharedReferences(此)
.UnregisterSharedPreferenceChangeListener(此);
super.onStop();
}
/**
*此方法用于更新位置数据设置。
*/
私有void createLocationRequest(){
mlLocationRequest=新位置请求();
mLocationRequest.setInterval(更新间隔);
//设置活动位置更新的最快速率。此间隔是精确的,并且
//应用程序接收更新的速度永远不会超过此值。
mLocationRequest.setFastTestInterval(最快的更新间隔);
mLocationRequest.setPriority(位置请求.优先级高精度);
//设置交付批处理位置更新的最长时间。更新可能是
//比这个时间间隔早交货。
mLocationRequest.setMaxWaitTime(最大等待时间);
}
/**
*此方法用于调用google位置服务。
*/
私有void BuildGoogleAppClient(){
if(mGoogleApiClient!=null){
回来
}
mgoogleapclient=新的Googleapclient.Builder(此)
.addConnectionCallbacks(此)
.enableAutoManage(这个,这个)
.addApi(LocationServices.API)
.build();
createLocationRequest();
}
@凌驾
未连接的公共无效(@Nullable Bundle){
Log.i(标记“GoogleAppClient已连接”);
}
/**
*此方法调用特定的类或服务
*如果使用了intent服务,则在类名LocationUpdateContentService中传递intent
*如果您使用广播服务,则在类名LocationUpdatesBroadcastReceiver中传递意图
*@返回
*/
私有pendingent getpendingent(){
意向意向=新意向(此,LocationUpdatesBroadcastReceiver.class);
intent.setAction(LocationUpdatesBroadcastReceiver.ACTION\u PROCESS\u Update);
返回pendingent.getBroadcast(this,0,intent,pendingent.FLAG\u UPDATE\u CURRENT);
}
@凌驾
公共空间连接暂停(int i){
最终字符串text=“连接已挂起”;
Log.w(标记,文本+”:错误代码:“+i”);
showSnackbar(“连接暂停”);
}
@凌驾
public void onconnection失败(@NonNull ConnectionResult ConnectionResult){
final String text=“连接到Google Play服务时出现异常”;
Log.w(标记,文本+”:“+connectionResult.getErrorMessage());
showSnackbar(文本);
}
/**
*此方法显示快餐店通知。
*/
专用void showSnackbar(最终字符串文本){
视图容器=findviewbyd(R.id.activity\u main);
if(容器!=null){
Snackbar.make(容器、文本、Snackbar.LENGTH_LONG).show();
}
}
/**
*此方法检查权限并返回权限需要的当前状态。
*/
私有布尔检查权限(){
int permissionState=ActivityCompat.checkSelfPermission(此,
Manifest.permission.ACCES
final static public String KEY_LOCATION_UPDATES_REQUESTED = "location-updates-requested";

public static void setRequesting(Context context, boolean value) {
    PreferenceManager.getDefaultSharedPreferences(context)
            .edit()
            .putBoolean(KEY_LOCATION_UPDATES_REQUESTED, value)
            .apply();
}

public static boolean getRequesting(Context context) {
    return PreferenceManager.getDefaultSharedPreferences(context)
            .getBoolean(KEY_LOCATION_UPDATES_REQUESTED, false);
}
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener,
    SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = MainActivity.class.getSimpleName();
private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;
/**
 * The used for interval for location updates.
 */
private static final long UPDATE_INTERVAL = 10 * 1000;

/**
 * The fastest interval to update for active location updates.
 */
private static final long FASTEST_UPDATE_INTERVAL = UPDATE_INTERVAL / 2;

/**
 * The max time to wait for location update.
 */
private static final long MAX_WAIT_TIME = UPDATE_INTERVAL * 3;

/**
 * Stores parameters for requests to the FusedLocationProviderApi.
 */
private LocationRequest mLocationRequest;

/**
 * The entry point to Google Play Services.
 */
private GoogleApiClient mGoogleApiClient;

private Button mRequestUpdatesButton;
private Button mRemoveUpdatesButton;
private TextView mLocationUpdatesResultView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initView();
}

/**
 * this method initialized view control.
 */
private void initView() {
    mRequestUpdatesButton = (Button) findViewById(R.id.request_updates_button);
    mRemoveUpdatesButton = (Button) findViewById(R.id.remove_updates_button);
    mLocationUpdatesResultView = (TextView) findViewById(R.id.location_updates_result);

    // Check if the user revoked runtime permissions.
    if (!checkPermissions()) {
        requestPermissions();
    }

    buildGoogleApiClient();

}

@Override
protected void onStart() {
    super.onStart();
    PreferenceManager.getDefaultSharedPreferences(this)
            .registerOnSharedPreferenceChangeListener(this);
}


@Override
protected void onResume() {
    super.onResume();
    updateButtonsState(LocationRequestHelper.getRequesting(this));
    mLocationUpdatesResultView.setText(LocationResultHelper.getSavedLocationResult(this));
}

@Override
protected void onStop() {
    PreferenceManager.getDefaultSharedPreferences(this)
            .unregisterOnSharedPreferenceChangeListener(this);
    super.onStop();
}

/**
 * this method used to location data update settings.
 */
private void createLocationRequest() {
    mLocationRequest = new LocationRequest();

    mLocationRequest.setInterval(UPDATE_INTERVAL);

    // 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);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    // Sets the maximum time when batched location updates are delivered. Updates may be
    // delivered sooner than this interval.
    mLocationRequest.setMaxWaitTime(MAX_WAIT_TIME);
}

/**
 * this method used to invoke google location service.
 */
private void buildGoogleApiClient() {
    if (mGoogleApiClient != null) {
        return;
    }
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .enableAutoManage(this, this)
            .addApi(LocationServices.API)
            .build();
    createLocationRequest();
}

@Override
public void onConnected(@Nullable Bundle bundle) {
    Log.i(TAG, "GoogleApiClient connected");
}

/**
 * this method call particular class or services
 * if you used intent service then pass intent in class name LocationUpdatesIntentService
 *if you used Broadcast  service then pass intent in class name LocationUpdatesBroadcastReceiver
 * @return
 */
private PendingIntent getPendingIntent() {
    Intent intent = new Intent(this, LocationUpdatesBroadcastReceiver.class);
    intent.setAction(LocationUpdatesBroadcastReceiver.ACTION_PROCESS_UPDATES);
    return PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}

@Override
public void onConnectionSuspended(int i) {
    final String text = "Connection suspended";
    Log.w(TAG, text + ": Error code: " + i);
    showSnackbar("Connection suspended");
}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    final String text = "Exception while connecting to Google Play services";
    Log.w(TAG, text + ": " + connectionResult.getErrorMessage());
    showSnackbar(text);
}

/**
 * this method show snack bar notification.
 */
private void showSnackbar(final String text) {
    View container = findViewById(R.id.activity_main);
    if (container != null) {
        Snackbar.make(container, text, Snackbar.LENGTH_LONG).show();
    }
}

/**
 * this method check permission and return current state of permission need.
 */
private boolean checkPermissions() {
    int permissionState = ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION);
    return permissionState == PackageManager.PERMISSION_GRANTED;
}

/**
 * this method request to permission asked.
 */
private void requestPermissions() {
    boolean shouldProvideRationale =
            ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_FINE_LOCATION);

    if (shouldProvideRationale) {
        Log.i(TAG, "Displaying permission rationale to provide additional context.");
        Snackbar.make(
                findViewById(R.id.activity_main),
                R.string.permission_rationale,
                Snackbar.LENGTH_INDEFINITE)
                .setAction(R.string.ok, new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        // Request permission
                        ActivityCompat.requestPermissions(MainActivity.this,
                                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                                REQUEST_PERMISSIONS_REQUEST_CODE);
                    }
                })
                .show();
    } else {
        Log.i(TAG, "Requesting permission");
        // previously and checked "Never ask again".
        ActivityCompat.requestPermissions(MainActivity.this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                REQUEST_PERMISSIONS_REQUEST_CODE);
    }
}

/**
 * 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 was granted. Kick off the process of building and connecting
            // GoogleApiClient.
            buildGoogleApiClient();
        } else {
            // Permission denied.
            Snackbar.make(
                    findViewById(R.id.activity_main),
                    R.string.permission_denied_explanation,
                    Snackbar.LENGTH_INDEFINITE)
                    .setAction(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);
                        }
                    })
                    .show();
        }
    }
}

@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
    if (s.equals(LocationResultHelper.KEY_LOCATION_UPDATES_RESULT)) {
        mLocationUpdatesResultView.setText(LocationResultHelper.getSavedLocationResult(this));
    } else if (s.equals(LocationRequestHelper.KEY_LOCATION_UPDATES_REQUESTED)) {
        updateButtonsState(LocationRequestHelper.getRequesting(this));
    }
}

/**
 * Handles the Request Updates button and requests start of location updates also disable button after selected.
 */
public void requestLocationUpdates(View view) {
    try {
        Log.i(TAG, "Starting location updates");
        LocationRequestHelper.setRequesting(this, true);
        LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient, mLocationRequest, getPendingIntent());
    } catch (SecurityException e) {
        LocationRequestHelper.setRequesting(this, false);
        e.printStackTrace();
    }
}

/**
 * Handles the Remove Updates button, and requests removal of location updates also disable button after selected.
 */
public void removeLocationUpdates(View view) {
    Log.i(TAG, "Removing location updates");
    LocationRequestHelper.setRequesting(this, false);
    LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient,
            getPendingIntent());
}

/**
 * maintain button state is selected or not if selected then show disable.
 */
private void updateButtonsState(boolean requestingLocationUpdates) {
    if (requestingLocationUpdates) {
        mRequestUpdatesButton.setEnabled(false);
        mRemoveUpdatesButton.setEnabled(true);
    } else {
        mRequestUpdatesButton.setEnabled(true);
        mRemoveUpdatesButton.setEnabled(false);
    }
}
        <receiver
        android:name=".notification.LocationUpdatesBroadcastReceiver"
        android:exported="true">
        <intent-filter>
            <action android:name=".notification.LocationUpdatesBroadcastReceiver.ACTION_PROCESS_UPDATES" />
        </intent-filter>
    </receiver>