I want to ask for permission from the application class. How can I ask permission for accessing the device ID? I cannot ask for permission from activity as it crashes before starting the splash screen activity. The following code is part of splash screen activity.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
checkpermi();
The code for checking permission
public void checkpermi() {
if(ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
+ ContextCompat.checkSelfPermission(
this,Manifest.permission.READ_PHONE_STATE)
+ ContextCompat.checkSelfPermission(
this,Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED){
// Do something, when permissions not granted
if(ActivityCompat.shouldShowRequestPermissionRationale(
this,Manifest.permission.ACCESS_FINE_LOCATION)
|| ActivityCompat.shouldShowRequestPermissionRationale(
this,Manifest.permission.READ_PHONE_STATE)
|| ActivityCompat.shouldShowRequestPermissionRationale(
this,Manifest.permission.WRITE_EXTERNAL_STORAGE)){
// If we should give explanation of requested permissions
// Show an alert dialog here with request explanation
AlertDialog.Builder builder = new AlertDialog.Builder(SplashScreenActivity.this);
builder.setMessage("Location, Read Contacts and Write External" +
" Storage permissions are required to do the task.");
builder.setTitle("Please grant those permissions");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
ActivityCompat.requestPermissions(
SplashScreenActivity.this,
new String[]{
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
},
STORAGE_PERMISSION_CODE
);
}
});
builder.setNeutralButton("Cancel",null);
AlertDialog dialog = builder.create();
dialog.show();
}else{
// Directly request for required permissions, without explanation
ActivityCompat.requestPermissions(
this,
new String[]{
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
},
STORAGE_PERMISSION_CODE
);
}
}else {
// Do something, when permissions are already granted
Toast.makeText(SplashScreenActivity.this,"Permissions already granted",Toast.LENGTH_SHORT).show();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
//Checking the request code of our request
if(requestCode == STORAGE_PERMISSION_CODE){
//If permission is granted
if(grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
//Displaying a toast
Toast.makeText(this,"Permission granted now you can read the storage",Toast.LENGTH_LONG).show();
}else{
//Displaying another toast if permission is not granted
Toast.makeText(this,"Oops you just denied the permission",Toast.LENGTH_LONG).show();
}
}
}
But instead of opening the splash screen activity the on create method overrides with the on create method of the Collect.java application class and the codes are.
@Override
public void onCreate() {
singleton = this;
super.onCreate();
PropertyManager mgr = new PropertyManager(this);
mActivityLogger = new ActivityLogger(
mgr.getSingularProperty(PropertyManager.DEVICE_ID_PROPERTY));
}
If I cannot delete the above code because most of the buttons inside the app won't work.
And the error logs are.
2020-02-27 16:36:12.159 31359-31359/com.gic.spade.android E/AndroidRuntime: FATAL EXCEPTION: main Process: com.gic.spade.android, PID: 31359 java.lang.RuntimeException: Unable to create application com.gic.spade.android.application.Collect: java.lang.SecurityException: getDeviceId: Neither user 10366 nor current process has android.permission.READ_PHONE_STATE. at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6065) at android.app.ActivityThread.-wrap1(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1764) at android.os.Handler.dispatchMessage(Handler.java:105) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6944) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374) Caused by: java.lang.SecurityException: getDeviceId: Neither user 10366 nor current process has android.permission.READ_PHONE_STATE. at android.os.Parcel.readException(Parcel.java:1959) at android.os.Parcel.readException(Parcel.java:1905) at com.android.internal.telephony.ITelephony$Stub$Proxy.getDeviceId(ITelephony.java:5333) at android.telephony.TelephonyManager.getDeviceId(TelephonyManager.java:1069) at com.gic.spade.android.logic.PropertyManager.(PropertyManager.java:135) at com.gic.spade.android.application.Collect.onCreate(Collect.java:260) at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1125) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6062) at android.app.ActivityThread.-wrap1(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1764) at android.os.Handler.dispatchMessage(Handler.java:105) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6944) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
If you need a permission before you could even request the permission, maybe you should conclude that your code is not well architectured.
Simply bypass that code until you can restart it when permissions are granted.
In your question you seem to want to send the device ID when application is created. Just don't send it unless you have permission to get that.
if (checkPermission(...) == GRANTED) {
PropertyManager mgr = new PropertyManager(this);
mActivityLogger = new ActivityLogger(mgr.getSingularProperty(PropertyManager.DEVICE_ID_PROPERTY));
} else {
mActivityLogger = new ActivityLogger();
// Or even disable that logger altogether
}