从相机和图库上传在所有版本中都无法正常工作

Posted

技术标签:

【中文标题】从相机和图库上传在所有版本中都无法正常工作【英文标题】:Upload from camera and gallery is not working properly in all the versions 【发布时间】:2016-09-11 02:51:21 【问题描述】:

我正在尝试一些教程和示例代码,以便从图库或相机中获取图像,然后裁剪图像并将其上传到服务器。我在该代码中实现了该代码,但面临的问题很少。

    在 Lollipop 之前的设备中,当我使用照片应用裁剪图像时,图像不会反映在图像视图中,但会在图像保存时显示消息.. 在 nexus 手机中,相机和图库均无法正常工作。

    当我裁剪图像时,在少数设备上的 5.0 版本得到的图像如下图所示

下面是我的代码sn-p。`

public void getPhoto() 

        final String[] items = new String[]  "Take from camera",
                "Select from gallery" ;
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
                android.R.layout.select_dialog_item, items);
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

        builder.setTitle("Select Image");
        builder.setAdapter(adapter, new DialogInterface.OnClickListener() 
            public void onClick(DialogInterface dialog, int item)  // pick from
                                                                    // camera
                if (item == 0) 
                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    intent.putExtra(
                            "android.intent.extras.CAMERA_FACING",
                            android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT);
                    mImageCaptureUri = Uri.fromFile(new File(Environment
                            .getExternalStorageDirectory(), "tmp_avatar_"
                            + String.valueOf(System.currentTimeMillis())
                            + ".jpg"));

                    intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,
                            mImageCaptureUri);

                    try 
                        intent.putExtra("return-data", true);
                        startActivityForResult(intent, PICK_FROM_CAMERA);
                     catch (ActivityNotFoundException e) 
                        e.printStackTrace();
                    
                 else  // pick from file
                    Intent intent = new Intent(Intent.ACTION_PICK);
                    intent.setType("image/*");
                    // startActivityForResult(intent, SELECT_PICTURE);
                    startActivityForResult(intent, PICK_FROM_FILE);
                
            
        );

        final AlertDialog dialog = builder.create();
        dialog.show();

    

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) 
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode != Activity.RESULT_OK)
            return;

        switch (requestCode) 
        case PICK_FROM_CAMERA:
            doCrop();

            break;

        case PICK_FROM_FILE:
            mImageCaptureUri = data.getData();
            doCrop();
            break;

        case CROP_FROM_CAMERA:
            Bundle extras = data.getExtras();
            if (extras != null) 
                photo = extras.getParcelable("data");
                profile_image = encodeTobase64(photo);
                saveType = "photo";
                try 
                    JSONObject obj = new JSONObject();
                    obj.put("user_id", user_id);
                    obj.put("mode", saveType);
                    obj.put("photo", profile_image);
                    obj.put("is_profile", 1);
                    saveResponse(obj);
                 catch (Exception e) 
                    // TODO: handle exception
                    e.printStackTrace();
                

            
            File f = new File(mImageCaptureUri.getPath());
            if (f.exists())
                f.delete();
            break;
        
    

    private void doCrop() 
        final ArrayList<CropOption> cropOptions = new ArrayList<CropOption>();
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setType("image/*");
        List<ResolveInfo> list = getActivity().getPackageManager()
                .queryIntentActivities(intent, 0);
        int size = list.size();
        if (size == 0) 
            Toast.makeText(getActivity(), "Can not find image crop app",
                    Toast.LENGTH_SHORT).show();
            return;
         else 
            intent.setData(mImageCaptureUri);
            intent.putExtra("crop", "true");
            intent.putExtra("outputX", 300);
            intent.putExtra("outputY", 300);
            intent.putExtra("aspectX", 1);
            intent.putExtra("aspectY", 1);
            intent.putExtra("scale", true);
            intent.putExtra("circleCrop", new String(""));
            intent.putExtra("return-data", true);
            if (size == 1) 
                Intent i = new Intent(intent);
                ResolveInfo res = list.get(0);

                i.setComponent(new ComponentName(res.activityInfo.packageName,
                        res.activityInfo.name));
                startActivityForResult(i, CROP_FROM_CAMERA);
             else 
                for (ResolveInfo res : list) 
                    final CropOption co = new CropOption();

                    co.title = getActivity().getPackageManager()
                            .getApplicationLabel(
                                    res.activityInfo.applicationInfo);
                    co.icon = getActivity().getPackageManager()
                            .getApplicationIcon(
                                    res.activityInfo.applicationInfo);
                    co.appIntent = new Intent(intent);
                    co.appIntent
                            .setComponent(new ComponentName(
                                    res.activityInfo.packageName,
                                    res.activityInfo.name));
                    cropOptions.add(co);
                

                CropOptionAdapter adapter = new CropOptionAdapter(
                        getActivity(), cropOptions);

                AlertDialog.Builder builder = new AlertDialog.Builder(
                        getActivity());
                builder.setTitle("Choose Crop App");
                builder.setAdapter(adapter,
                        new DialogInterface.OnClickListener() 
                            public void onClick(DialogInterface dialog, int item) 
                                startActivityForResult(
                                        cropOptions.get(item).appIntent,
                                        CROP_FROM_CAMERA);
                            
                        );

                builder.setOnCancelListener(new DialogInterface.OnCancelListener() 
                    @Override
                    public void onCancel(DialogInterface dialog) 

                        if (mImageCaptureUri != null) 
                            getActivity().getContentResolver().delete(
                                    mImageCaptureUri, null, null);
                            mImageCaptureUri = null;
                        
                    
                );

                AlertDialog alert = builder.create();

                alert.show();
            
        
    

    public String encodeTobase64(Bitmap image) 
        Bitmap immagex = image;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        immagex.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        image_Array = baos.toByteArray();
        String imageEncoded = Base64
                .encodeToString(image_Array, Base64.DEFAULT);
        return imageEncoded;
    

`

