onRequestPermissionsResult is not called back in an android activity - android

I am trying to get the camera permission from the user before launching my camera activity. onRequestPermissionsResult is never called back after the user presses "Allow" from the permission dialog. Here is my Activity class:
public class ImageCaptureActivity extends AppCompatActivity {
public static final String TAG = ImageCaptureActivity.class.getSimpleName();
private static final int REQUEST_CAMERA = 0;
private static final int REQUEST_CAMERA_PERMISSION = 1;
private Point mSize;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_capture);
Display display = getWindowManager().getDefaultDisplay();
mSize = new Point();
display.getSize(mSize);
// Request for Camera Permission
requestForCameraPermission(findViewById(android.R.id.content));
}
/**
* #param view
* #brief requestForCameraPermission
*/
public void requestForCameraPermission(View view) {
Log.v(TAG, "Requesting Camera Permission");
final String permission = Manifest.permission.CAMERA;
if (ContextCompat.checkSelfPermission(ImageCaptureActivity.this, permission)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(ImageCaptureActivity.this, permission)) {
showPermissionRationaleDialog(getString(R.string.camera_permission_rationale), permission);
} else {
requestForPermission(permission);
}
} else {
launch();
}
}
/**
* #param message
* #param permission
* #brief showPermissionRationaleDialog
*/
private void showPermissionRationaleDialog(final String message, final String permission) {
new AlertDialog.Builder(ImageCaptureActivity.this)
.setMessage(message)
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ImageCaptureActivity.this.requestForPermission(permission);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
})
.create()
.show();
}
/**
* #param permission
* #brief requestForPermission
*/
private void requestForPermission(final String permission) {
ActivityCompat.requestPermissions(ImageCaptureActivity.this, new String[]{permission}, REQUEST_CAMERA_PERMISSION);
}
/**
* #brief launch
*/
private void launch() {
Log.v(TAG, "Camera Permission Granted, launching the CameraActivity");
String documentId = getIntent().getStringExtra(IntentNames.INTENT_EXTRA_WIP_DOCUMENT_ID);
Intent startCustomCameraIntent = new Intent(this, CameraActivity.class);
startCustomCameraIntent.putExtra(IntentNames.INTENT_EXTRA_WIP_DOCUMENT_ID, documentId);
startActivityForResult(startCustomCameraIntent, REQUEST_CAMERA);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_CAMERA_PERMISSION:
final int numOfRequest = grantResults.length;
final boolean isGranted = numOfRequest == 1
&& PackageManager.PERMISSION_GRANTED == grantResults[numOfRequest - 1];
Log.v(TAG, "Camera Permission callback on onRequestPermissionsResult");
if (isGranted) {
launch();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
Here is my App Manifest with the Camera Permission:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.myapp.testpackage">
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature
android:name="android.hardware.camera.front"
android:required="true" />
<uses-feature android:name="android.hardware.camera2" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
My Gradle Dependency:
compile 'com.android.support:appcompat-v7:24.0.0'
compile 'com.android.support:design:24.0.0'
compile 'com.android.support:support-v4:24.0.0'

I tried your code myself and everything works just fine. I think that the only thing that can be a problem is the scenario when your activity has these two flags:
android:noHistory="true"
android:excludeFromRecents="true"
Here's a guy that is explains the issue: https://stackoverflow.com/a/35772265/5281581

Related

Workaround EACCES (Permission denied) with MANAGE_EXTERNAL_STORAGE und requestLegacyExternalStorage

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();
}
}
}
}
}

Android Open Camera Permission Denial

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);
}
}

android: FATAL EXCEPTION: java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE

