Closed zztmercury closed 5 years ago
I tried to run the sample project in android 9 emulator and used application context to request permissions, but it worked as expected. Can you provide me a minimal code that leads to the crash?
public class MyService extends Service {
private static final String TAG = "MyService";
private LocalBinder mBinder = new LocalBinder();
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public class LocalBinder extends Binder {
public MyService getService(){
return MyService.this;
}
}
public void requestWriteExternalStoragePermission() {
Permissions.check(this, Manifest.permission.WRITE_EXTERNAL_STORAGE, "need permissions", new PermissionHandler() {
@Override
public void onGranted() {
Log.d(TAG, "onGranted");
}
});
}
}
Start with Permission WRITE_EXTERNAL_STORAGE not granted
Hello, sorry for the late response. I used your code and It is still working.
In MainActivity, I added the following code:
private boolean mServiceBound = false;
MyService mBoundService;
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
mServiceBound = false;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MyService.LocalBinder myBinder = (MyService.LocalBinder) service;
mBoundService = myBinder.getService();
mServiceBound = true;
}
};
@Override
protected void onStart() {
super.onStart();
Intent intent = new Intent(this, MyService.class);
startService(intent);
bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
if (mServiceBound) {
unbindService(mServiceConnection);
mServiceBound = false;
}
}
Then I called mBoundService.requestWriteExternalStoragePermission();
on button click, it worked just fine in my emulator. Is there anything that I'm missing? Have you encountered this problem in single device or in emulator too?
I'm not sure if this fits the OP's project or not, but consider the case where you don't have an Activity, i.e. you're running from a service started e.g. by intercepting the android.intent.action.BOOT_COMPLETED or more recently from an WorkManager task (where you don't have neither an activity nor a service!).
The workaround on the code as is is to instantiate an activity just for calling Permissions.check.
The fix to avoid that would be to provide an option in the Options object (i.e. a boolean for e.g. named newTask) and then:
else {
PermissionsActivity.permissionHandler = handler;
ArrayList<String> permissionsList = new ArrayList<>(permissionsSet);
Intent intent = new Intent(context, PermissionsActivity.class)
.putExtra(PermissionsActivity.EXTRA_PERMISSIONS, permissionsList)
.putExtra(PermissionsActivity.EXTRA_RATIONALE, rationale)
.putExtra(PermissionsActivity.EXTRA_OPTIONS, options);
if (options.newTask) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
context.startActivity(intent);
}
android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want? at android.app.ContextImpl.startActivity(ContextImpl.java:1072) at android.app.ContextImpl.startActivity(ContextImpl.java:1041)
With Android 9, you cannot start an activity from a non-activity context unless you pass the intent flag FLAG_ACTIVITY_NEW_TASK. If you attempt to start an activity without passing this flag, the activity does not start, and the system prints a message to the log.