在复制这个问题之前在下面评论,因为我被检查了很多但没有找到任何解决方案,如果您需要更多信息,请告诉我。

【问题讨论】:

我通过删除 intent.putExtra("circleCrop", new String("")); 清除了问题 3;从代码 【参考方案1】:

我正在使用此代码,它适用于所有版本的 android 注意:您可以省略selectImage函数中的自定义对话框代码或为其创建自定义对话框

在 build graddle 文件中添加以下内容 compile 'com.theartofdev.edmodo:android-image-cropper:2.1.+'

 private File photoFile = null;
    public void selectImage() 
            final Dialog dialog = new Dialog(this, R.style.CustomDialog);
            dialog.setContentView(R.layout.custom_dialog);
            dialog.setCancelable(true);
            dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
            final TextView camrea= (TextView) dialog.findViewById(R.id.text);
            final TextView lib= (TextView) dialog.findViewById(R.id.text1);
            final TextView cancel= (TextView) dialog.findViewById(R.id.text2);
            camrea.setOnClickListener(new View.OnClickListener() 
                @Override
                public void onClick(View v) 
                    dispatchTakePictureIntent() ;
                    dialog.cancel();
                
            );
            lib.setOnClickListener(new View.OnClickListener() 
                @Override
                public void onClick(View v) 
                    if (Build.VERSION.SDK_INT < 19) 
                        Intent intent = new Intent();
                        intent.setType("image/*");
                        intent.setAction(Intent.ACTION_GET_CONTENT);
                        intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
                        startActivityForResult(Intent.createChooser(intent, "Complete action using"), 200);
                     else 
                        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                        intent.addCategory(Intent.CATEGORY_OPENABLE);
                        intent.setType("image/*");
                        intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
                        startActivityForResult(intent, 300);
                    
                    dialog.cancel();
                
            );
            cancel.setOnClickListener(new View.OnClickListener() 
                @Override
                public void onClick(View v) 
                    dialog.cancel();
                
            );
            dialog.show();

        



         private void dispatchTakePictureIntent() 
            MarshMallowPermission marshMallowPermission = new MarshMallowPermission(this);
            if (!marshMallowPermission.checkPermissionForCamera()) 
                marshMallowPermission.requestPermissionForCamera();
             else 
                if (!marshMallowPermission.checkPermissionForExternalStorage()) 
                    marshMallowPermission.requestPermissionForExternalStorage();
                 else 
                    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    // Ensure that there's a camera activity to handle the intent
                    if (takePictureIntent.resolveActivity(getPackageManager()) != null) 
                        // Create the File where the photo should go
                        try 
                            photoFile = createImageFile();
                         catch (IOException ex) 
                            // Error occurred while creating the File
                        
                        // Continue only if the File was successfully created
                        if (photoFile != null) 
                            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
                            //Log.d("Uri","Activity started");
                            startActivityForResult(takePictureIntent, 100);
                        
                    
                
            

            private void startCropImage(Uri crop) 
    CropImage.activity(crop)
            .setGuidelines(CropImageView.Guidelines.ON)
            .setAutoZoomEnabled(true)
            .setShowCropOverlay(true)
            .setActivityTitle("Crop Image")
            .start(this);



