I think my permissions properly located on AndroidManifest.xml.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.ganedu.intent">
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".NextActivity"
android:label="This is next_activity"/>
</application>
</manifest>
I have "android.permission.READ_EXTERNAL_STORAGE" and "android.permission.WRITE_EXTERNAL_STORAGE" right after manifest.
but the error is keep occured.
Caused by: java.lang.SecurityException: Permission Denial: reading
com.android.providers.media.MediaProvider uri
content://media/external/images/media/40 from pid=2473, uid=10073
requires android.permission.READ_EXTERNAL_STORAGE, or
grantUriPermission()
and this is my MainActivity.java
public class MainActivity extends AppCompatActivity {
public static final int IMAGE_GALLERY_REQUEST = 20;
Button btnStart;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void gallery_open(View view) {
Intent galleryPickerIntent = new Intent(Intent.ACTION_PICK);
File pictureDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
String pictureDirectoryPath = pictureDirectory.getPath();
Uri data = Uri.parse(pictureDirectoryPath);
galleryPickerIntent.setDataAndType(data,"image/*");
startActivityForResult(galleryPickerIntent, IMAGE_GALLERY_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent){
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
if(resultCode == Activity.RESULT_OK){
if(requestCode == IMAGE_GALLERY_REQUEST) {
onSelectedFromGalleryResult(imageReturnedIntent);
}
}
}
private void onSelectedFromGalleryResult(Intent data){
Bitmap bm = null;
if(data != null){
try{
bm = MediaStore.Images.Media.getBitmap(getApplicationContext().getContentResolver(), data.getData());
}catch(IOException e){
e.printStackTrace();
}
//ivImage.setImageBitmap(bm);
ImageView imgView = (ImageView)findViewById(R.id.ivImage);
imgView.setImageBitmap(bm);
}
}
James I suppose you are facing this error on Android 6.0 or onwards. You need to handle the permissions explicitly in these versions.
Please find the android developer link
https://developer.android.com/guide/topics/permissions/requesting.html
You need to provide the run time permission for android marshmallow version
You can add this code in onCreate() or any click events, try this:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1){
// requestPermission();
requestAppPermissions(new String[]{
Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE },
R.string.app_name, REQUEST_PERMISSIONS);
//this code will be executed on devices running ICS or later
}
also add this function for requesting the run time permission
public void requestAppPermissions(final String[] requestedPermissions,
final int stringId, final int requestCode) {
mErrorString.put(requestCode, stringId);
int permissionCheck = PackageManager.PERMISSION_GRANTED;
boolean shouldShowRequestPermissionRationale = false;
for (String permission : requestedPermissions) {
permissionCheck = permissionCheck + ContextCompat.checkSelfPermission(this, permission);
shouldShowRequestPermissionRationale = shouldShowRequestPermissionRationale || ActivityCompat.shouldShowRequestPermissionRationale(this, permission);
}
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
if (shouldShowRequestPermissionRationale) {
Snackbar.make(findViewById(android.R.id.content), stringId,
Snackbar.LENGTH_INDEFINITE).setAction("GRANT",
new View.OnClickListener() {
#Override
public void onClick(View v) {
ActivityCompat.requestPermissions(DashBoardActivity.this, requestedPermissions, requestCode);
}
}).show();
} else {
ActivityCompat.requestPermissions(this, requestedPermissions, requestCode);
}
} else {
onPermissionsGranted(requestCode);
}
}
This function is called when the permission is granted and you can read the internal and external storage
public void onPermissionsGranted(final int requestCode) {
Toast.makeText(this, "Permissions Received.", Toast.LENGTH_LONG).show();
}
The below code for checking the requested permission result
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
int permissionCheck = PackageManager.PERMISSION_GRANTED;
for (int permission : grantResults) {
permissionCheck = permissionCheck + permission;
}
if ((grantResults.length > 0) && permissionCheck == PackageManager.PERMISSION_GRANTED) {
onPermissionsGranted(requestCode);
} else {
Snackbar.make(findViewById(android.R.id.content), mErrorString.get(requestCode),
Snackbar.LENGTH_INDEFINITE).setAction("ENABLE",
new View.OnClickListener() {
#Override
public void onClick(View v) {
}
}).show();
}
}
Related
I'm developing app in which we pick image from Camera OR Gallery using intents and set to ImageView. The camera button feature is working perfect.
The problem is when first time I click Gallery button it asks permission when I allow the permission it the app crashes but gallery opens. Then second time when I open app and click the Gallery button again then works fine.
Here is my code:
The WRITE_EXTERNAL_STORAGE permission is used for both taking image from camera intent and also taking image from Galley intent may be that is causing the problem. But I'm new in android development so don't know how to solve it.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.blogspot.atifsoftwares.myapplication">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<ImageView
android:id="#+id/imageIv"
android:layout_width="match_parent"
android:layout_height="300dp"
android:scaleType="fitCenter"
android:src="#drawable/ic_launcher_background" />
<Button
android:id="#+id/galleryBtn"
android:text="Gallery"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="#+id/cameraBtn"
android:text="Camera"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
MainActivity.java
package com.blogspot.atifsoftwares.myapplication;
import android.Manifest;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private static final int IMAGE_PICK_GALLERY_CODE = 1000;
private static final int IMAGE_PICK_CAMERA_CODE = 1001;
private static final int PERMISSION_WRITE_STORAGE_CODE = 1002;
private static final int PERMISSION_CAMERA_CODE = 1003;
Uri image_uri;
ImageView mImageView;
Button mGalleryBtn, mCameraBtn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = findViewById(R.id.imageIv);
mGalleryBtn = findViewById(R.id.galleryBtn);
mCameraBtn = findViewById(R.id.cameraBtn);
//Gallery button click listener to pick image from gallery
mGalleryBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
//System OS is Marshmallow or above
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_DENIED){
//permission not granted, request it.
String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
//show popup for runtime permission
requestPermissions(permissions, PERMISSION_WRITE_STORAGE_CODE);
}
else {
//permission already granted
pickGallery();
}
}
else {
//System OS is less then Marshmallow
pickGallery();
}
}
});
//Camera button click listener to pick image from gallery
mCameraBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
//System OS is Marshmallow or above
if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED ||
checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED){
//permission not granted, request it.
String[] permissions = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
//show popup for runtime permission
requestPermissions(permissions, PERMISSION_CAMERA_CODE);
}
else {
//permission already granted
pickCamera();
}
}
else {
//System OS is less than Marshmallow
pickCamera();
}
}
});
}
public void pickCamera(){
//take image from default camera
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "New Picture");
values.put(MediaStore.Images.Media.DESCRIPTION, "From Camera");
image_uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri);
startActivityForResult(cameraIntent, IMAGE_PICK_CAMERA_CODE);
}
public void pickGallery(){
//pick image from gallery
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, IMAGE_PICK_GALLERY_CODE);
}
//handle result of runtime permission
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode){
case PERMISSION_WRITE_STORAGE_CODE:{
if (grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
//permission was granted
Toast.makeText(this, "Gallery Granted", Toast.LENGTH_SHORT).show();
pickGallery();
}
else {
//permission was denied
Toast.makeText(this, "Permission denied...!", Toast.LENGTH_SHORT).show();
}
}
case PERMISSION_CAMERA_CODE:{
if (grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
//permission was granted
Toast.makeText(this, "Camera Granted", Toast.LENGTH_SHORT).show();
pickCamera();
}
else {
//permission was denied
Toast.makeText(this, "Permission denied...!", Toast.LENGTH_SHORT).show();
}
}
}
}
//handle result of picked image
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK){
if (requestCode == IMAGE_PICK_GALLERY_CODE){
//set image to image view
mImageView.setImageURI(data.getData());
}
if (requestCode == IMAGE_PICK_CAMERA_CODE){
//set image to image view
mImageView.setImageURI(image_uri);
}
}
}
}
Here is logcat report:
FATAL EXCEPTION: main
Process: com.blogspot.atifsoftwares.myapplication, PID: 24672
java.lang.RuntimeException: Failure delivering result ResultInfo{who=#android:requestPermissions:, request=1002, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }} to activity {com.blogspot.atifsoftwares.myapplication/com.blogspot.atifsoftwares.myapplication.MainActivity}: java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE flg=0x3 cmp=com.oppo.camera/.Camera clip={text/uri-list U:content://media/external/images/media/58337} (has extras) } from ProcessRecord{f4a4aee 24672:com.blogspot.atifsoftwares.myapplication/u0a427} (pid=24672, uid=10427) with revoked permission android.permission.CAMERA
at android.app.ActivityThread.deliverResults(ActivityThread.java:4339)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4382)
at android.app.ActivityThread.-wrap20(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1679)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:186)
at android.app.ActivityThread.main(ActivityThread.java:6509)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:914)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:804)
Caused by: java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE flg=0x3 cmp=com.oppo.camera/.Camera clip={text/uri-list U:content://media/external/images/media/58337} (has extras) } from ProcessRecord{f4a4aee 24672:com.blogspot.atifsoftwares.myapplication/u0a427} (pid=24672, uid=10427) with revoked permission android.permission.CAMERA
at android.os.Parcel.readException(Parcel.java:1702)
at android.os.Parcel.readException(Parcel.java:1655)
at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:3229)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1520)
at android.app.Activity.startActivityForResult(Activity.java:4434)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:767)
at android.app.Activity.startActivityForResult(Activity.java:4369)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:754)
at com.blogspot.atifsoftwares.myapplication.MainActivity.pickCamera(MainActivity.java:98)
at com.blogspot.atifsoftwares.myapplication.MainActivity.onRequestPermissionsResult(MainActivity.java:128)
at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:7404)
at android.app.Activity.dispatchActivityResult(Activity.java:7256)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4335)
Your app is crashed when we click on camera button and it asks for camera permission and storage permissions. And we allow camera permission but deny the storage permission. The reason for crash is this: We allowed camera permission to capture image but we also have to give permission to store that image as well. Otherwise it crashes..
I tried to rewrite code to take permissions effectively. Try this code and tell me if it works.
MainActivity.java
public class MainActivity extends AppCompatActivity {
public static final int CAMERA_REQUEST_CODE = 200;
public static final int STORAGE_REQUEST_CODE = 400;
private static final int IMAGE_PICK_GALLERY_CODE = 1000;
private static final int IMAGE_PICK_CAMERA_CODE = 1001;
Uri image_uri;
ImageView mImageView;
Button mGalleryBtn, mCameraBtn;
String cameraPermission[];
String storagePermission[];
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = findViewById(R.id.imageIv);
mGalleryBtn = findViewById(R.id.galleryBtn);
mCameraBtn = findViewById(R.id.cameraBtn);
cameraPermission = new String [] {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
storagePermission = new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE};
//Gallery button click listener to pick image from gallery
mGalleryBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!checkStoragePermission()) {
requestStoragePermission();
} else {
pickGallery();
}
}
});
//Camera button click listener to pick image from gallery
mCameraBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!checkCameraPermission()) {
requestCameraPermission();
} else {
pickCamera();
}
}
});
}
public void pickCamera() {
//take image from default camera
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "New Picture");
values.put(MediaStore.Images.Media.DESCRIPTION, "From Camera");
image_uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri);
startActivityForResult(cameraIntent, IMAGE_PICK_CAMERA_CODE);
}
public void pickGallery() {
//pick image from gallery
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, IMAGE_PICK_GALLERY_CODE);
}
public boolean checkStoragePermission() {
boolean result = ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == (PackageManager.PERMISSION_GRANTED);
return result;
}
public void requestStoragePermission() {
ActivityCompat.requestPermissions(this, storagePermission, STORAGE_REQUEST_CODE);
}
public boolean checkCameraPermission() {
boolean result = ContextCompat.checkSelfPermission(this,
Manifest.permission.CAMERA) == (PackageManager.PERMISSION_GRANTED);
boolean result1 = ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == (PackageManager.PERMISSION_GRANTED);
return result && result1;
}
public void requestCameraPermission() {
ActivityCompat.requestPermissions(this,cameraPermission, CAMERA_REQUEST_CODE);
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case CAMERA_REQUEST_CODE:
if (grantResults.length > 0) {
boolean cameraAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
boolean writeStorageAccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED;
if (cameraAccepted && writeStorageAccepted) {
Toast.makeText(this, "Thank you", Toast.LENGTH_SHORT).show();
pickCamera();
}
else {
Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {
showMessageOkCancel("You need to allow storage permissions.",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(cameraPermission, CAMERA_REQUEST_CODE);
}
}
});
return;
}
}
}
}
break;
case STORAGE_REQUEST_CODE:
if (grantResults.length > 0) {
boolean writeStorageAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
if (writeStorageAccepted) {
Toast.makeText(this, "Thank you", Toast.LENGTH_SHORT).show();
pickGallery();
}
else {
Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
showMessageOkCancel("You need to allow storage permissions.",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(storagePermission, STORAGE_REQUEST_CODE);
}
}
});
return;
}
}
}
}
break;
}
}
private void showMessageOkCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(this).setMessage(message).setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", null).create().show();
}
//handle result of picked image
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == IMAGE_PICK_GALLERY_CODE) {
//set image to image view
mImageView.setImageURI(data.getData());
}
if (requestCode == IMAGE_PICK_CAMERA_CODE) {
//set image to image view
mImageView.setImageURI(image_uri);
}
}
}
}
Hopefully app should run this time!
Now whenever you click gallery button, app asks for Storage Permission and when click camera button, app will ask for both camera and storage permissions.
I am writing an app who download some images from a remote server. I try to save them in the gallery but I got a android.permission.WRITE_EXTERNAL_STORAGE required due to a Permission Denial.
I do not understand why because I set up the permission in the manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.seb.sebastien.reddit">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Any idea why the permission denial happens as I add the permission. For information, I do not have an Android Device, I use the emulator. SDK use is API 26.
Thanks
For Android Running on Android 6.0 (API level 23) and above , we need to add runtime permission to work, you can follow this link Storage permission error in Marshmallow
----Updated ----
Code reference
public boolean isStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Log.v(TAG,"Permission is granted");
return true;
} else {
Log.v(TAG,"Permission is revoked");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else { //permission is automatically granted on sdk<23 upon installation
Log.v(TAG,"Permission is granted");
return true;
}
}
Permission result callback:
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(grantResults[0]== PackageManager.PERMISSION_GRANTED){
Log.v(TAG,"Permission: "+permissions[0]+ "was "+grantResults[0]);
//resume tasks needing this permission
}
}
For TargetSDK 23 or higher, you need to give runtime permission As per Android's guideline. Check this link for code snippet and more description.
https://developer.android.com/training/permissions/requesting.html
Add this code for permission to allow run time operation in splash activity in onCreate or before download process of image.
if (!checkPermission()) {
openActivity();
} else {
if (checkPermission()) {
requestPermissionAndContinue();
} else {
openActivity();
}
}
Add this method outside onCreate.
private static final int PERMISSION_REQUEST_CODE = 200;
private boolean checkPermission() {
return ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
;
}
private void requestPermissionAndContinue() {
if (ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, WRITE_EXTERNAL_STORAGE)
&& ActivityCompat.shouldShowRequestPermissionRationale(this, READ_EXTERNAL_STORAGE)) {
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(this);
alertBuilder.setCancelable(true);
alertBuilder.setTitle(getString(R.string.permission_necessary));
alertBuilder.setMessage(R.string.storage_permission_is_encessary_to_wrote_event);
alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(SplashActivity.this, new String[]{WRITE_EXTERNAL_STORAGE
, READ_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}
});
AlertDialog alert = alertBuilder.create();
alert.show();
Log.e("", "permission denied, show dialog");
} else {
ActivityCompat.requestPermissions(SplashActivity.this, new String[]{WRITE_EXTERNAL_STORAGE,
READ_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}
} else {
openActivity();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == PERMISSION_REQUEST_CODE) {
if (permissions.length > 0 && grantResults.length > 0) {
boolean flag = true;
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
flag = false;
}
}
if (flag) {
openActivity();
} else {
finish();
}
} else {
finish();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
private void openActivity() {
//add your further process after giving permission or to download images from remote server.
}
happy Coding.
I want to play video in Video view, I have tried so many solutions but I am not able to access image file and video file as well.
It allows me to access image files when I run application for second time.
Click to see error,
Full Error Log
I already have run time permissions, but system won't allow me to access images and files.
Here is my code -
MainActivity
`
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.imageView);
videoView = (VideoView) findViewById(R.id.videoView);
String image = "/ImageVideos/1501064538061.jpg";
String video = "/ImageVideos/20170707155916_mmy037p0xZzcW.mp4";
MediaController mediaController = new MediaController(this);
String strFileDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
String strImgDir = strFileDir + image;
String strVideoDir = strFileDir + video;
File fileImg = new File(strImgDir);
File fileVideo = new File(strVideoDir);
if (Build.VERSION.SDK_INT >= 24) {
if (!checkPermission()) {
requestPermission();
}
Uri imgContentUri = FileProvider.getUriForFile(getApplicationContext(), BuildConfig.APPLICATION_ID + ".provider", fileImg);
Uri videoContentUri = FileProvider.getUriForFile(getApplicationContext(), BuildConfig.APPLICATION_ID + ".provider", fileVideo);
this.grantUriPermission(getPackageName(), imgContentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
this.grantUriPermission(getPackageName(), videoContentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
imageView.setImageURI(imgContentUri);
videoView.setVideoPath(String.valueOf(videoContentUri));
mediaController.setAnchorView(videoView);
videoView.setMediaController(mediaController);
videoView.start();
}
}
private void requestPermission() {
ActivityCompat.requestPermissions(this, new String[]{WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE}, PERMISSION_ALL);
}
private boolean checkPermission() {
int result = ContextCompat.checkSelfPermission(getApplicationContext(), WRITE_EXTERNAL_STORAGE);
int result1 = ContextCompat.checkSelfPermission(getApplicationContext(), READ_EXTERNAL_STORAGE);
return result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case PERMISSION_ALL:
if (grantResults.length > 0) {
boolean WriteExternalAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
boolean ReadExternalAccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED;
if (ReadExternalAccepted && WriteExternalAccepted) {
//Snackbar.make(view, "Permission Granted, Now you can access location data and camera.", Snackbar.LENGTH_LONG).show();
} else {
//Snackbar.make(view, "Permission Denied, You cannot access location data and camera.", Snackbar.LENGTH_LONG).show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (shouldShowRequestPermissionRationale(WRITE_EXTERNAL_STORAGE)) {
showMessageOKCancel("You need to allow access to both the permissions",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE},
PERMISSION_ALL);
}
}
});
return;
}
}
}
}
break;
}
}
`
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>
provider_paths.xml
<path xmlns:android="http://schemas.android.com/apk/res/android">
<root-path name="external_files" path="."/>
</path>
try this
step 1 :- add this permission in manifest file
android.Manifest.permission.READ_EXTERNAL_STORAGE,
step 2 : ask runtime permission
String permission = Manifest.permission.READ_EXTERNAL_STORAGE;
if (ActivityCompat.checkSelfPermission(SearchCityClass.this, permission)
!= PackageManager.PERMISSION_GRANTED ) {
ActivityCompat.requestPermissions(SearchCityClass.this, new String[]
{permission}, 1010);
}
step 3: handle permsiion result
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1010) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, location_permission_granted_msg, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, location_permission_not_granted_msg, Toast.LENGTH_SHORT).show();
}
}
}
I'm trying to select the image from gallery , but my application is getting exception of 'Something went wrong' message . I thought i set up the android WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE permission correctly, but i keep getting errors What should i do to have it working?
Here is my Log cat error
06-07 12:07:27.567 1692-1711/? E/DatabaseUtils﹕ Writing exception to parcel
java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/media/359 from pid=2818, uid=10057 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:605)
at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:480)
at android.content.ContentProvider$Transport.query(ContentProvider.java:211)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:112)
at android.os.Binder.execTransact(Binder.java:453)
Here is my Activity code
public class MainActivity extends Activity {
private static int RESULT_LOAD_IMG = 1;
String imgDecodableString;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void loadImagefromGallery(View view) {
// Create intent to Open Image applications like Gallery, Google Photos
Intent galleryIntent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
// Start the Intent
startActivityForResult(galleryIntent, RESULT_LOAD_IMG);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
// When an Image is picked
if (requestCode == RESULT_LOAD_IMG && resultCode == RESULT_OK
&& null != data) {
// Get the Image from data
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
// Get the cursor
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
// Move to first row
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
imgDecodableString = cursor.getString(columnIndex);
cursor.close();
ImageView imgView = (ImageView) findViewById(R.id.imgView);
// Set the Image in ImageView after decoding the String
imgView.setImageBitmap(BitmapFactory
.decodeFile(imgDecodableString));
} else {
Toast.makeText(this, "You haven't picked Image",
Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Toast.makeText(this, "Something went wrong", Toast.LENGTH_LONG)
.show();
}
}
}
Here is my Menifest.xml file code
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.tazeen.image_fromgallery" >
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
For checking manual permissions for API level 23 and above i use this code.
public static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 123;
public boolean checkPermissionREAD_EXTERNAL_STORAGE(
final Context context) {
int currentAPIVersion = Build.VERSION.SDK_INT;
if (currentAPIVersion >= android.os.Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(context,
Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(
(Activity) context,
Manifest.permission.READ_EXTERNAL_STORAGE)) {
showDialog("External storage", context,
Manifest.permission.READ_EXTERNAL_STORAGE);
} else {
ActivityCompat
.requestPermissions(
(Activity) context,
new String[] { Manifest.permission.READ_EXTERNAL_STORAGE },
MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
}
return false;
} else {
return true;
}
} else {
return true;
}
}
showDialog()
public void showDialog(final String msg, final Context context,
final String permission) {
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
alertBuilder.setCancelable(true);
alertBuilder.setTitle("Permission necessary");
alertBuilder.setMessage(msg + " permission is necessary");
alertBuilder.setPositiveButton(android.R.string.yes,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions((Activity) context,
new String[] { permission },
MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
}
});
AlertDialog alert = alertBuilder.create();
alert.show();
}
in your activity check like this.
if (checkPermissionREAD_EXTERNAL_STORAGE(this)) {
// do your stuff..
}
And don't forget to add onRequestPermissionsResult.
#Override
public void onRequestPermissionsResult(int requestCode,
String[] permissions, int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// do your stuff
} else {
Toast.makeText(Login.this, "GET_ACCOUNTS Denied",
Toast.LENGTH_SHORT).show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions,
grantResults);
}
}
Happy Coding..
You have two solutions for your problem. The quick one is to lower targetApi to 22 (build.gradle file). Second is to use the new runtimePermission model: Since your target api is 23 you should add the permissions on runtime too.
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.READ_EXTERNAL_STORAGE) {
// Should we show an explanation?
if (shouldShowRequestPermissionRationale(
Manifest.permission.READ_EXTERNAL_STORAGE)) {
// Explain to the user why we need to read the contacts
}
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
// MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an
// app-defined int constant
return;
}
Sniplet found here: https://developer.android.com/training/permissions/requesting.html
You need to set permissions explicitly to all packages match your intent.
you can use this utility to do that :
List<ResolveInfo> resInfoList = getContext().getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
getContext().grantUriPermission(packageName, imageFileUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
There is an easy way, set an action to your "galleryIntent" so the OS will not panick (I test this on Andorid Emulator API 23 and it works):
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
Also, don't forget to set a type too:
galleryIntent.setType("image/*");
Change:
Intent galleryIntent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
To:Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
=> done !
I added the permission on the manifest.xml
But I still having the same error:
Permission Denial: reading com.android.providers.media.MediaProvider
Help me please.
My java class
package com.example.maymaa.mytest;
+import..
public class Image extends AppCompatActivity {
private static final int PICK_IMAGE =100;
Uri imageUri;
ImageView imageview1;
Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image);
imageview1=(ImageView)findViewById(R.id.imageview1);
button=(Button)findViewById(R.id.btphoto);
assert button != null;
button.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
openGallery();
}}
);}
private void openGallery()
{
Intent gallery= new Intent
(Intent.ACTION_PICK,MediaStore.Images.Media.INTERNAL_CONTENT_URI);
startActivityForResult(gallery, PICK_IMAGE);
}
#Override
protected void onActivityResult
(int requestcode,int resultcode,Inten data)
{
super.onActivityResult(requestcode,resultcode,data);
if(resultcode == RESULT_OK && requestcode==PICK_IMAGE){
imageUri =data.getData();
imageview1.setImageURI(imageUri);
}
}
}
My activity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:padding="10dp"
android:weightSum="1">
<ImageView
android:layout_width="361dp"
android:layout_height="255dp"
android:id="#+id/imageview1"
android:layout_weight="0.14" />
<Button
android:layout_width="180dp"
android:layout_height="wrap_content"
android:text="Choisir"
android:layout_gravity="center_horizontal"
android:onClick="btnclick"
android:id="#+id/btphoto"
/>
</LinearLayout>
My code is not working
Thank you
Try this, Put this code in onCreate right after setContentView and put the remaining code of onCreate in else part:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int hasWritePermission = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
int hasReadPermission = checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE);
List<String> permissions = new ArrayList<String>();
if (hasWritePermission != PackageManager.PERMISSION_GRANTED) {
permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
} else {
preferencesUtility.setString("storage", "true");
}
if (hasReadPermission != PackageManager.PERMISSION_GRANTED) {
permissions.add(Manifest.permission.READ_EXTERNAL_STORAGE);
} else {
preferencesUtility.setString("storage", "true");
}
if (!permissions.isEmpty()) {
requestPermissions(permissions.toArray(new String[permissions.size()]), REQUEST_CODE_SOME_FEATURES_PERMISSIONS);
}
}
out side onCreate write :
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_SOME_FEATURES_PERMISSIONS: {
for (int i = 0; i < permissions.length; i++) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
System.out.println("Permissions --> " + "Permission Granted: " + permissions[i]);
} else if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
System.out.println("Permissions --> " + "Permission Denied: " + permissions[i]);
}
}
}
break;
default: {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
Add external read/write permission in Manifest file
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
I also had same issue ,
Have provided permissions as below in manifext.xml
**<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>**
Thanks
Krish