基于Marshmallow的自定义设备PermissionActivity重复创建问题求助
Alright, let's tackle this double-launch issue with your PermissionActivity. Even though your BootReceiver only fires once, there are a few edge cases in Android's activity lifecycle and permission handling (especially on Marshmallow) that could cause this duplication. Here are the targeted fixes I recommend:
1. Switch to singleTask launch mode for PermissionActivity
The singleTop mode only prevents launching a new instance if the activity is already at the top of the stack. But if the activity isn’t in the stack at all, it will still create a new one. Using singleTask ensures there’s only one instance of PermissionActivity across the entire task stack—exactly what we need to avoid duplicates.
Update your manifest entry:
<activity android:name=".PermissionActivity" android:launchMode="singleTask"/>
2. Add FLAG_ACTIVITY_CLEAR_TOP when launching PermissionActivity
When starting PermissionActivity from BootReceiver, combine FLAG_ACTIVITY_NEW_TASK with FLAG_ACTIVITY_CLEAR_TOP. This will clear any existing instances of PermissionActivity from the stack and bring the existing one to the foreground (instead of creating a new one), which pairs perfectly with singleTask mode.
Modify your BootReceiver code:
Intent i = new Intent(); i.setClassName("com.mgroup.carnumberapp", "com.mgroup.carnumberapp.PermissionActivity"); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); i.putExtra("from", "boot receiver"); context.startActivity(i);
3. Handle onNewIntent in PermissionActivity
Since we’re using singleTask, any new intents sent to PermissionActivity will trigger onNewIntent instead of creating a new instance. We need to handle this to avoid re-running permission logic unnecessarily.
Add this to your PermissionActivity:
@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); // Skip permission request if we already have access if (UtilityFunctions.checkPermission(this, Manifest.permission.READ_PHONE_STATE)) { startMainActivity(); finish(); } } private void startMainActivity() { Intent mainIntent = new Intent(this, MainActivity.class); mainIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(mainIntent); }
4. Prevent duplicate permission requests on Activity recreation
On Marshmallow, the system can temporarily destroy and recreate your activity during the permission request flow (though rare in a boot scenario). Save the state of your permission request to avoid re-requesting.
Add this to PermissionActivity:
private static final int PERMISSION_REQUEST_CODE = 100; private boolean isPermissionRequested = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Restore state if activity was recreated if (savedInstanceState != null) { isPermissionRequested = savedInstanceState.getBoolean("isPermissionRequested", false); } // Only request permission if we haven't already if (!isPermissionRequested) { ActivityCompat.requestPermissions( this, new String[]{Manifest.permission.READ_PHONE_STATE}, PERMISSION_REQUEST_CODE ); isPermissionRequested = true; } } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean("isPermissionRequested", isPermissionRequested); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == PERMISSION_REQUEST_CODE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { startMainActivity(); finish(); // Close PermissionActivity to avoid leaving it in the stack } else { // Optional: Handle permission denial (e.g., show a message or re-request) } } }
5. Verify SharedPreferences update logic
Ensure that in MainActivity, after successfully sending data to the server, you’re correctly updating the is_num_updated flag with a committed editor:
SharedPreferences.Editor editor = getSharedPreferences("car_num", MODE_PRIVATE).edit(); editor.putBoolean("is_num_updated", true); editor.apply(); // Use commit() if you need immediate persistence
These changes should eliminate duplicate PermissionActivity instances and prevent the MainActivity dialog from showing twice. The core fix is ensuring only one instance of PermissionActivity exists at any time, paired with handling edge cases in the activity lifecycle and permission flow.
内容的提问来源于stack exchange,提问作者Gil Akrish

