java - 访问相机和存储图像 Marshmallow

标签 java android camera

我有这段代码允许用户访问相机拍照并从图库中选择图像,它适用于我运行 Android 5.1.1 的索尼 Xperia Z3。

我现在已经升级到运行 Android 6.0 的 Nexus 5X,但是当我尝试使用相机或保存图像时出现错误,有什么帮助吗?

我使用相机的代码

Intent CameraImage = new Intent("android.media.action.IMAGE_CAPTURE");
Intent SelectedCameraImage = Intent.createChooser(CameraImage, "Take A Photo With");
startActivityForResult(SelectedCameraImage, SELECTED);

我的结果处理程序

public void onActivityResult(int RequestCode, int ResultCode, Intent Data) {
    if (ResultCode == RESULT_OK) {
        if (RequestCode == SELECTED) {
            Uri SelectedImageUri = Data.getData();
            SelectedImagePath = getPath(SelectedImageUri);
            Log.d("DatabaseOperations", "Image Path :  " + SelectedImagePath);
            Img.setImageURI(SelectedImageUri);

            try {
                FileInputStream FileInpStream = new FileInputStream(SelectedImagePath);
                BufferedInputStream BufInputStream = new BufferedInputStream(FileInpStream);
                DBByte = new byte[BufInputStream.available()];
                BufInputStream.read(DBByte);
                Log.d("DatabaseOperations", "Image Size :  " + DBByte.length + " KB");
            }

            catch (IOException e) {
                Log.d("DatabaseOperations", "Error :  " + SelectedImagePath);
                Log.d("DatabaseOperations", e.getMessage(), e);
            }
        }
    }
}

public String getPath(Uri Uris) {
    String[] projection = { MediaStore.Images.Media.DATA };
    Cursor Cursor = managedQuery(Uris, projection, null, null, null);
    int ColumnIndex = Cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    Cursor.moveToFirst();
    return Cursor.getString(ColumnIndex);
}

我的 list 权限

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

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

错误 (Logcat)

FATAL EXCEPTION: main
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime: Process: rajancorporations.database, PID: 3768
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime: java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE cmp=com.google.android.GoogleCamera/com.android.camera.CaptureActivity } from ProcessRecord{c9f94d7 3768:rajancorporations.database/u0a80} (pid=3768, uid=10080) with revoked permission android.permission.CAMERA
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:     at android.os.Parcel.readException(Parcel.java:1620)
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:     at android.os.Parcel.readException(Parcel.java:1573)
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:     at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:2658)
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:     at android.app.Instrumentation.execStartActivity(Instrumentation.java:1507)
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:     at android.app.Activity.startActivityForResult(Activity.java:3930)
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:     at android.app.Activity.startActivityForResult(Activity.java:3890)
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:     at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:784)
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:     at rajancorporations.database.Reg$2.onClick(Reg.java:75)
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:     at android.view.View.performClick(View.java:5204)
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:     at android.view.View$PerformClick.run(View.java:21153)
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:     at android.os.Handler.handleCallback(Handler.java:739)
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:95)
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:148)
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5417)
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method)
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
03-01 22:12:44.071 3768-3768/rajancorporations.database E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

最佳答案

这是我从相机或画廊拍摄图像的完整代码,它在 marshmallow 中与其他人一起工作正常。

在这里声明变量

protected static final int CAMERA_REQUEST = 0;
protected static final int GALLERY_REQUEST = 1;
private static final int REQUEST_ACESS_STORAGE=3;
private static final int REQUEST_ACESS_CAMERA=2;
private Uri uri;

这里我有一些棉花糖权限的方法

public static boolean checkPermission(String permission, Context context) {
    int statusCode = ContextCompat.checkSelfPermission(context, permission);
    return statusCode == PackageManager.PERMISSION_GRANTED;
}

public static void requestPermission(AppCompatActivity activity, String[] permission, int requestCode) {
    if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permission[0])) {
        Toast.makeText(activity, "Application need permission", Toast.LENGTH_SHORT).show();
    }
    ActivityCompat.requestPermissions(activity, permission, requestCode);
}

public static void requestPermission(Fragment fragment, String[] permission, int requestCode) {
    fragment.requestPermissions(permission, requestCode);
}

我的点击方法

if (v.getId()==R.id.idOfPhoto){
            handleCamera();
        }

handle 相机方法详解

private void handleCamera(){
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M) {
            if (checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, this)) {
                startDilog();
            }else{
               requestPermission(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},REQUEST_ACESS_STORAGE);
            }
        }else{
            startDilog();
        }
    }

