【问题标题】:Taking photo fails with "requires android:camera"拍照失败并显示“需要 android:camera”
【发布时间】:2016-06-23 11:12:56
【问题描述】:

我用下面的代码拍照

Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File photoPath = new File(getExternalFilesDir(null), "postcard.jpg");
takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                Uri.fromFile(photoPath));
log.debug("start camera for {}", photoPath.getAbsolutePath());
startActivityForResult(takePhotoIntent, REQUEST_TAKE_PHOTO);

...

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_TAKE_PHOTO) {
        if (resultCode == RESULT_OK) {
            log.debug("photo successfully created");
        } else {
            log.error("problem to take photo resultCode={}", resultCode);
        }
    } else {
        log.debug("not my request: {}", requestCode);
    }
}

这在 Android 5 上运行良好,但在 Android 6 上失败并出现 resultCode=0 (RESULT_CANCELED) 和 logcat 错误消息:

03-09 07:56:13.759 878-3735/? W/ActivityManager:Appop 拒绝: 开始意图 { act=android.media.action.IMAGE_CAPTURE flg=0x3 cmp=com.google.android.GoogleCamera/com.android.camera.CaptureActivity 剪辑={文本/uri列表 U:file:///storage/emulated/0/Android/data/censored.package.name.here/files/postcard.jpg} (有附加功能)}来自 ProcessRecord{55cce35 21309:censored.package.name.here/u0a136} (pid=21309, uid=10136) 需要安卓:相机

我在 Android Manifest 中有以下内容:

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />

我也检查一下应用是否真的有摄像头权限,这个检查通过了。

checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED

另外值得注意的是,我在项目中包含了一个也使用相机的 aar。这个包含的库在清单中有这个:

<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.camera.front" android:required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<uses-feature android:name="android.hardware.camera.flash" android:required="false"/>
<uses-feature android:name="android.hardware.screen.landscape" android:required="false" />
<uses-feature android:name="android.hardware.wifi" android:required="false"/>

有人知道错误消息的含义或如何解决此问题吗? Google 在这种情况下没有帮助。

到目前为止,我还没有通过一个小示例成功重现该问题。这似乎是与另一个应用程序部分的一些交互。

【问题讨论】:

  • @O'one 谢谢,但不,这是一个不同的问题。我获得了许可,而且错误消息也不同。
  • 你可以通过将target sdk设置为22来尝试它,因为它也会在23上运行,如果它运行那么肯定会由于权限问题而发生。
  • @O'one 与目标 sdk 22 完全相同。
  • 确保相机应用已启用相机和存储权限

标签: android android-camera android-6.0-marshmallow


【解决方案1】:

经过一天多的试验和调试,它现在可以工作了。代码还是一样的。

我想,通过设置收回相机权限,然后重新启用它就可以了,但我不完全确定。

如果有人遇到同样的问题,请将此作为答案发布。

【讨论】:

    【解决方案2】:

    -- 用于捕获图像、保存到 SD 卡、从图库中选择、压缩、旋转图像等的完整代码。200% 工作。

    public class A extends AppCompatActivity implements View.OnClickListener, AsyncTaskCompleteListener {
    
        private static final String IMAGE_DIRECTORY = "/idyme";
        private static int MAX_IMAGE_DIMENSION = 200;
        private final String TAG = "RegisterFragment";
        private Button btnVerify, btnUploadImage;
    
        private String   ImgPath = null, filePath = null,
                profileImageFilePath, profileImageData = null,imageVideoType = "", imageVideoPath = "";
        private ImageView ivImage;
        private AQuery aQuery;
        private Uri uri = null;
        private ImageOptions imageOptions;
        ActionBar actionBar;
    
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_vip_registration);
    
    
            ivImage = (ImageView) findViewById(R.id.ivProfile);
            aQuery = new AQuery(this);
            imageOptions = new ImageOptions();
            imageOptions.memCache = true;
            imageOptions.fileCache = true;
            imageOptions.fallback = R.drawable.userimage;
    
    
    
    
    
    
        }
    
        @Override
        public void onClick(View v) {
            //  onRegisterButtonClick();
    
            switch (v.getId()) {
    
                case R.id.btnUploadImage:
                    showPictureDialog();
            }
        }
    
        private void showPictureDialog() {
            AlertDialog.Builder pictureDialog = new AlertDialog.Builder(this);
            pictureDialog.setTitle(getResources().getString(
                    R.string.dialog_chhose_photo));
            String[] pictureDialogItems = {
                    getResources().getString(R.string.dialog_from_gallery),
                    getResources().getString(R.string.dialog_from_camera)};
    
            pictureDialog.setItems(pictureDialogItems,
                    new DialogInterface.OnClickListener() {
    
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            switch (which) {
    
                                case 0:
                                    choosePhotoFromGallary();
                                    break;
    
                                case 1:
                                    takePhotoFromCamera();
                                    break;
    
                            }
                        }
                    });
            pictureDialog.show();
        }
    
        private void choosePhotoFromGallary() {
            Intent galleryIntent = new Intent(Intent.ACTION_PICK,
                    android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    
            startActivityForResult(galleryIntent, Constants.CHOOSE_PHOTO);
    
    
        }
    
        private void takePhotoFromCamera() {
            Calendar cal = Calendar.getInstance();
            File file = new File(Environment.getExternalStorageDirectory(),
                    (cal.getTimeInMillis() + ".jpg"));
    
            if (!file.exists()) {
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
    
                file.delete();
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            //   uri = Uri.fromFile(file);
            uri = getOutputMediaFileUri();
            Intent cameraIntent = new Intent(
                    android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
            startActivityForResult(cameraIntent, Constants.TAKE_PHOTO);
    
    
        }
    
        public Uri getOutputMediaFileUri() {
            return Uri.fromFile(getOutputMediaFile());
        }
    
        private String getRealPathFromURI(Uri contentURI) {
            String result;
    
            String[] proj = {MediaStore.Images.Media.DATA};
            Cursor cursor = this.getContentResolver().query(contentURI, proj, null, null, null);
    
            if (cursor == null) { // Source is Dropbox or other similar local file
                // path
                result = contentURI.getPath();
            } else {
                cursor.moveToFirst();
                int idx = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                result = cursor.getString(idx);
                cursor.close();
            }
    
    
            return result;
    
    
        }
    
    
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
    
            super.onActivityResult(requestCode, resultCode, data);
            if (resultCode == this.RESULT_CANCELED) {
                return;
            }
            if (requestCode == Constants.CHOOSE_PHOTO) {
                if (data != null) {
                    Uri contentURI = data.getData();
                    profileImageData = getRealPathFromURI(contentURI);
                    // new AQuery(getApplicationContext()).id(ivMeme).image(
                    // profileImageData, imageOptions);
                    try {
                        String path = saveImage(scaleImage(this, contentURI));
                        imageVideoPath = path;
                        aQuery.id(R.id.ivProfile).image(
                                imageVideoPath, imageOptions);
                    } catch (IOException e) {
                        e.printStackTrace();
                        Utils.showToast("Failed", this);
                    }
    
                }
    
            } else if (requestCode == Constants.TAKE_PHOTO) {
    
    
                // old
                if (uri != null) {
                    profileImageFilePath = uri.getPath();
                    if (profileImageFilePath != null
                            && profileImageFilePath.length() > 0) {
                        File myFile = new File(profileImageFilePath);
                        String path = saveImage(BitmapFactory
                                .decodeFile(profileImageFilePath));
                        imageVideoPath = path;
                        aQuery.id(R.id.ivProfile).image(
                                imageVideoPath, imageOptions);
                    } else {
                       Utils.showToast("Failed", this);
                    }
    
                } else {
                    Utils.showToast("Failed", this);
                }
    
            }
    
        }
    
        public String saveImage(Bitmap myBitmap) {
            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
            myBitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
            File wallpaperDirectory = new File(
                    Environment.getExternalStorageDirectory() + IMAGE_DIRECTORY);
            // have the object build the directory structure, if needed.
            if (!wallpaperDirectory.exists()) {
                wallpaperDirectory.mkdirs();
            }
    
            try {
                File f = new File(wallpaperDirectory, Calendar.getInstance()
                        .getTimeInMillis() + ".jpg");
                f.createNewFile();
                FileOutputStream fo = new FileOutputStream(f);
                fo.write(bytes.toByteArray());
                MediaScannerConnection.scanFile(this,
                        new String[]{f.getPath()},
                        new String[]{"image/jpeg"}, null);
                fo.close();
                AppLog.Log("TAG", "File Saved::-> " + f.getAbsolutePath());
                return f.getAbsolutePath();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            return "";
        }
    
    
    private static File getOutputMediaFile() {
    
            // External sdcard location
            File mediaStorageDir = new File(
                    Environment
                            .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
                    IMAGE_DIRECTORY);
    
            // Create the storage directory if it does not exist
            if (!mediaStorageDir.exists()) {
                if (!mediaStorageDir.mkdirs()) {
                    Log.d(IMAGE_DIRECTORY, "Oops! Failed create " + IMAGE_DIRECTORY
                            + " directory");
                    return null;
                }
            }
    
            // Create a media file name
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
                    Locale.getDefault()).format(new Date());
            File mediaFile;
            mediaFile = new File(mediaStorageDir.getPath() + File.separator
                    + "VID_" + timeStamp + ".mp4");
    
            return mediaFile;
        }
    
        public static Bitmap scaleImage(Context context, Uri photoUri)
                throws IOException {
            InputStream is = context.getContentResolver().openInputStream(photoUri);
            BitmapFactory.Options dbo = new BitmapFactory.Options();
            dbo.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(is, null, dbo);
            is.close();
    
            int rotatedWidth, rotatedHeight;
            int orientation = getOrientation(context, photoUri);
    
            if (orientation == 90 || orientation == 270) {
                rotatedWidth = dbo.outHeight;
                rotatedHeight = dbo.outWidth;
            } else {
                rotatedWidth = dbo.outWidth;
                rotatedHeight = dbo.outHeight;
            }
    
            Bitmap srcBitmap;
            is = context.getContentResolver().openInputStream(photoUri);
            if (rotatedWidth > MAX_IMAGE_DIMENSION
                    || rotatedHeight > MAX_IMAGE_DIMENSION) {
                float widthRatio = ((float) rotatedWidth)
                        / ((float) MAX_IMAGE_DIMENSION);
                float heightRatio = ((float) rotatedHeight)
                        / ((float) MAX_IMAGE_DIMENSION);
                float maxRatio = Math.max(widthRatio, heightRatio);
    
                // Create the bitmap from file
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = (int) maxRatio;
                srcBitmap = BitmapFactory.decodeStream(is, null, options);
            } else {
                srcBitmap = BitmapFactory.decodeStream(is);
            }
            is.close();
    
            /*
             * if the orientation is not 0 (or -1, which means we don't know), we
             * have to do a rotation.
             */
            if (orientation > 0) {
                Matrix matrix = new Matrix();
                matrix.postRotate(orientation);
    
                srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0,
                        srcBitmap.getWidth(), srcBitmap.getHeight(), matrix, true);
            }
    
            String type = context.getContentResolver().getType(photoUri);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            if (type.equals("image/png")) {
                srcBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
            } else if (type.equals("image/jpg") || type.equals("image/jpeg")) {
                srcBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
            }
            byte[] bMapArray = baos.toByteArray();
            baos.close();
            return BitmapFactory.decodeByteArray(bMapArray, 0, bMapArray.length);
        }
    
    
        public static int getOrientation(Context context, Uri photoUri) {
            /* it's on the external media. */
            Cursor cursor = context.getContentResolver().query(photoUri,
                    new String[]{MediaStore.Images.ImageColumns.ORIENTATION},
                    null, null, null);
    
            if (cursor.getCount() != 1) {
                return -1;
            }
    
            cursor.moveToFirst();
            return cursor.getInt(0);
        }
    
    }
    

    -- 需要权限:

     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.CAMERA" />
    

    【讨论】:

    • 你没看懂,这就是我在做的,哪一个不行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多