private File createImageFile() throws IOException 
    @SuppressLint("SimpleDateFormat")
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    return File.createTempFile(
            imageFileName,/* prefix */
            ".jpg",       /* suffix */
            storageDir    /* directory */);


 protected void onActivityResult(int requestCode, int resultCode, Intent data) 
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode != RESULT_OK)
            return;

      if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) 
        final CropImage.ActivityResult result = CropImage.getActivityResult(data);
        Log.d(TAG," : Image-URI :"+result.getUri());


    else if (requestCode == 100) 
            if("com.google.android.apps.docs.storage".equals(Uri.fromFile(photoFile).getAuthority()))
                Toast.makeText(RegistrationActivity.this, "File Not On Device", Toast.LENGTH_SHORT).show();
            else 
               startCropImage(Uri.fromFile(photoFile));
            



         else if (requestCode == 200) 
            mIsImageUploadUri=Uri.parse(getPathFromURI(getApplicationContext(),Uri.parse(data.getData().toString())));
            final Uri selectedImage = Uri.parse(getPathFromURI(getApplicationContext(),data.getData()));
             //Log.d(TAG,"Uri"+ selectedImage.toString());
            if("com.google.android.apps.docs.storage".equals(selectedImage.getAuthority()))
                Toast.makeText(RegistrationActivity.this, "File Not On Device", Toast.LENGTH_SHORT).show();
            else 

                 startCropImage(data.getData());

            

        else if (requestCode == 300) 
            final Uri originalUri = data.getData();
            final int takeFlags = data.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            //noinspection ResourceType
            getContentResolver().takePersistableUriPermission(originalUri, takeFlags);
             Log.d(TAG,"Uri"+ originalUri.toString());
            if("com.google.android.apps.docs.storage".equals(originalUri.getAuthority()))
                Toast.makeText(RegistrationActivity.this, "File Not On Device", Toast.LENGTH_SHORT).show();
            else 

                startCropImage(originalUri);
            
        
    
        @TargetApi(Build.VERSION_CODES.KITKAT)
        public static String getPathFromURI(final Context context, final Uri uri) 
            final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
            // DocumentProvider
            if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) 
                // ExternalStorageProvider
                if (isExternalStorageDocument(uri)) 
                    final String docId = DocumentsContract.getDocumentId(uri);
                    final String[] split = docId.split(":");
                    final String type = split[0];
                    if ("primary".equalsIgnoreCase(type)) 
                        return Environment.getExternalStorageDirectory() + "/" + split[1];
                    
                
                // DownloadsProvider
                else if (isDownloadsDocument(uri)) 

                    final String id = DocumentsContract.getDocumentId(uri);
                    final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
                    return getDataColumn(context, contentUri, null, null);
                
                // MediaProvider
                else if (isMediaDocument(uri)) 
                    final String docId = DocumentsContract.getDocumentId(uri);
                    final String[] split = docId.split(":");
                    final String type = split[0];
                    Uri contentUri = null;
                    if ("image".equals(type)) 
                        contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                     else if ("video".equals(type)) 
                        contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                     else if ("audio".equals(type)) 
                        contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                    
                    final String selection = "_id=?";
                    final String[] selectionArgs = new String[] 
                            split[1]
                    ;
                    return getDataColumn(context, contentUri, selection, selectionArgs);
                
            
            // MediaStore (and general)
            else if ("content".equalsIgnoreCase(uri.getScheme())) 
                return getDataColumn(context, uri, null, null);
            
            // File
            else if ("file".equalsIgnoreCase(uri.getScheme())) 
                return uri.getPath();
            
            return null;
        
        public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) 
            Cursor cursor = null;
            final String column = "_data";
            final String[] projection = 
                    column
            ;
            try 
                cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                        null);
                if (cursor != null && cursor.moveToFirst()) 
                    final int column_index = cursor.getColumnIndexOrThrow(column);
                    return cursor.getString(column_index);
                
             finally 
                if (cursor != null)
                    cursor.close();
            
            return null;
        
        public static boolean isExternalStorageDocument(Uri uri) 
            return "com.android.externalstorage.documents".equals(uri.getAuthority());
        
        public static boolean isDownloadsDocument(Uri uri) 
            return "com.android.providers.downloads.documents".equals(uri.getAuthority());
        
        public static boolean isMediaDocument(Uri uri) 
            return "com.android.providers.media.documents".equals(uri.getAuthority());
        

