英文:
Permissions not working in app Camera, causes crash ,caused bypermission denial
问题
在我的应用程序中,我导入了一个用于文档扫描的库。现在我的问题是,当我尝试在库中启动扫描器时,我收到以下错误信息:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.smartpractice.smartpracticesmartapp/com.scanlibrary.ScanActivity}: java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE flg=0x3 cmp=com.huawei.camera/.ThirdCamera clip={text/uri-list U:content://com.scanlibrary.provider/external_files/scanSample/IMG_20200922_115551.jpg} (has extras) } from ProcessRecord{fc4f03f 19801:com.smartpractice.smartpracticesmartapp/u0a384} (pid=19801, uid=10384) with revoked permission android.permission.CAMERA
问题是权限已在应用程序和库的清单文件中声明,如下所示:
<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" />
我尝试在清单文件中的活动中添加 android:exported="true"
,如在 Stack Overflow 的另一个问题中建议的,我还尝试了清理项目、重新构建等。
以下是完整的 Logcat 日志,如果需要的话:
(此处省略了完整的 Logcat 日志)
以下是在 Logcat 中显示的 PickImageFragment
的代码:
package com.scanlibrary;
// ... 省略了导入语句和部分代码 ...
public class PickImageFragment extends Fragment {
// ... 省略了类中的方法和成员变量 ...
private class CameraButtonClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
openCamera();
}
}
private class GalleryClickListener implements View.OnClickListener {
@Override
public void onClick(View view) {
openMediaContent();
}
}
public void openMediaContent() {
// 打开媒体内容的代码
}
public void openCamera() {
// 打开相机的代码
}
private File createImageFile() {
// 创建图像文件的代码
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// 在活动结果返回时的处理代码
}
protected void postImagePick(Bitmap bitmap) {
// 处理图像选择后的代码
}
private Bitmap getBitmap(Uri selectedimg) throws IOException {
// 获取位图的代码
}
}
请注意,上述内容是对您提供的代码片段的翻译。如果您有任何进一步的问题或需要进一步的帮助,请随时提问。
英文:
In My app I am importing a library for a document scanner,
Now my problem is when I try to launch the scanner in the library, I get this error
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.smartpractice.smartpracticesmartapp/com.scanlibrary.ScanActivity}: java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE flg=0x3 cmp=com.huawei.camera/.ThirdCamera clip={text/uri-list U:content://com.scanlibrary.provider/external_files/scanSample/IMG_20200922_115551.jpg} (has extras) } from ProcessRecord{fc4f03f 19801:com.smartpractice.smartpracticesmartapp/u0a384} (pid=19801, uid=10384) with revoked permission android.permission.CAMERA
Now the thing is the premissions are declared in the manifests for the app and in the libraries manifest like
<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" />
I have tried adding android:exported="true"
to the activity in the manifest as suggested on another question here on SO, I also tied the usual Clean Project, Rebuild etc.
here is the full logcat if you need it
Process: com.smartpractice.smartpracticesmartapp, PID: 19801
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.smartpractice.smartpracticesmartapp/com.scanlibrary.ScanActivity}: java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE flg=0x3 cmp=com.huawei.camera/.ThirdCamera clip={text/uri-list U:content://com.scanlibrary.provider/external_files/scanSample/IMG_20200922_115551.jpg} (has extras) } from ProcessRecord{fc4f03f 19801:com.smartpractice.smartpracticesmartapp/u0a384} (pid=19801, uid=10384) with revoked permission android.permission.CAMERA
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3430)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3614)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:86)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199)
at android.os.Handler.dispatchMessage(Handler.java:112)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7625)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
Caused by: java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE flg=0x3 cmp=com.huawei.camera/.ThirdCamera clip={text/uri-list U:content://com.scanlibrary.provider/external_files/scanSample/IMG_20200922_115551.jpg} (has extras) } from ProcessRecord{fc4f03f 19801:com.smartpractice.smartpracticesmartapp/u0a384} (pid=19801, uid=10384) with revoked permission android.permission.CAMERA
at android.os.Parcel.createException(Parcel.java:1953)
at android.os.Parcel.readException(Parcel.java:1921)
at android.os.Parcel.readException(Parcel.java:1871)
at android.app.IActivityManager$Stub$Proxy.startActivity(IActivityManager.java:3733)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1900)
at android.app.Activity.startActivityForResult(Activity.java:5573)
at android.app.Activity.startActivityFromFragment(Activity.java:5538)
at android.app.Activity$HostCallbacks.onStartActivityFromFragment(Activity.java:8277)
at android.app.Fragment.startActivityForResult(Fragment.java:1115)
at android.app.Fragment.startActivityForResult(Fragment.java:1104)
at com.scanlibrary.PickImageFragment.openCamera(PickImageFragment.java:129)
at com.scanlibrary.PickImageFragment.handleIntentPreference(PickImageFragment.java:77)
at com.scanlibrary.PickImageFragment.init(PickImageFragment.java:58)
at com.scanlibrary.PickImageFragment.onCreateView(PickImageFragment.java:48)
at android.app.Fragment.performCreateView(Fragment.java:2537)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1301)
at android.app.FragmentManagerImpl.addAddedFragments(FragmentManager.java:2433)
at android.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2212)
at android.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2168)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2069)
at android.app.FragmentManagerImpl.dispatchMoveToState(FragmentManager.java:3059)
at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3006)
at android.app.FragmentController.dispatchActivityCreated(FragmentController.java:182)
at android.app.Activity.performCreate(Activity.java:7465)
at android.app.Activity.performCreate(Activity.java:7448)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1286)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3409)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3614) 
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:86) 
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199) 
at android.os.Handler.dispatchMessage(Handler.java:112) 
at android.os.Looper.loop(Looper.java:216) 
at android.app.ActivityThread.main(ActivityThread.java:7625) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987) 
Caused by: android.os.RemoteException: Remote stack trace:
at com.android.server.am.ActivityStackSupervisor.checkStartAnyActivityPermission(ActivityStackSupervisor.java:2028)
at com.android.server.am.ActivityStarter.startActivity(ActivityStarter.java:923)
at com.android.server.am.ActivityStarter.startActivity(ActivityStarter.java:656)
at com.android.server.am.HwActivityStarter.startActivity(HwActivityStarter.java:222)
at com.android.server.am.ActivityStarter.startActivityMayWait(ActivityStarter.java:1483)
Here is the code for PickImageFragment shown in the logcat
package com.scanlibrary;
import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import androidx.core.content.FileProvider;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Created by jhansi on 04/04/15.
*/
public class PickImageFragment extends Fragment {
private View view;
private ImageButton cameraButton;
private ImageButton galleryButton;
private Uri fileUri;
private IScanner scanner;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (!(activity instanceof IScanner)) {
throw new ClassCastException("Activity must implement IScanner");
}
this.scanner = (IScanner) activity;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.pick_image_fragment, null);
init();
return view;
}
private void init() {
cameraButton = (ImageButton) view.findViewById(R.id.cameraButton);
cameraButton.setOnClickListener(new CameraButtonClickListener());
galleryButton = (ImageButton) view.findViewById(R.id.selectButton);
galleryButton.setOnClickListener(new GalleryClickListener());
if (isIntentPreferenceSet()) {
handleIntentPreference();
} else {
getActivity().finish();
}
}
private void clearTempImages() {
try {
File tempFolder = new File(ScanConstants.IMAGE_PATH);
for (File f : tempFolder.listFiles())
f.delete();
} catch (Exception e) {
e.printStackTrace();
}
}
private void handleIntentPreference() {
int preference = getIntentPreference();
if (preference == ScanConstants.OPEN_CAMERA) {
openCamera();
} else if (preference == ScanConstants.OPEN_MEDIA) {
openMediaContent();
}
}
private boolean isIntentPreferenceSet() {
int preference = getArguments().getInt(ScanConstants.OPEN_INTENT_PREFERENCE, 0);
return preference != 0;
}
private int getIntentPreference() {
int preference = getArguments().getInt(ScanConstants.OPEN_INTENT_PREFERENCE, 0);
return preference;
}
private class CameraButtonClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
openCamera();
}
}
private class GalleryClickListener implements View.OnClickListener {
@Override
public void onClick(View view) {
openMediaContent();
}
}
public void openMediaContent() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent, ScanConstants.PICKFILE_REQUEST_CODE);
}
public void openCamera() {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File file = createImageFile();
boolean isDirectoryCreated = file.getParentFile().mkdirs();
Log.d("", "openCamera: isDirectoryCreated: " + isDirectoryCreated);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Uri tempFileUri = FileProvider.getUriForFile(getActivity().getApplicationContext(),
"com.scanlibrary.provider", // As defined in Manifest
file);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempFileUri);
} else {
Uri tempFileUri = Uri.fromFile(file);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempFileUri);
}
startActivityForResult(cameraIntent, ScanConstants.START_CAMERA_REQUEST_CODE);
}
private File createImageFile() {
clearTempImages();
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new
Date());
File file = new File(ScanConstants.IMAGE_PATH, "IMG_" + timeStamp +
".jpg");
fileUri = Uri.fromFile(file);
return file;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d("", "onActivityResult" + resultCode);
Bitmap bitmap = null;
if (resultCode == Activity.RESULT_OK) {
try {
switch (requestCode) {
case ScanConstants.START_CAMERA_REQUEST_CODE:
bitmap = getBitmap(fileUri);
break;
case ScanConstants.PICKFILE_REQUEST_CODE:
bitmap = getBitmap(data.getData());
break;
}
} catch (Exception e) {
e.printStackTrace();
}
} else {
getActivity().finish();
}
if (bitmap != null) {
postImagePick(bitmap);
}
}
protected void postImagePick(Bitmap bitmap) {
Uri uri = Utils.getUri(getActivity(), bitmap);
bitmap.recycle();
scanner.onBitmapSelect(uri);
}
private Bitmap getBitmap(Uri selectedimg) throws IOException {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 3;
AssetFileDescriptor fileDescriptor = null;
fileDescriptor =
getActivity().getContentResolver().openAssetFileDescriptor(selectedimg, "r");
Bitmap original
= BitmapFactory.decodeFileDescriptor(
fileDescriptor.getFileDescriptor(), null, options);
return original;
}
}
答案1
得分: 1
检查是否已授予权限。
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
== PackageManager.PERMISSION_DENIED){
// 未授予权限
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.CAMERA}, 0);
} else {
// 已授予权限
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_DENIED){
// 未授予权限
ActivityCompat.requestPermissions(Draw.this, new String[]{android.Manifest.permission
.WRITE_EXTERNAL_STORAGE}, 1);
} else {
// 已授予权限
}
然后重写此方法:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 0){
if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
// 权限已授予
} else {
// 已取消
}
} else if (requestCode == 1){
if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
// 权限已授予
} else {
// 已取消
}
}
}
英文:
Check if permission is granted or not first.
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
== PackageManager.PERMISSION_DENIED){
// Permission not granted
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.CAMERA}, 0);
}else {
//Permission granted
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_DENIED){
// Permission not granted
ActivityCompat.requestPermissions(Draw.this, new String[]{android.Manifest
.permission
.WRITE_EXTERNAL_STORAGE}, 1);
}else {
//Permission granted
}
Then override this method :
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 0){
if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
//permission granted
}else {
//Cancelled
}
}else if (requestCode == 1){
if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
//permission granted
}else {
//Cancelled
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论