You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何确保权限授予后再绑定Android前台服务?

Fixing Premature Service Binding in Google's Play Location Sample

Great question! Let's walk through the correct way to ensure you only call bindService() after location permissions have been granted—this is a common pitfall with Android's dynamic permission model, and getting it right will resolve the issue you're facing.

Core Issue Recap

The sample app's original onStart() method calls bindService() directly at line 151, but Android 6.0+ requires dangerous permissions (like ACCESS_FINE_LOCATION/ACCESS_COARSE_LOCATION) to be granted dynamically by the user. Binding the service before permissions are granted will cause unexpected behavior, exactly as noted in the issue you referenced.

Step-by-Step Solution

1. Create a Helper Method to Verify Permission Status

First, make a reusable method to check if all required location permissions are granted. Always use Android's official permission check method instead of custom logic—it's the only reliable way to confirm permission status:

private boolean hasRequiredLocationPermissions() {
    int fineLocationPerm = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
    int coarseLocationPerm = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION);
    
    return fineLocationPerm == PackageManager.PERMISSION_GRANTED 
            && coarseLocationPerm == PackageManager.PERMISSION_GRANTED;
}

2. Modify onStart() to Conditionally Bind the Service

Replace the direct bindService() call in onStart() with a conditional check. If permissions are already granted, bind the service; if not, trigger the permission request flow:

@Override
protected void onStart() {
    super.onStart();
    // Keep all your existing onStart() logic here...
    
    // Replace the original bindService line with this check
    if (hasRequiredLocationPermissions()) {
        bindService(
            new Intent(this, LocationUpdatesService.class), 
            mServiceConnection, 
            Context.BIND_AUTO_CREATE
        );
    } else {
        requestLocationPermissions();
    }
}

3. Implement Permission Request and Callback Handling

Add code to request permissions, and bind the service only after the user grants them in the permission callback:

private static final int REQUEST_LOCATION_PERMISSIONS = 1001;

private void requestLocationPermissions() {
    ActivityCompat.requestPermissions(
        this,
        new String[]{
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
        },
        REQUEST_LOCATION_PERMISSIONS
    );
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    
    if (requestCode == REQUEST_LOCATION_PERMISSIONS) {
        // Verify all required permissions were granted
        boolean allPermissionsGranted = true;
        for (int result : grantResults) {
            if (result != PackageManager.PERMISSION_GRANTED) {
                allPermissionsGranted = false;
                break;
            }
        }
        
        if (allPermissionsGranted) {
            // Permissions approved—now bind the service
            bindService(
                new Intent(this, LocationUpdatesService.class), 
                mServiceConnection, 
                Context.BIND_AUTO_CREATE
            );
        } else {
            handlePermissionDenial();
        }
    }
}

4. Handle Permission Denial Gracefully

Add logic to handle cases where the user rejects permissions, including when they check "Never ask again":

private void handlePermissionDenial() {
    // Check if we can show a rationale for the permission
    boolean canShowRationale = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)
            || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION);
    
    if (!canShowRationale) {
        // User checked "Never ask again"—direct them to app settings
        new AlertDialog.Builder(this)
                .setTitle("Location Permission Required")
                .setMessage("This app needs location permissions to function properly. Please enable them in your device settings.")
                .setPositiveButton("Open Settings", (dialog, which) -> {
                    Intent settingsIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                    Uri appUri = Uri.fromParts("package", getPackageName(), null);
                    settingsIntent.setData(appUri);
                    startActivity(settingsIntent);
                })
                .setNegativeButton("Cancel", null)
                .show();
    } else {
        // Show a simple toast explaining why we need the permission
        Toast.makeText(this, "Location permissions are required to receive location updates", Toast.LENGTH_LONG).show();
    }
}

Why Your Previous Fix Might Have Failed

If your initial conditional check didn't work, it's likely one of these reasons:

  • You only checked one location permission (both ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION are needed for most location features)
  • You used custom permission-check logic instead of ContextCompat.checkSelfPermission()
  • You didn't bind the service in the onRequestPermissionsResult() callback, so the app never tried to bind after the user granted permissions

内容的提问来源于stack exchange,提问作者HelpingHand

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:06:23