I want to open camera when clicking an item on my dialog box, but I get an error like below. I've been adding a camera permission to manifest.xml.
java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE cmp=com.sonyericsson.android.camera/.MultiWindowActivity } from ProcessRecord{b42fcde 29884:ukmutilizer.project.com.ukm_utilizer/u0a273} (pid=29884, uid=10273) with revoked permission android.permission.CAMERA
this is my function
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.personal_data_step, container, false);
ButterKnife.bind(this, view);
imageEktp.setClickable(true);
imageEktp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Log.d("test : ", "testing");
CharSequence menu[] = new CharSequence[]{"Take From Galery", "Open Camera"};
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("Pick a Picture");
builder.setItems(menu, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
if(i == 0){
Toast.makeText(getActivity(), "galery", Toast.LENGTH_SHORT).show();
}else{
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivity(intent);
}
}
});
builder.show();
}
});
return view;
}
Ensure you request Runtime Camera Permission from the user.
private static final int CAMERA_REQUEST_CODE = 100;
Request permission if not granted.
if (checkSelfPermission(Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.CAMERA},
CAMERA_REQUEST_CODE);
}
Do stuff inside onRequestPermissionsResult.
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == CAMERA_REQUEST_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Camera permission granted.", Toast.LENGTH_LONG).show();
// Do stuff here for Action Image Capture.
} else {
Toast.makeText(this, "Camera permission denied.", Toast.LENGTH_LONG).show();
}
}
}
Also this should be declared inside Manifest as well.
You have to get runtime permission then only access your camera
like
in manifest
<uses-permission android:name="android.permission.CAMERA" />
in Java
private static final int MY_CAMERA_REQUEST_CODE = 100;
private void processPickImage() {
if(hasCameraPermission()) {
pickImage();
}
else
{
requestCameraPermission();
}
}
private boolean hasCameraPermission() {
return ContextCompat.checkSelfPermission(context,
Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
}
#TargetApi(Build.VERSION_CODES.M)
private void requestCameraPermission() {
requestPermissions(new String[]{Manifest.permission.CAMERA},
MY_CAMERA_REQUEST_CODE );
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
switch (requestCode) {
case MY_CAMERA_REQUEST_CODE :
processPickImage();
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
The user has to confirm the permission request.
Try
public class ActivityMain extends AppCompatActivity
{
public static final int MY_PERMISSIONS_REQUEST = 0;
#Override
protected void onCreate(Bundle savedInstanceState)
{
if (ContextCompat.checkSelfPermission(ActivityMain.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
{ ActivityCompat.requestPermissions(ActivityMain.this, new String[]{Manifest.permission.CAMERA}, MY_PERMISSIONS_REQUEST);
}
[...]
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults)
{ switch (requestCode)
{ case MY_PERMISSIONS_REQUEST:
[...]
}
}
}
when you run your app in 6.0 above like marshmallow device then need permission other wise no need to permission.
that time your code work..
if run marshmallow device that time need permission then make below code ..
private void alertDialog(){
CharSequence menu[] = new CharSequence[]{"Take From Galery", "Open Camera"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Pick a Picture");
builder.setItems(menu, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
if(i == 0){
Toast.makeText(getApplicationContext(), "galery", Toast.LENGTH_SHORT).show();
}else{
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivity(intent);
}
}
});
builder.show();
}
then above method put in permission code like below ..
if (ContextCompat.checkSelfPermission(webView.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(webView.this, Manifest.permission.CAMERA)) {
alertDialog();
}
else{
ActivityCompat.requestPermissions(webView.this, new String[] { Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE }, 0);
}
}
add two permission into manifest file ..
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
your error main problem is permission if you add this below line is work.
if (ContextCompat.checkSelfPermission(webView.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(webView.this, Manifest.permission.CAMERA)) {
alertDialog();
}
else{
ActivityCompat.requestPermissions(webView.this, new String[] { Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE }, 0);
}
}
Related
if you have Problem with file permissions, following solution worked for me on API 27, 29 and 30. I haven't tried for API version 28 but I assume it would also work for 28 because the file access rights are changed from API version 29.
AndroidManifest.xml,
<manifest
...
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="29"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="29"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
...
<application
...
android:requestLegacyExternalStorage="true"
>
...
</application>
</manifest>
main.java,
private static final int PERMISSIONS_REQUEST_CODE = 1240;
private ArrayList<String> appPermissions;
private ActivityResultLauncher<Intent> permissionLauncher;
private void checkPermissionsGranted() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if ( !Environment.isExternalStorageManager() ) {
requestPermission();
} else {
// app has permissions, init app
initApp();
}
} else {
// older API-Versions
checkAndRequestPermissions();
}
}
private void requestPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
permissionLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(), result -> {
if (result.getResultCode() == Activity.RESULT_OK) {
// app has permissions, init app
initApp();
} else {
//permission is denied
finish();
}
});
try {
Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(Uri.parse(String.format("package:%s", getApplicationContext().getPackageName())));
// startActivityForResult(intent, AppConstants.STORAGE_PERMISSION_CODE);
permissionLauncher.launch(intent);
} catch (Exception e) {
Log.e(TAG, "Exp... " + e.toString());
Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
permissionLauncher.launch(intent);
}
}
}
public void checkAndRequestPermissions(){
// check which permissions are granted
List<String> listPermissionsNeeded = new ArrayList<>();
for (String perm:appPermissions){
if (ContextCompat.checkSelfPermission(this, perm) != PackageManager.PERMISSION_GRANTED){
listPermissionsNeeded.add(perm);
}
}
// ask for non-granted
if (!listPermissionsNeeded.isEmpty()){
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), PERMISSIONS_REQUEST_CODE);
} else {
// app has all permissions, init app
initApp();
}
}
private void initApp() {
/**
* TODO
* */
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSIONS_REQUEST_CODE) {
HashMap<String, Integer> permissionResults = new HashMap<>();
int deniedCount = 0;
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
permissionResults.put(permissions[i], grantResults[i]);
deniedCount++;
}
}
if (deniedCount == 0) {
// app has all permissions, init app
initApp();
} else {
// denied
for (Map.Entry<String, Integer> entry : permissionResults.entrySet()) {
String permName = entry.getKey();
int permResult = entry.getValue();
// permission is denied (this is first time, when "newer ask again" is not checked)
if (ActivityCompat.shouldShowRequestPermissionRationale(this, permName)) {
// show dialog
new MaterialAlertDialogBuilder(MainActivity.this)
.setTitle("Title")
.setMessage(getString(R.string.confirmation_permissions))
.setPositiveButton(getString(R.string.confirm_permissions_ok), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
checkAndRequestPermissions();
}
})
.setNegativeButton(getString(R.string.confirm_permissions_cancel), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
// finish App
finish();
}
})
.show();
} else {
//permission is denied ("newer ask again" is checked)
finish();
}
}
}
}
}
This issue happens when I deliberately don't do anything when the permission request screen pops up, the app will just crash after a few seconds.
The permission requests pop up after transitioned from another activity (LoginActivity) to MapsActivity.
LoginActivity
if statement to check the validity
if valid
Intent intent = new Intent(LoginActivity.this,MapActivity.class);
startActivity(intent);
finish();
MapActivity
...
public void onMapReady(GoogleMap map) {
mMap = map;
getLocationPermission();
updateLocationUI();
getDeviceLocation();
}
private void getLocationPermission() {
if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
} else {
ActivityCompat.requestPermissions(this,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
}
}
Just realised how to solve this with a simpled solution lmao...
In my original code, I have onRequestPermissionResult() already btw.
MapActivity
private boolean mLocationPermissionGranted;
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String permissions[], #NonNull int[] grantResults) {
mLocationPermissionGranted = false;
switch (requestCode) {
case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
}
}
}
updateLocationUI();
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
...
getLocationPermission();
if(mLocationPermissionGranted){
updateLocationUI();
getDeviceLocation();
}
}
No more crashing now :)
i am checking the permission this way and this is working properly try this :-
if (checkLocationPermission()) {
Log.e("Tag", "Camera and External storage Permission's are allowed");
} else {
requestLocationPermission();
}
this is the method checkLocationPermission:-
private boolean checkLocationPermission() {
int result = ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION);
if (result == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
this is request method for location:-
private void requestLocationPermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale
(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this, R.style.DialogTheme);
alertDialog.setMessage("You Have To Give Permission From Your Device Setting To go in Setting Please Click on Settings Button");
alertDialog.setCancelable(false);
alertDialog.setPositiveButton("Go To Settings", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}
});
alertDialog.show();
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1012);
}
}
and finally onRequestPermissionsResult:-
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this, R.style.DialogTheme);
alertDialog.setMessage("You Have To Give Permission From Your Device Setting To go in Setting Please Click on Settings Button");
alertDialog.setCancelable(false);
alertDialog.setPositiveButton("Go To Settings", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}
});
alertDialog.show();
}else{
// do your stuff in case accept permission
}
}
I'm trying to download file via Download Manager in Instant app:
Uri uri = Uri.parse("https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260");
DownloadManager downloadManager = (DownloadManager) context.getSystemService(DOWNLOAD_SERVICE);
downloadManager.enqueue(new DownloadManager.Request(uri)
.setTitle("Demo")
.setDescription("Something useful. No, really.")
.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,
"test.mp4"));
But getting an exception:
java.lang.IllegalStateException: Unable to create directory: /storage/emulated/0/Download
at android.app.DownloadManager$Request.setDestinationInExternalPublicDir(DownloadManager.java:539)
Is there other way to download files in Instant apps?
Issue seems it be related with Android Runtime Permission introduced in Android 6.0
When your app targeting API Level 23, by default all the permission is false you have to request permission dialog and approve the permission before using that into your app.
Ask the permission
public class RequestPermissionHandler {
private Activity mActivity;
private RequestPermissionListener mRequestPermissionListener;
private int mRequestCode;
public void requestPermission(Activity activity, #NonNull String[] permissions, int requestCode,
RequestPermissionListener listener) {
mActivity = activity;
mRequestCode = requestCode;
mRequestPermissionListener = listener;
if (!needRequestRuntimePermissions()) {
mRequestPermissionListener.onSuccess();
return;
}
requestUnGrantedPermissions(permissions, requestCode);
}
private boolean needRequestRuntimePermissions() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
}
private void requestUnGrantedPermissions(String[] permissions, int requestCode) {
String[] unGrantedPermissions = findUnGrantedPermissions(permissions);
if (unGrantedPermissions.length == 0) {
mRequestPermissionListener.onSuccess();
return;
}
ActivityCompat.requestPermissions(mActivity, unGrantedPermissions, requestCode);
}
private boolean isPermissionGranted(String permission) {
return ActivityCompat.checkSelfPermission(mActivity, permission)
== PackageManager.PERMISSION_GRANTED;
}
private String[] findUnGrantedPermissions(String[] permissions) {
List<String> unGrantedPermissionList = new ArrayList<>();
for (String permission : permissions) {
if (!isPermissionGranted(permission)) {
unGrantedPermissionList.add(permission);
}
}
return unGrantedPermissionList.toArray(new String[0]);
}
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
if (requestCode == mRequestCode) {
if (grantResults.length > 0) {
for (int grantResult : grantResults) {
if (grantResult != PackageManager.PERMISSION_GRANTED) {
mRequestPermissionListener.onFailed();
return;
}
}
mRequestPermissionListener.onSuccess();
} else {
mRequestPermissionListener.onFailed();
}
}
}
public interface RequestPermissionListener {
void onSuccess();
void onFailed();
}
Use in Activity like this:
public class MainActivity extends AppCompatActivity {
private RequestPermissionHandler mRequestPermissionHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRequestPermissionHandler = new RequestPermissionHandler();
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
handleButtonClicked();
}
});
}
private void handleButtonClicked(){
mRequestPermissionHandler.requestPermission(this, new String[] {
Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_EXTERNAL_STORAGE
}, 123, new RequestPermissionHandler.RequestPermissionListener() {
#Override
public void onSuccess() {
Toast.makeText(MainActivity.this, "request permission success", Toast.LENGTH_SHORT).show();
}
#Override
public void onFailed() {
Toast.makeText(MainActivity.this, "request permission failed", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
mRequestPermissionHandler.onRequestPermissionsResult(requestCode, permissions,
grantResults);
}
}
and don't forget to add this in your manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
this is my code for get permissions...but still its stop when user perform permission action(target api is 25). any other way?
boolean isMdevice;
boolean pstatus;
int code=1;
String[] perms = { android.Manifest.permission.RECEIVE_SMS, Manifest.permission.CALL_PHONE, Manifest.permission.SEND_SMS};
/////then in oncreate
isMdevice=isMarshmallowPlusDevice();
pstatus= isPermissionRequestRequired(MainActivity.this, perms, code);
////then methods
public static boolean isMarshmallowPlusDevice() {
return Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1;
}
#TargetApi(Build.VERSION_CODES.M)
public static boolean isPermissionRequestRequired(Activity activity, #NonNull String[] permissions, int requestCode) {
if (isMarshmallowPlusDevice() && permissions.length > 0) {
List<String> newPermissionList = new ArrayList<>();
for (String permission : permissions) {
if (PERMISSION_GRANTED != activity.checkSelfPermission(permission)) {
newPermissionList.add(permission);
}
}
if (newPermissionList.size() > 0) {
activity.requestPermissions(newPermissionList.toArray(new String[newPermissionList.size()]), requestCode);
return true;
}
}
return false;
}
try this code for Check permission and ask for runtime permission:
Add this class to your project
public class PermissionUtils {
public static boolean checkPermission(Context context, String permission) {
return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
}
public static void requestPermissions(Activity activity, String messageInCaseOfCustomDialog, int permissionId, String... permissions) {
/* if (o instanceof Fragment) {
FragmentCompat.requestPermissions((Fragment) o, permissions, permissionId);
} else */
if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
permissions[0])) {
showCustomDialogForAskPermission(activity, messageInCaseOfCustomDialog, permissionId, permissions);
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else if (/*MySharedPreference.getSharedPrefrence(activity).getBoolean(permissions[0], false)*/) { //Use your Shared Preference
// No explanation needed, we can request the permission.
showCustomDialogForGoToTheSettings(activity, messageInCaseOfCustomDialog);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
} else {
ActivityCompat.requestPermissions(activity, permissions, permissionId);
}
/*MySharedPreference.getSharedPrefrence(activity).edit().putBoolean(permissions[0], true).commit();*/ //Use your Shared Preference
}
private static void showCustomDialogForGoToTheSettings(final Activity activity, String message) {
AlertDialog.Builder dialog = new AlertDialog.Builder(activity);
dialog.setTitle("Permission Required");
dialog.setMessage(message);
dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
intent.setData(uri);
activity.startActivity(intent);
}
});
dialog.show();
}
private static void showCustomDialogForAskPermission(final Activity activity, String message, final int permissionId, final String... permissions) {
AlertDialog.Builder dialog = new AlertDialog.Builder(activity);
dialog.setTitle("Permission Required");
dialog.setMessage(message);
dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(activity, permissions, permissionId);
}
});
dialog.show();
}
}
Now you can directly check if you have that permission or not,Suppose you want to check for READ_EXTERNAL_STORAGE permission
if (PermissionUtils.checkPermission(RegisterScreenActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
//Do your work
} else {PermissionUtils.requestPermissions(RegisterScreenActivity.this, "You need to provide storage permission for this service", 101, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE});//ask for permission
}
You can also track its result in onRequestPermissionsResult() methods like
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 101:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//permission granted, can do your work
} else {
//permission not granted
}
break;
}
}
I am trying to take an image from Gallery and set it to an imageview but in Android 6 there are some permission problems. Below is the method to ask for the permission. Should I ask for read external storage or write external storage?
Here is what I have done so far:
private static final int READ_CONTACTS_PERMISSIONS_REQUEST = 1;
public void getPermissionToReadExternalStorage() {
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
if (shouldShowRequestPermissionRationale(
Manifest.permission.READ_EXTERNAL_STORAGE)) {
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
READ_CONTACTS_PERMISSIONS_REQUEST);
}}}
#Override
public void onRequestPermissionsResult(int requestCode,
#NonNull String permissions[],
#NonNull int[] grantResults){
// Make sure it's our original READ_CONTACTS request
if (requestCode == READ_CONTACTS_PERMISSIONS_REQUEST) {
if (grantResults.length == 1 &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getActivity(), "Read Contacts permission granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getActivity(), "Read Contacts permission denied", Toast.LENGTH_SHORT).show();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
Now my on click listener to pick data from the Gallery:
pro.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
if (android.os.Build.VERSION.SDK_INT >= 23) {
getPermissionToReadExternalStorage();
if (getPermissionToReadExternalStorage () this???? <==)
startActivityForResult(Intent.createChooser(intent, "Select Picture"), 0);
} else {
startActivityForResult(Intent.createChooser(intent, "Select Picture"), 0);
}}
});
return v;
}
Now I want to get result of the method getPermissionToReadExternalStorage() so I can start the Activity for picking gallery for Android 6. How can I get the result of the void class?
And another thing is do I have to write method for every permission my app asks for?
So I have completely rewritten the code to request permissions.
Now it supports requesting for multiple permissions and running code with proper result.
Also it works with preMarshmallow devices, so you don't have to check and copy the code in that case.
First, create an Activity class with this code (You can extend any king of activity you need, e.g. AppCompatActivity):
public abstract class PermissionActivity extends AppCompatActivity {
private final ArrayList<PermissionListener> permissionListeners = new ArrayList<>();
#SuppressWarnings("unused")
public void requestPermissions(int requestCode, String[] requestPermissions, PermissionListener permissionListener) {
requestPermissions(requestCode, requestPermissions, null, permissionListener);
}
#SuppressWarnings("unused")
public void requestPermissions(final int requestCode, String[] requestPermissions, String message, final PermissionListener permissionListener) {
final int[] grantResults = new int[requestPermissions.length];
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ArrayList<String> list_notGranted = new ArrayList<>();
for (String requestPermission : requestPermissions)
if (ContextCompat.checkSelfPermission(this, requestPermission) != PackageManager.PERMISSION_GRANTED)
list_notGranted.add(requestPermission);
if (list_notGranted.size() > 0) {
permissionListeners.add(permissionListener);
requestPermissions = list_notGranted.toArray(new String[list_notGranted.size()]);
if (message != null) {
boolean shouldShowRequestPermissionRationale = false;
for (String permission : requestPermissions)
if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {
shouldShowRequestPermissionRationale = true;
break;
}
if (shouldShowRequestPermissionRationale) {
final String[] f_requestPermissions = requestPermissions;
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(message);
DialogInterface.OnClickListener onClickListener = new DialogInterface.OnClickListener() {
#TargetApi(Build.VERSION_CODES.M)
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
PermissionActivity.super.requestPermissions(f_requestPermissions, requestCode);
break;
default:
for (int i = 0; i < grantResults.length; i++)
grantResults[i] = PackageManager.PERMISSION_DENIED;
if (permissionListener != null)
permissionListener.onResult(requestCode, f_requestPermissions, grantResults);
break;
}
}
};
builder.setPositiveButton("OK", onClickListener);
builder.setNegativeButton("Cancel", onClickListener);
builder.show();
} else {
super.requestPermissions(requestPermissions, requestCode);
}
} else {
super.requestPermissions(requestPermissions, requestCode);
}
} else {
for (int i = 0; i < grantResults.length; i++)
grantResults[i] = PackageManager.PERMISSION_GRANTED;
if (permissionListener != null)
permissionListener.onResult(requestCode, requestPermissions, grantResults);
}
} else {
if (permissionListener != null) {
for (int i = 0; i < grantResults.length; i++)
grantResults[i] = PackageManager.PERMISSION_GRANTED;
permissionListener.onResult(requestCode, requestPermissions, grantResults);
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String permissions[], #NonNull int[] grantResults) {
for (Iterator<PermissionListener> it = permissionListeners.iterator(); it.hasNext(); ) {
PermissionListener permissionListener = it.next();
if (permissionListener.onResult(requestCode, permissions, grantResults)) {
it.remove();
}
}
}
public interface PermissionListener {
boolean onResult(int requestCode, String[] requestPermissions, int[] grantResults);
}
}
If you want to request permissions from Fragments, add this class:
public class PermissionFragment extends Fragment {
#SuppressWarnings("unused")
public void requestPermissions(int requestCode, String[] requestPermissions, PermissionActivity.PermissionListener permissionListener) {
requestPermissions(requestCode, requestPermissions, null, permissionListener);
}
#SuppressWarnings("unused")
public void requestPermissions(final int requestCode, String[] requestPermissions, String message, PermissionActivity.PermissionListener permissionListener) {
((PermissionActivity) getActivity()).requestPermissions(requestCode, requestPermissions, message, permissionListener);
}
}
Your Activities and Fragments should extend these classes instead of the standart ones.
Now you are ready to request the permissions by calling a method:
requestPermissions(int requestCode, String[] requestPermissions, PermissionListener permissionListener)
If the permission is required for the app to work, you should call this method and specify the message saying why the permission is required.
requestPermissions(int requestCode, String[] requestPermissions, String message, PermissionListener permissionListener)
DONT MISSCALL THE DEFAULT METHOD, WHICH IS
// DON'T USE THIS ONE!
requestPermissions(String[] requestPermissions, int requestCode)
// DON'T USE THIS ONE!
Here is the example of requesting contacts:
private void requestAndLoadContacts() {
String[] permissions = new String[]{Manifest.permission.READ_CONTACTS};
requestPermissions(REQUEST_PERMISSIONS_CONTACTS, permissions, "Read contacts permission is required for the app to work!", new PermissionListener() {
#Override
public boolean onResult(int requestCode, String[] requestPermissions, int[] grantResults) {
// Check if the requestCode is ours
if (requestCode == REQUEST_PERMISSIONS_CONTACTS) {
// Check if the permission is correct and is granted
if (requestPermissions[0].equals(Manifest.permission.READ_CONTACTS) && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted
// Calling a method to actually load the contacts
loadContacts();
} else {
// Permission not granted
Toast.makeText(MainActivity.this, "Access denied!", Toast.LENGTH_SHORT).show();
}
return true;
}
return false;
}
});
}
NOTE:
When you implement the PermissionListener, don't forget to return true when the requestCode is the correct one, otherwise the PermissionListener won't be removed from the ArrayList and you'll most likely get a small memory leak.
EDIT
I have rewritted the code and posted in another answer.
Old answer:
Yes, you have to check and ask for permission every time.
Usually I write the code like this:
private int requestPermissionCode;
private Runnable requestPermissionRunnable;
private void runPermissionCode(String requestPermission, int requestCode, Runnable codeToRun) {
if (android.os.Build.VERSION.SDK_INT >= 23) {
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissionCode = requestCode;
requestPermissionRunnable = codeToRun;
requestPermissions(new String[]{requestPermission},
requestCode);
}
} else {
codeToRun.run();
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
#NonNull String permissions[],
#NonNull int[] grantResults) {
if (requestCode == requestPermissionCode) {
if (grantResults.length == 1 &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (requestPermissionRunnable != null)
requestPermissionRunnable.run();
} else {
Toast.makeText(getActivity(), "Permission denied", Toast.LENGTH_SHORT).show();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
and run it like this:
runPermissionCode(Manifest.permission.READ_EXTERNAL_STORAGE, READ_CONTACTS_PERMISSIONS_REQUEST, new Runnable() {
#Override
public void run() {
// your code here
}
});
I am sure it is not a best way, but at least it gives a possibility to request permission and make actions easier.
Initialize Your Permission
private static final int INITIAL_REQUEST = 1337;
private static final int GET_ACCOUNTS = INITIAL_REQUEST+2;
private static final int LOCATION_REQUEST =INITIAL_REQUEST+3;
private static final String[] INITIAL_PERMS = {
Manifest.permission.GET_ACCOUNTS,
Manifest.permission.INTERNET,
Manifest.permission.ACCESS_FINE_LOCATION
};
Check for device and Request for permissions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!canAccessAccounts()|| !canAccessLocation() ||!canAccessInternet()) {
requestPermissions(INITIAL_PERMS, INITIAL_REQUEST);
}
}
Check Permission is granted Or not
private boolean canAccessAccounts() {
return (hasPermission(Manifest.permission.GET_ACCOUNTS));
}
private boolean canAccessLocation() {
return (hasPermission(Manifest.permission.ACCESS_FINE_LOCATION));
}
private boolean canAccessInternet() {
return (hasPermission(Manifest.permission.INTERNET));
}
private boolean hasPermission(String perm) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return (PackageManager.PERMISSION_GRANTED == checkSelfPermission(perm));
}
return (true);
}
Update Permissions and Check method for permissions onRequestPermissionsResult
void UpdatePermissions(){
canAccessInternet();
canAccessLocation();
canAccessInternet();
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
UpdatePermissions();
switch(requestCode) {
case GET_ACCOUNTS:
if (canAccessAccounts()) {
}
else {
}
break;
case LOCATION_REQUEST:
if (canAccessLocation()) {
}
else {
}
break;
case INITIAL_REQUEST:
if(canAccessInternet()){
}else {
}
break;
}
}