【讨论】:

在nexus手机上也能用吗,你测试了吗 但是您的代码没有裁剪选项对吗?如果可能的话,你可以分享 git 链接,以便我可以检查整个代码 没有createImageFile();该代码中的方法你也可以更新 让我们continue this discussion in chat。 我怎样才能将那个 jar 文件用于 eclip。我尝试了 jar 文件,但没有找到任何方法【参考方案2】:

上周我遇到了同样的问题,我终于解决了,这有点不同,我从服务器获取 Base64 中的图像然后裁剪它

这是代码

byte[] decodedString = Base64.decode(imageJson, Base64.DEFAULT);
Bitmap tmp = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
bitmapDecoded = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

int h = metrics.heightPixels;
int w = metrics.widthPixels;
Bitmap resized = Bitmap.createScaledBitmap(tmp, tmp.getWidth(), (int) (tmp.getHeight()*1.6), true);
imageView.setImageBitmap(canvas.getCircleBitmap(resized, w,h));

imageJson 是 Base64 中的图像它是一个字符串我将它转换为位图,在我获得屏幕大小后,调整大小的位图在这里是为了有一个方形图像,因为我有一个 16/9 图像这可能是对你没用,最后我在 imageView 中显示位图并用画布方法 getCircleBitmap 裁剪它

方法如下

public Bitmap getCircleBitmap(Bitmap bitmap,int width, int height) 
    final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
            bitmap.getHeight(), Bitmap.Config.ARGB_8888);
    final Canvas canvas = new Canvas(output);
    final int color = Color.RED;
    final Paint paint = new Paint();
    final Rect rect = new Rect((int)(bitmap.getWidth()*0.054), (int) (height*0.005), (int) (bitmap.getWidth()*0.945), (bitmap.getHeight()));
    final RectF rectF = new RectF(rect);

    paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    canvas.drawOval(rectF, paint);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    canvas.drawBitmap(bitmap, rect, rect, paint);
    bitmap.recycle();

    return output;

您可以更改矩形的值以适合您的使用 我在一个扩展 View 的画布类中声明了这个方法,真的希望这对你也有帮助,对不起我的英语

【讨论】:

【参考方案3】:

我也面临这个问题..现在它工作正常,因为我正在使用库

 **compile 'com.soundcloud.android:android-crop:1.0.1@aar'**

公共 Uri mImageCaptureUri=null;

从图库中选择图片

Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, PICK_FROM_FILE);

这是添加到 onActivityResult 方法

 //call this line after crop it 

   if(requestCode == Crop.REQUEST_CROP)
        handleCrop(resultCode, data);
    

  case PICK_FROM_FILE:

            mImageCaptureUri = data.getData();
            beginCrop(mImageCaptureUri);
            break;