启动日志方法

private void startDilog() {
    AlertDialog.Builder myAlertDilog = new AlertDialog.Builder(YourActivity.this);
    myAlertDilog.setTitle("Upload picture option..");
    myAlertDilog.setMessage("Where to upload picture????");
    myAlertDilog.setPositiveButton("Gallery", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            Intent picIntent = new Intent(Intent.ACTION_GET_CONTENT,null);
            picIntent.setType("image/*");
            picIntent.putExtra("return_data",true);
            startActivityForResult(picIntent,GALLERY_REQUEST);
        }
    });
    myAlertDilog.setNegativeButton("Camera", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
                if(checkPermission(Manifest.permission.CAMERA,YourActivity.this)){
                    openCameraApplication();
                }else{
                    requestPermission(YourActivity.this,new String[]{Manifest.permission.CAMERA},REQUEST_ACESS_CAMERA);
                }
            }else{
                openCameraApplication();
            }
        }
    });
    myAlertDilog.show();
}

openCameraApplication 方法

private void openCameraApp() {
    Intent picIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (picIntent.resolveActivity(getPackageManager())!= null){
        startActivityForResult(picIntent, CAMERA_REQUEST);
    }
}

其余代码

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == GALLERY_REQUEST) {
        if (resultCode == RESULT_OK) {
            if (data != null) {
                uri = data.getData();
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true;
                try {
                    BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options);
                    options.inSampleSize =calculateInSampleSize(options, 100, 100);
                    options.inJustDecodeBounds = false;
                    Bitmap image = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options);
                    imageview.setImageBitmap(image);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                Toast.makeText(getApplicationContext(), "Cancelled",
                        Toast.LENGTH_SHORT).show();
            }
        } else if (resultCode == RESULT_CANCELED) {
            Toast.makeText(getApplicationContext(), "Cancelled",
                    Toast.LENGTH_SHORT).show();
        }
    } else if (requestCode == CAMERA_REQUEST) {
        if (resultCode == RESULT_OK) {
            if (data.hasExtra("data")) {
                Bitmap bitmap = (Bitmap) data.getExtras().get("data");
                uri = getImageUri(YourActivity.this, bitmap);
                File finalFile = new File(getRealPathFromUri(uri));
                imageview.setImageBitmap(bitmap);
            } else if (data.getExtras() == null) {

                Toast.makeText(getApplicationContext(),
                        "No extras to retrieve!", Toast.LENGTH_SHORT)
                        .show();

                BitmapDrawable thumbnail = new BitmapDrawable(
                        getResources(), data.getData().getPath());
                owner_pic.setImageDrawable(thumbnail);

            }

        } else if (resultCode == RESULT_CANCELED) {
            Toast.makeText(getApplicationContext(), "Cancelled",
                    Toast.LENGTH_SHORT).show();
        }
    }
}

private String getRealPathFromUri(Uri tempUri) {
    Cursor cursor = null;
    try {
        String[] proj = {MediaStore.Images.Media.DATA};
        cursor = this.getContentResolver().query(tempUri, proj, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
}
private Uri getImageUri(YourActivity youractivity, Bitmap bitmap) {
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
    String path = MediaStore.Images.Media.insertImage(youractivity.getContentResolver(), bitmap, "Title", null);
    return Uri.parse(path);

public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            // Calculate the largest inSampleSize value that is a power of 2 and keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }
        return inSampleSize;
    }



@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if(requestCode==REQUEST_ACESS_STORAGE && grantResults[0]== PackageManager.PERMISSION_GRANTED){
        startDilog();
    }
    if(requestCode==REQUEST_ACESS_CAMERA && grantResults[0]==PackageManager.PERMISSION_GRANTED){
        openCameraApp();
    }
}

它在所有设备上都运行良好..

关于java - 访问相机和存储图像 Marshmallow,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35734996/

相关文章:

java - 如果 read 返回 -1 套接字是否自动关闭?

c# - 正则表达式在 C# 中匹配,但在 java 中不匹配

android - 使用 Aquery 在 sdcar 中存储图像 - Android

android - 尝试使用 Intent 在android中打开特定文件夹

windows-phone-7 - 如何在 Windows Phone 中使相机图像曝光不足?

javascript - 三个jslensflare渲染在外面

java - 使用java扫描仪读取文本文件

java - 如何从android中的字节数组加载类?

Android setX() 和 setY() 表现怪异

iphone - 访问用于相机曝光和快门速度的 iOS 6 新 API