Reputation: 313
I am new to android and I am working in an android existing project.The app is crashing on android version >6.0, with below exception.Basically app is selecting photo from gallery which is working fine for the first time and on second time onwards the app is crashing giving permission denial exception.
java.lang.SecurityException: Permission Denial: reading com.google.android.apps.photos.contentprovider.MediaContentProvider uri content://com.google.android.apps.photos.contentprovider/0/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F1022/ORIGINAL/NONE/256350537 from pid=7789, uid=10145 requires the provider be exported, or grantUriPermission()
I have gone through few links and checked that android has introduce run time permissions and I have used below code to check the runtime permission.
The things I have tried so far...
2.Checking the runtime permission from code.
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
Log.d("Enter", "onRequestPermissionsResult: ");
switch (requestCode){
case REQUEST_CODE_PERMISSION:{
Map<String,Integer> perms = new HashMap<>();
//Initialize the map with the permissions
perms.put(Manifest.permission.ACCESS_COARSE_LOCATION,PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.CAMERA,PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.READ_EXTERNAL_STORAGE,PackageManager.PERMISSION_GRANTED);
// perms.put(Manifest.permission.READ_USER_DICTIONARY,PackageManager.PERMISSION_GRANTED);
//Fill with actual results from user
if (grantResults.length > 0){
for (int i = 0 ; i < permissions.length ; i++){
perms.put(permissions[i],grantResults[i]);
//check for all permissions
if (perms.get(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED
&& perms.get(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
&& perms.get(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED){
Log.d("Permission Granted", "onRequestPermissionsResult: ");
}else{
Log.d("Some", "onRequestPermissionsResult: ");
//if (perms.get(Manifest.permission.ACCESS_COARSE_LOCATION))
if (ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.CAMERA)
|| ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.ACCESS_COARSE_LOCATION)
|| ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.READ_EXTERNAL_STORAGE)){
new DialogInterface.OnClickListener(){
@Override
public void onClick (DialogInterface dialog, int which){
switch (which){
case DialogInterface.BUTTON_POSITIVE:
checkAndRequestPermission();
break;
case DialogInterface.BUTTON_NEGATIVE:
break;
}
}
};
}else{
Toast.makeText(this,"Go to Settings and enable Permissions",Toast.LENGTH_LONG).show();
}
}
}
}
}
}
}
private void showDialogOK(String message, DialogInterface.OnClickListener okListener){
new AlertDialog.Builder(this)
.setMessage(message)
.setPositiveButton("OK",okListener)
.setNegativeButton("Cancel",okListener)
.create()
.show();
}
}
And the line where it is crashing is :-
if (checkAndRequestPermission()){
InputStream fis = getContentResolver().openInputStream(Uri.parse(url)); //Crashing Line
BitmapFactory.decodeStream(fis, null, o);
fis.close();
}
Below are the permissions used in My Manifest:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_USER_DICTIONARY"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS"/>
<uses-permission android:name="com.google.android.apps.photos.permission.GOOGLE_PHOTOS"/>
<!-- <uses-permission android:name="com.google.android.apps.photos.permission.GOOGLE_PHOTOS"/>-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<!-- The following two permissions are not required to use
Google Maps Android API v2, but are recommended. -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="com.google.android.apps.photos.permission.GOOGLE_PHOTOS"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-feature android:name="android.hardware.location" android:required="true" />
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
Upvotes: 4
Views: 2150
Reputation: 313
After a lot of research I was able to fix the issue.The error was causing since the google photos needs a persistable URI of images,even if you have all codes for runtime permission and flags in Manifest file.
With the help of below answer I have fixed my issue. https://stackoverflow.com/a/29588566/1842304
Upvotes: 1
Reputation: 59
Try this Solution
in your OnCreate() method
@Override
protected void onCreate(Bundle savedInstanceState)
{
// your code
.................
// call dynamic permission
check_SD_CARD_Permissions();
}
public void check_SD_CARD_Permissions()
{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int permissionCheck = this.checkSelfPermission("Manifest.permission.WRITE_EXTERNAL_STORAGE");
permissionCheck += this.checkSelfPermission("Manifest.permission.READ_EXTERNAL_STORAGE");
if (permissionCheck != 0) {
this.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, 1001); //Any number
}
}else{
Log.d(TAG, "checkBTPermissions: No need to check permissions. SDK version < LOLLIPOP.");
}
}
in AndroidManifest.xml
add these permissions
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
and targetSdkVersion must be 23
<uses-sdk
android:minSdkVersion="13"
android:targetSdkVersion="23" />
Build your project with
Version : Android 6.0
and finally in project.properties target must be 23
target=android-23
it's working for me
Upvotes: 0
Reputation: 15775
The problem is not with your manifest permissions, but rather the URI being used. How did you get the URI? The logcat output tells you that the URI is for a content provider which was not exported or that the URI was not provided in an Intent
which granted temporary access to the ContentProvider
.
Upvotes: 2
Reputation: 2815
Note down all your permission that are working in manifest below android M. We dont need any additional permission for android M. We have to just request at runtime.
And request your permission like this. Change your permission(only dangerous permissions) as they are in manifest. Put this in onCreate
/// granting permission ////
if(!checkPermission())
{
requestPermission();
}
/////////////////////////////
And in class add these
/////////////////////// permission for marshmallow ///////////////////
private boolean checkPermission(){
int result1 = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE);
int result2 = ContextCompat.checkSelfPermission(this, Manifest.permission.MODIFY_PHONE_STATE);
int result3 = ContextCompat.checkSelfPermission(this, Manifest.permission.PROCESS_OUTGOING_CALLS);
int result4 = ContextCompat.checkSelfPermission(this, Manifest.permission.PROCESS_INCOMING_CALLS);
int result5 = ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE);
if (result1 == PackageManager.PERMISSION_GRANTED && result2 == PackageManager.PERMISSION_GRANTED &&
result3 == PackageManager.PERMISSION_GRANTED && result4 == PackageManager.PERMISSION_GRANTED
&& result5 == PackageManager.PERMISSION_GRANTED){
return true;
} else {
//Toast.makeText(this,"You don't have permission to use further features",Toast.LENGTH_LONG).show();
return false;
}
}
private void requestPermission(){
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_PHONE_STATE) &&
ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.MODIFY_PHONE_STATE) &&
ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.PROCESS_OUTGOING_CALLS) &&
ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.PROCESS_INCOMING_CALLS) &&
ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CALL_PHONE)){
Toast.makeText(this,"Application needs permission to use your camera, calls, storage and location.",Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_PHONE_STATE,
Manifest.permission.MODIFY_PHONE_STATE, Manifest.permission.PROCESS_OUTGOING_CALLS,
Manifest.permission.PROCESS_INCOMING_CALLS, Manifest.permission.CALL_PHONE},1);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 1:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED &&
grantResults[1] == PackageManager.PERMISSION_GRANTED &&
grantResults[2] == PackageManager.PERMISSION_GRANTED &&
grantResults[3] == PackageManager.PERMISSION_GRANTED &&
grantResults[4] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this,"Permission Granted.",Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this,"Permission Denied.",Toast.LENGTH_LONG).show();
}
break;
}
}
////////////////////////////////////////////////////////////////////////
Upvotes: 0