private void beginCrop(Uri source) 
    Uri destination = Uri.fromFile(new File(getCacheDir(), "cropped"));
    Crop.of(source, destination).asSquare().start(this);

private void handleCrop(int resultCode, Intent result) 

    if (resultCode == RESULT_OK) 
       // mImage.setImageURI(Crop.getOutput(result));
        Picasso.with(SettingsActivity.this).load(Crop.getOutput(result)).transform(new RoundTransform()).into(mImage);
        mImageCaptureUri=Crop.getOutput(result);
        getImageUri(mImageCaptureUri);     //this method uri stored to sdcard
     else if (resultCode == Crop.RESULT_ERROR) 
        Toast.makeText(this, Crop.getError(result).getMessage(), Toast.LENGTH_SHORT).show();
    

【讨论】:

【参考方案4】:

如果用户要求拍照:

 Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                        if (takePictureIntent.resolveActivity(BaseActivity.this.getPackageManager()) != null) 
                            File photoFile = null;
                            try 
                                photoFile = ImageVideoUtil.createImageFile();
                             catch (IOException ex) 
                                ex.printStackTrace();
                            
                            if (photoFile != null) 
                                imagePath = Uri.fromFile(photoFile);
                                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imagePath);
                                startActivityForResult(takePictureIntent, ApplicationConstants.REQUEST_CAMERA);
                            
                        

如果用户要求从相机中选择,您可以使用:

Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                        startActivityForResult(intent, ApplicationConstants.REQUEST_GALLERY);
                        dialog.dismiss();

在您的活动结果中,您可以获取 uri 并使用它:

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
        super.onActivityResult(requestCode, resultCode, data);
        BaseFragment fragment = (BaseFragment) getSupportFragmentManager().findFragmentById(R.id.fl_main);
        if (resultCode == RESULT_OK) 
            Bitmap bitmap = null;
            switch (requestCode) 
                case ApplicationConstants.REQUEST_CAMERA:
                    if (imagePath != null && fragment instanceof PhotoView) 
                        bitmap = Tools.fromGallery(this, imagePath);
                        if (bitmap != null) 
                            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth() / 2, bitmap.getHeight() / 2);
                            ((PhotoView) fragment).onPhotoSet(bitmap);
                        
                    
                    break;

                case ApplicationConstants.REQUEST_GALLERY:
                    Uri uri = data.getData();
                    imagePath = uri;
                    bitmap = Tools.fromGallery(this, uri);
                    if (bitmap != null && fragment instanceof PhotoView) 
                        bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth() / 2, bitmap.getHeight() / 2);
                        ((PhotoView) fragment).onPhotoSet(bitmap);
                    
                    break;

                case ApplicationConstants.REQUEST_VIDEO:
                    if (fragment instanceof VideoView) 
                        ((VideoView) fragment).onVideoSelected(videoPath);
                    
                    break;
            

        
    

这里是 ImageVideoUtil 类,它可以帮助您裁剪、缩放、保存和读取图像视频操作。

public class ImageVideoUtil 

    public static void startCameraIntent(Activity activity) 

        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        // Ensure that there's a camera activity to handle the intent
        if (takePictureIntent.resolveActivity(activity.getPackageManager()) != null) 
            // Create the File where the photo should go
            File photoFile = null;
            try 
                photoFile = createImageFile();
             catch (IOException ex) 
                // Error occurred while creating the File
                ex.printStackTrace();
            
            // Continue only if the File was successfully created
            if (photoFile != null) 
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
                activity.startActivityForResult(takePictureIntent, ApplicationConstants.REQUEST_CAMERA);
            
        
    

    public static File createImageFile() throws IOException 
        // Create an image file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "SnapSense" + timeStamp + "_";
        File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(imageFileName, /* prefix */
                ApplicationConstants.DEFAULT_IMGAE_SUFFIX, /* suffix */
                storageDir /* directory */
        );

        // Save a file: path for use with ACTION_VIEW intents
        return image;
    

    public static File createVideoFile() throws IOException 
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "SnapSense" + timeStamp + "_";
        File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
        File video = File.createTempFile(imageFileName, /* prefix */
                ApplicationConstants.DEFAULT_VIDEO_SUFFIX, /* suffix */
                storageDir /* directory */
        );

        // Save a file: path for use with ACTION_VIEW intents
        return video;
    

    public static Bitmap decodeBitmap(Bitmap bmp) 
        try 
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            bmp.compress(Bitmap.CompressFormat.PNG, 50, out);
            return BitmapFactory.decodeStream(new ByteArrayInputStream(out.toByteArray()));
         catch (Exception ex) 
            ex.printStackTrace();
        
        return bmp;
    