I have tried everything I could find by researching. Nothing is working. I have an Activity with a FragmentDialog. In this dialog, I have an image view with a button. When this button is pressed, an alert pops up to take pic, choose pic from gallery or cancel. Both the cancel and the gallery buttons work great, but when I try to take a photo, I get the error message in the title:
FATAL EXCEPTION: java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE cmp=com.lge.camera/.app.CameraActivity } from ProcessRecord{c6d8bdf 7649:com.devhopes.ryde/u0a152} (pid=7649, uid=10152) with revoked permission android.permission.CAMERA
Below is my DialogFragment and Manifest Code:
UsernameDialogFragment
public static class UsernameDialogFragment extends DialogFragment {
Context applicationContext = bDriverRegistrationActivity.getContextOfApplication();
private ImageView profilePic;
private int REQUEST_CAMERA = 0, SELECT_FILE = 1;
private Button btnSelect;
private String userChosenTask;
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case Utility.MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if(userChosenTask.equals("Take Photo"))
cameraIntent();
else if(userChosenTask.equals("Choose from Library"))
galleryIntent();
} else {
//code for deny
}
break;
}
}
private void galleryIntent() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);//
startActivityForResult(Intent.createChooser(intent, "Select File"),SELECT_FILE);
}
private void cameraIntent() {
Intent intent = new Intent(ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, REQUEST_CAMERA);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == SELECT_FILE)
onSelectFromGalleryResult(data);
else if (requestCode == REQUEST_CAMERA)
onCaptureImageResult(data);
}
}
private void onCaptureImageResult(Intent data) {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
File destination = new File(Environment.getExternalStorageDirectory(),
System.currentTimeMillis() + ".jpg");
FileOutputStream fo;
try {
destination.createNewFile();
fo = new FileOutputStream(destination);
fo.write(bytes.toByteArray());
fo.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
profilePic.setImageBitmap(thumbnail);
}
#SuppressWarnings("deprecation")
private void onSelectFromGalleryResult(Intent data) {
Bitmap bm=null;
if (data != null) {
try {
bm = MediaStore.Images.Media.getBitmap(contextOfApplication
.getContentResolver(), data.getData());
} catch (IOException e) {
e.printStackTrace();
}
}
profilePic.setImageBitmap(bm);
}
private void selectImage() {
final CharSequence[] items = { "Take Photo", "Choose from Library",
"Cancel" };
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Add Photo!");
builder.setItems(items, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int item) {
boolean result=Utility.checkPermission(getActivity());
if (items[item].equals("Take Photo")) {
userChosenTask ="Take Photo";
if(result) {
cameraIntent();
}
} else if (items[item].equals("Choose from Library")) {
userChosenTask ="Choose from Library";
if(result) {
galleryIntent();
}
} else if (items[item].equals("Cancel")) {
dialog.dismiss();
}
}
});
builder.show();
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
super.onCreateDialog(savedInstanceState);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
LayoutInflater inflater = getActivity().getLayoutInflater();
View dialogView = inflater.inflate(R.layout.username_dialog, null);
// Select button
btnSelect = (dialogView).findViewById(R.id.btnSelectPhoto);
btnSelect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectImage();
}
});
// profile pic
profilePic = dialogView.findViewById(R.id.profile_pic);
// Inflate and set the layout for the dialog
// Pass null as the parent view because its going in the dialog layout
builder.setView(dialogView);
// ... Add action buttons ...
builder.setPositiveButton(R.string.action_register, new DialogInterface.OnClickListener() {
#Override
public final void onClick(final DialogInterface dialog, int id) {
// save the username to Firebase and sign in user ...
// ... casting dialog interface to an alert dialog and casting
// the result of the findView to an EditText
EditText usernameField = (EditText)((AlertDialog) dialog).findViewById(username);
String username = usernameField.getText().toString();
// year
EditText yearField = (EditText)((AlertDialog) dialog).findViewById(R.id.year);
String year = yearField.getText().toString();
// color, make and model
EditText cmmField = (EditText)((AlertDialog) dialog).findViewById(R.id.cmm);
String cmm = cmmField.getText().toString();
// cell
EditText cellField = (EditText)((AlertDialog) dialog).findViewById(R.id.cell);
String cell = cellField.getText().toString();
// license plate no.
EditText plateField = (EditText)((AlertDialog) dialog).findViewById(R.id.licenseNo);
String licenseNo = plateField.getText().toString();
// profic pic
ImageView profil_pic = (ImageView)((AlertDialog) dialog).findViewById(R.id.profile_pic);
// TODO: set up profile pic to save to firebase
// ... get user's unique id
String userId = FirebaseAuth.getInstance().getCurrentUser().getUid();
User aUser = new User(username, year, cmm, cell, licenseNo);
/* https://android-chat-af94c.firebaseio.com/android-chat-af94c/
users/pRsxsToJZPTzCdtft69f1grIJC13/profile/username
getInstance -> grabbing the url:
https://android-chat-af94c.firebaseio.com/android-chat-af94c/
*/
// above is the same as below ...
FirebaseDatabase.getInstance().getReference("drivers").child(userId).setValue(aUser);
Intent intent = new Intent(getActivity().getBaseContext(), PoliciesActivity.class);
startActivity(intent);
}
});
return builder.create();
}
} // UsernameDialogFragment
AndroidManifest permissions
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA"
android:requiredFeature="true"/>
<uses-permission android:name="android.permission.STORAGE"/>
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but you must specify either coarse or fine
location permissions for the 'MyLocation' functionality.
-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
In the Android Monitor, it seems to point at 3 lines in particular:
startActivityForResult(intent, REQUEST_CAMERA);
public static class UsernameDialogFragment extends DialogFragment {
cameraIntent();
If you are targeting API Level 23 or more, then you should force get permissions like below(contains several permissions, you can add or remove based on your requirement). Put this in a separate class:
public static List<String> checkAndRequestPermissions(Context context) {
int camera = ContextCompat.checkSelfPermission(context, android.Manifest.permission.CAMERA);
int readStorage = ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE);
int writeStorage = ContextCompat.checkSelfPermission(context, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
int fineLoc = ContextCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_FINE_LOCATION);
int coarseLoc = ContextCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_COARSE_LOCATION);
List<String> listPermissionsNeeded = new ArrayList<>();
if (camera != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.CAMERA);
}
if (readStorage != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.READ_EXTERNAL_STORAGE);
}
if (writeStorage != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (fineLoc != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.ACCESS_FINE_LOCATION);
}
if (coarseLoc != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(android.Manifest.permission.ACCESS_COARSE_LOCATION);
}
return listPermissionsNeeded;
}
And in your activity:
public static final int REQUEST_ID_MULTIPLE_PERMISSIONS = 1; // Declare this integer globally
Add this method(to retrieve permissions):
private boolean permissions(List<String> listPermissionsNeeded) {
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray
(new String[listPermissionsNeeded.size()]), REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true;
}
And force get permissions like this:
// In my case I've put the 'checkAndRequestPermissions' method in a separate class named 'PermissionUtils'
List<String> permissionList = PermissionUtils.checkAndRequestPermissions(this);
if (permissions(permissionList)) {
dispatchTakePictureIntent(); // call your camera instead of this method
}
If you are testing your app with Android 6.x or 7.x version you need to grant some permission (Location,camera etc..) at run time.You can find how to achieve this in here.
https://developer.android.com/training/permissions/requesting.html
Request the permissions you need at runtime. Code is from here so check it out
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {
// 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 {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}

required android.permission Read_External_storage, or grantUrlPermissions error

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();
}
}

