android:致命异常:java.lang.SecurityException:权限被拒绝:启动 Intent { act=android.media.action.IMAGE_CAPTURE
android: FATAL EXCEPTION: java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE
我已经通过研究尝试了所有我能找到的东西。什么都不起作用。我有一个带有 FragmentDialog 的 Activity。在这个对话框中,我有一个带有按钮的图像视图。按下此按钮时,会弹出一个提示,提示您拍照、从相册中选择照片或取消。取消和图库按钮都很好用,但是当我尝试拍照时,我在标题中收到错误消息:
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
下面是我的 DialogFragment 和清单代码:
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
Android清单权限
<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" />
在Android监视器中,它似乎特别指向3行:
- 开始ActivityForResult(intent, REQUEST_CAMERA);
- public 静态 class UsernameDialogFragment 扩展 DialogFragment {
- cameraIntent();
在运行时请求您需要的权限。代码来自 here,请查看
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.
}
}
如果您使用 Android 6.x 或 7.x 版本测试您的应用程序,您需要在 运行 time.You 可以在这里找到实现方法。
https://developer.android.com/training/permissions/requesting.html
如果您的目标是 API 23 级或更高级别,那么您应该强制获取如下权限(包含多个权限,您可以根据您的要求添加或删除)。把它放在一个单独的 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;
}
在你的activity中:
public static final int REQUEST_ID_MULTIPLE_PERMISSIONS = 1; // Declare this integer globally
添加此方法(以检索权限):
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;
}
并强制获得这样的权限:
// 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
}
我已经通过研究尝试了所有我能找到的东西。什么都不起作用。我有一个带有 FragmentDialog 的 Activity。在这个对话框中,我有一个带有按钮的图像视图。按下此按钮时,会弹出一个提示,提示您拍照、从相册中选择照片或取消。取消和图库按钮都很好用,但是当我尝试拍照时,我在标题中收到错误消息:
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
下面是我的 DialogFragment 和清单代码:
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
Android清单权限
<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" />
在Android监视器中,它似乎特别指向3行:
- 开始ActivityForResult(intent, REQUEST_CAMERA);
- public 静态 class UsernameDialogFragment 扩展 DialogFragment {
- cameraIntent();
在运行时请求您需要的权限。代码来自 here,请查看
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.
}
}
如果您使用 Android 6.x 或 7.x 版本测试您的应用程序,您需要在 运行 time.You 可以在这里找到实现方法。 https://developer.android.com/training/permissions/requesting.html
如果您的目标是 API 23 级或更高级别,那么您应该强制获取如下权限(包含多个权限,您可以根据您的要求添加或删除)。把它放在一个单独的 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;
}
在你的activity中:
public static final int REQUEST_ID_MULTIPLE_PERMISSIONS = 1; // Declare this integer globally
添加此方法(以检索权限):
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;
}
并强制获得这样的权限:
// 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
}