最后还有一些其他的静态方法可以帮助你:

public static Bitmap fromGallery(Context context, final Uri selectedImageUri) 
        try 
            Bitmap bm = MediaStore.Images.Media.getBitmap(context.getContentResolver(), selectedImageUri);
            ExifInterface exif = new ExifInterface(selectedImageUri.getPath());
            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
            int angle = 0;
            switch (orientation) 
                case ExifInterface.ORIENTATION_ROTATE_90:
                    angle = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    angle = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    angle = 270;
                    break;
                default:
                    angle = 0;
                    break;
            
            Matrix mat = new Matrix();
            if (angle == 0 && bm.getWidth() > bm.getHeight())
                mat.postRotate(90);
            else
                mat.postRotate(angle);

            return Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), mat, true);

         catch (IOException e) 
            e.printStackTrace();
         catch (OutOfMemoryError oom) 
            oom.printStackTrace();
        
        return null;
    

    public static String getRealPathFromURI(Activity activity, Uri contentUri) 
        String[] proj = MediaStore.Images.Media.DATA;
        Cursor cursor = activity.managedQuery(contentUri, proj, null, null, null);
        int column_index = cursor
                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    

希望我的代码对您有所帮助。祝你好运。

【讨论】:

【参考方案5】:

我在 Nexus 中遇到了同样的问题。我使用了Android Image Cropper,它非常轻巧灵活。

编译'com.theartofdev.edmodo:android-image-cropper:2.2.+'

【讨论】:

【参考方案6】:

每个版本都有自己的路径获取方式: 试试这个方法将适用于每个版本,它为我工作:

public static String getRealPathFromURI(final Context context, final Uri uri) 

    final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

    // DocumentProvider
    if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) 
        // ExternalStorageProvider
        if (isExternalStorageDocument(uri)) 
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            if ("primary".equalsIgnoreCase(type)) 
                return Environment.getExternalStorageDirectory() + "/"
                        + split[1];
            

            // TODO handle non-primary volumes
        
        // DownloadsProvider
        else if (isDownloadsDocument(uri)) 

            final String id = DocumentsContract.getDocumentId(uri);
            final Uri contentUri = ContentUris.withAppendedId(
                    Uri.parse("content://downloads/public_downloads"),
                    Long.valueOf(id));

            return getDataColumn(context, contentUri, null, null);
        
        // MediaProvider
        else if (isMediaDocument(uri)) 
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            Uri contentUri = null;
            if ("image".equals(type)) 
                contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
             else if ("video".equals(type)) 
                contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
             else if ("audio".equals(type)) 
                contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
            

            final String selection = "_id=?";
            final String[] selectionArgs = new String[]split[1];

            return getDataColumn(context, contentUri, selection,
                    selectionArgs);
        
    
    // MediaStore (and general)
    else if ("content".equalsIgnoreCase(uri.getScheme())) 
        return getDataColumn(context, uri, null, null);
    
    // File
    else if ("file".equalsIgnoreCase(uri.getScheme())) 
        return uri.getPath();
    

    return null;

【讨论】:

以上是关于从相机和图库上传在所有版本中都无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

在 webview 中从相机上传图像不起作用

在 WebView 中从相机或图库上传图像

从相机中选择图像时无法交付结果,但从图库中选择图像时没有问题

从android中的画廊和相机中捕获图像

从图库/相机中选择后,图像尺寸变化[增加/减少]?

文件上传选项以从相机拍摄图像或从图库中选择不适用于 Mozilla Firefox 中的 Web 应用程序