Check Permission at Android Marshmallow

I am writing a graphical program in eclipse IDE and compiling with 23 api version, minSdkVersion="11" and that's important for me to keep targetSdkVersion="16".
I have to use device camera in one of my activities (DarjActivity). All things work OK, but since I tried to improve my codes to support permissions of android marshmallow (api 23), so added Check_Permission class that caused for some errors. Please guide me in that confusing problem!
Thanks with regards.
DarjActivity class:
private void selectImage() {
final CharSequence[] items = { "camera", "gallery",
"cancel" };
AlertDialog.Builder builder = new AlertDialog.Builder(DarjActivity.this);
builder.setTitle("capture photo");
builder.setItems(items, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int item) {
boolean result=Check_Permission.checkPermission(DarjActivity.this);
if (items[item].equals("camera")) {
// userChoosenTask="Take Photo";
if(result);
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 1);
} else if (items[item].equals("gallery")) {
// userChoosenTask="Choose from Library";
if(result);
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);//
startActivityForResult(Intent.createChooser(intent, "select"),2);
} else if (items[item].equals("cancel")) {
dialog.dismiss();
}
}
});
builder.show();
}
Check_Permission class:
package com.codegostarNiloo.negar;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
public class Check_Permission {
public static final int MY_PERMISSIONS_REQUEST_CAMERA = 123;
public static boolean checkPermission(final Context context)
{
int currentAPIVersion = Build.VERSION.SDK_INT;
if(Build.VERSION.SDK_INT >= 23)
// if(currentAPIVersion>=Build.VERSION_CODES.M)
{
if (ContextCompat.checkSelfPermission((Activity) context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.CAMERA)) {
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
alertBuilder.setCancelable(true);
alertBuilder.setTitle("Check Permission");
alertBuilder.setMessage("pleas let this applicathion to use your device camera");
alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_CAMERA);
}
});
AlertDialog alert = alertBuilder.create();
alert.show();
} else {
ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.CAMERA}, MY_PERMISSIONS_REQUEST_CAMERA);
}
return false;
} else {
return true;
}
} else {
return true;
}
}
}
Here at Check_Permission class, the (checkSelfPermission) , (shouldShowRequestPermissionRationale) and (requestPermissions) methods occurs errors.
For first parameter of them, I placed (Activity) context, Context context, context, this.Activity, Activity.this, DarjActivity and ext. I updated and replaced some android-support-v4.jar files in bin folder.
AndroidManifest permissions:
<uses-feature android:name="android.hardware.camera"></uses-feature>
<uses-feature android:name="android.hardware.camera" android:required="false"></uses-feature>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="ANDROID.PERMISSION.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="16" />
Step 1.
First implement ActivityCompat.OnRequestPermissionsResultCallback in your activity
private static final int REQUEST_CAMERA_PERMISSION = 1;
private static final String FRAGMENT_DIALOG = "dialog";
Step 2 Override Method
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults)
{
switch (requestCode)
{
case REQUEST_CAMERA_PERMISSION:
if (permissions.length != 1 || grantResults.length != 1) {
throw new RuntimeException("Error on requesting camera permission.");
}
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, R.string.camera_permission_not_granted,
Toast.LENGTH_SHORT).show();
}
// No need to start camera here; it is handled by onResume
break;
}
}
#Override
protected void onResume()
{
super.onResume();
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
== PackageManager.PERMISSION_GRANTED) {
// Do whatever you want to do after the permission granted.
} else if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.CAMERA)) {
ConfirmationDialogFragment
.newInstance(R.string.camera_permission_confirmation,
new String[]{Manifest.permission.CAMERA},
REQUEST_CAMERA_PERMISSION,
R.string.camera_permission_not_granted)
.show(getSupportFragmentManager(), FRAGMENT_DIALOG);
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
REQUEST_CAMERA_PERMISSION);
}
}
Step 3 Write a dialog fragment to ask for the permission -
public static class ConfirmationDialogFragment extends DialogFragment
{
private static final String ARG_MESSAGE = "message";
private static final String ARG_PERMISSIONS = "permissions";
private static final String ARG_REQUEST_CODE = "request_code";
private static final String ARG_NOT_GRANTED_MESSAGE = "not_granted_message";
public static ConfirmationDialogFragment newInstance(#StringRes int message,
String[] permissions, int requestCode, #StringRes int notGrantedMessage) {
ConfirmationDialogFragment fragment = new ConfirmationDialogFragment();
Bundle args = new Bundle();
args.putInt(ARG_MESSAGE, message);
args.putStringArray(ARG_PERMISSIONS, permissions);
args.putInt(ARG_REQUEST_CODE, requestCode);
args.putInt(ARG_NOT_GRANTED_MESSAGE, notGrantedMessage);
fragment.setArguments(args);
return fragment;
}
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Bundle args = getArguments();
return new AlertDialog.Builder(getActivity())
.setMessage(args.getInt(ARG_MESSAGE))
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
String[] permissions = args.getStringArray(ARG_PERMISSIONS);
if (permissions == null)
{
throw new IllegalArgumentException();
}
ActivityCompat.requestPermissions(getActivity(),
permissions, args.getInt(ARG_REQUEST_CODE));
}
})
.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getActivity(),
args.getInt(ARG_NOT_GRANTED_MESSAGE),
Toast.LENGTH_SHORT).show();
}
})
.create();
}
}
Step 4 Always check on onResume() for camera permission
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
== PackageManager.PERMISSION_GRANTED)
{
// Do whatever you want to do if permission granted
}
else if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.CAMERA)) {
ConfirmationDialogFragment
.newInstance(R.string.camera_permission_confirmation,
new String[]{Manifest.permission.CAMERA},
REQUEST_CAMERA_PERMISSION,
R.string.camera_permission_not_granted)
.show(getSupportFragmentManager(), FRAGMENT_DIALOG);
} else {
ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.CAMERA},
REQUEST_CAMERA_PERMISSION);
}
Hope it helps !!
Or just use a simple library like PermissionsDispatcher or Dexter or EasyPermissions or many many others. Why do you need to pollute your code with permissions handling?

Categories

Resources