flutter app crashes after pressing back button
🐛 Bug Report
when you are in the app permission setting i.e : openAppSettings() and then if you press back button. flutter app crashes.
Expected behavior
if you are in the openAppSettings() and then press back button to return in your app. it should not crashing the app
Example of code :
Map<Permission, PermissionStatus> result = await [
Permission.storage,
Permission.manageExternalStorage
].request();
if (result[Permission.storage].isGranted && result[Permission.manageExternalStorage].isGranted) {
print("permission granted");
} else {
if(result[Permission.manageExternalStorage].isPermanentlyDenied || result[Permission.storage].isPermanentlyDenied){
print("Storage permission is permanently Denied");
openAppSettings();
}
}
error after crashing :
D/AndroidRuntime(18500): Shutting down VM
E/AndroidRuntime(18500): FATAL EXCEPTION: main
E/AndroidRuntime(18500): Process: com.example.ebag, PID: 18500
E/AndroidRuntime(18500): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=210, result=0, data=null} to activity {com.example.ebag/com.example.ebag.MainActivity}: java.lang.IllegalStateException: Reply already submitted
E/AndroidRuntime(18500): at android.app.ActivityThread.deliverResults(ActivityThread.java:5304)
E/AndroidRuntime(18500): at android.app.ActivityThread.handleSendResult(ActivityThread.java:5343)
E/AndroidRuntime(18500): at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:54)
E/AndroidRuntime(18500): at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
E/AndroidRuntime(18500): at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
E/AndroidRuntime(18500): at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
E/AndroidRuntime(18500): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2214)
E/AndroidRuntime(18500): at android.os.Handler.dispatchMessage(Handler.java:106)
E/AndroidRuntime(18500): at android.os.Looper.loopOnce(Looper.java:201)
E/AndroidRuntime(18500): at android.os.Looper.loop(Looper.java:288)
E/AndroidRuntime(18500): at android.app.ActivityThread.main(ActivityThread.java:7842)
E/AndroidRuntime(18500): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(18500): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
E/AndroidRuntime(18500): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
E/AndroidRuntime(18500): Caused by: java.lang.IllegalStateException: Reply already submitted
E/AndroidRuntime(18500): at io.flutter.embedding.engine.dart.DartMessenger$Reply.reply(DartMessenger.java:164)
E/AndroidRuntime(18500): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler$1.success(MethodChannel.java:238)
E/AndroidRuntime(18500): at com.baseflow.permissionhandler.-$$Lambda$fOfJ7OpNBkhP48Mtzqs01exhUJs.onSuccess(Unknown Source:2)
E/AndroidRuntime(18500): at com.baseflow.permissionhandler.PermissionManager.onActivityResult(PermissionManager.java:100)
E/AndroidRuntime(18500): at io.flutter.embedding.engine.FlutterEngineConnectionRegistry$FlutterEngineActivityPluginBinding.onActivityResult(FlutterEngineConnectionRegistry.java:741)
E/AndroidRuntime(18500): at io.flutter.embedding.engine.FlutterEngineConnectionRegistry.onActivityResult(FlutterEngineConnectionRegistry.java:426)
E/AndroidRuntime(18500): at io.flutter.embedding.android.FlutterActivityAndFragmentDelegate.onActivityResult(FlutterActivityAndFragmentDelegate.java:749)
E/AndroidRuntime(18500): at io.flutter.embedding.android.FlutterActivity.onActivityResult(FlutterActivity.java:651)
E/AndroidRuntime(18500): at android.app.Activity.dispatchActivityResult(Activity.java:8382)
E/AndroidRuntime(18500): at android.app.ActivityThread.deliverResults(ActivityThread.java:5297)
E/AndroidRuntime(18500): ... 13 more
I/flutter (18500): permission storage is permanently denied
I/flutter (18500): Permission denied storage permission is PermissionStatus.permanentlyDenied and External storage permission is null
I/Process (18500): Sending signal. PID: 18500 SIG: 9
Lost connection to device.
Configuration
Pixel 4 XL API 31 Version: 8.3.0
Platform:
- [ ] :iphone: iOS
- [x] :robot: Android
i recorded 26seconds video for this issue :
https://cdn.discordapp.com/attachments/924570284441346118/924570433188155423/vokoscreen-2021-12-26_11-19-06.mkv
i recorded 26seconds video for this issue :
https://cdn.discordapp.com/attachments/924570284441346118/924570433188155423/vokoscreen-2021-12-26_11-19-06.mkv
even if i enable the permission and press backbutton it will still crashes
there is a requestCode clash, flutter sends the same result to all listeners, you should avoid at least:
static final int PERMISSION_CODE = 24;
static final int PERMISSION_CODE_IGNORE_BATTERY_OPTIMIZATIONS = 209;
static final int PERMISSION_CODE_MANAGE_EXTERNAL_STORAGE = 210;
static final int PERMISSION_CODE_SYSTEM_ALERT_WINDOW = 211;
static final int PERMISSION_CODE_REQUEST_INSTALL_PACKAGES = 212;
static final int PERMISSION_CODE_ACCESS_NOTIFICATION_POLICY = 213;
just pick a fortunate number like 0x1337 :)
I have the same issue with iOS @sherpya Could you please elaborate your answer a bit?
I have the same issue with iOS @sherpya Could you please elaborate your answer a bit?
I suppose iOS work differently, but anyway on android you call startActivityForResult() passing an int code, when the activity is closed the data you put as result using setResult() is passed on each Activity() (or other listener) with same code.
If another Activity uses the result because listen for the same code, it can expose unespected results.
My app registered for the 213 code and the Activity (or listener) this package exponed was picking my result as PERMISSION_CODE_ACCESS_NOTIFICATION_POLICY.
I think the whole system is wrongly designed, the Activity/listener called startActivityForResult() should receive only his own results
@SashaMyh I had been confused for a few days until I saw the message of @sherpya. I change List<Permission>.request() to Permission.request(), request a permission at a time. It works perfectly.
final permissions = [
Permission.storage,
Permission.manageExternalStorage,
];
if (widget.permissions != null) {
permissions.addAll(widget.permissions!);
}
log(permissions.toString());
bool f = true;
for (var permission in permissions) {
final state = await permission.request();
if (!f || state != PermissionStatus.granted) {
f = false;
}
}
Is there a solution to this problem? I have the same problem, I requested the "manageExternalStorage" permission and the application crashed directly after returning. I also tried just requesting the permission individually, but that didn't work either.
I solve such problem with this code
More about here
// dont forget add import
import 'dart:io';
WillPopScope(
child: ..., // you app, maybe navigation stack
onWillPop: () async {
BuildContext? context = navigatorKeys[_selectedIndex].currentState.context;
bool maybePop = await Navigator.maybePop(context);
// if maybePop equal to false, then exit, else return false to prevent exit from app
if(!maybePop) {
exit(0);
}
return false;
},
),
I have started investigating, and the problem lies in requesting multiple permissions of which one opens the app's settings. The minimal code that reproduces the crash is
[Permission.storage, Permission.manageExternalStorage].request();