简体   繁体   English

如何从相机或图库中获取图像并上传到 Android Q 中的服务器?

[英]How to get image from camera or gallery and upload to server in Android Q?

I am trying to get an image from the camera or gallery to upload on the server.我正在尝试从相机或图库中获取图像以上传到服务器上。 My code is working perfectly in Android 9 or lower but I cannot able to access the image path in Android 10. I don't know much about Android 10's Scoped Storage, Please review my code and help.我的代码在 Android 9 或更低版本中运行良好,但我无法在 Android 10 中访问图像路径。我对 Android 10 的范围存储不太了解,请查看我的代码并提供帮助。

 private void selectImage(Context context, final int cameraRequestCode, final int galleryRequestCode) {

    if (!hasPermissions(context, PERMISSIONS)) {
        ActivityCompat.requestPermissions(requireActivity(), PERMISSIONS, PERMISSION_ALL);
    } else {
        final CharSequence[] options = {"Take Photo", "Choose from Gallery", "Cancel"};

        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle("Choose your profile picture");

        builder.setItems(options, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int item) {

                if (options[item].equals("Take Photo")) {
                   /* Intent takePicture = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                    startActivityForResult(takePicture, cameraRequestCode);*/
                    Uri outputFileUri = Uri.fromFile(sdImageMainDirectory);

                    Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);

                    startActivityForResult(intent, cameraRequestCode);

                } else if (options[item].equals("Choose from Gallery")) {
                    Intent pickPhoto = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                    startActivityForResult(pickPhoto, galleryRequestCode);

                } else if (options[item].equals("Cancel")) {
                    dialog.dismiss();
                }
            }
        });
        builder.show();
    }
}

public File convertBitmaptoFile(Bitmap bitmap, String filename) throws IOException {
    File f = new File(requireContext().getCacheDir(), filename);
    f.createNewFile();


    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100 /*ignored for PNG*/, bos);
    byte[] bitmapdata = bos.toByteArray();


    FileOutputStream fos = new FileOutputStream(f);
    fos.write(bitmapdata);
    fos.flush();
    fos.close();
    return f;

}

'Here is my onActivity code' '这是我的 onActivity 代码'

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode != RESULT_CANCELED) {
        switch (requestCode) {
            case 0:

                try {
                    String millisecond = String.valueOf(Calendar.getInstance().getTimeInMillis());
                   // logo_file = new File(String.valueOf(convertBitmaptoFile(fileToBitmap(sdImageMainDirectory.getPath()), "IMAGE_" + millisecond + ".jpg")));

                   // img_logo.setImageURI(Uri.parse(logo_file.getAbsolutePath()));
                    img_logo.setImageURI(Uri.parse(getPath(Uri.fromFile(logo_file = new File(String.valueOf(convertBitmaptoFile(fileToBitmap(sdImageMainDirectory.getPath()), "IMAGE_" + millisecond + ".jpg")))))));
                    Log.e("logo file path","" +  logo_file.getPath());
                    Log.e("logo file absolute path","" +  logo_file.getAbsolutePath());
                } catch (IOException e) {
                    e.printStackTrace();
                }


                // fa_image.setImageURI(Uri.parse(fa_image_file.getPath()));

                break;
            case 1:
                if (resultCode == RESULT_OK && data != null) {
                    Uri selectedImage = Uri.parse(data.getData().getEncodedPath());
                    String[] filePathColumn = {MediaStore.Images.Media.DATA};
                    if (selectedImage != null) {
                        Cursor cursor = getActivity().getContentResolver().query(selectedImage,
                                filePathColumn, null, null, null);
                        if (cursor != null) {
                            cursor.moveToFirst();

                            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                            String picturePath = cursor.getString(columnIndex);
                            logo_file = new File(picturePath);
                            Log.e("IMAGE", "ja_image :" + logo_file);
                            img_logo.setImageBitmap(BitmapFactory.decodeFile(picturePath));
                            cursor.close();
                        }
                    }

                }
                break;

        }
    }
}

Have you used android:requestLegacyExternalStorage="true" in AndroidManifest.xml您是否在 AndroidManifest.xml 中使用过 android:requestLegacyExternalStorage="true"

  <application
    android:name="com.xyz"
    android:allowBackup="true"
    android:exported="false"
    android:hardwareAccelerated="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:largeHeap="true"
    android:requestLegacyExternalStorage="true"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme"
    android:usesCleartextTraffic="true"
    tools:ignore="GoogleAppIndexingWarning"
    tools:targetApi="q">

In Android 10, you cannot access image using the uri provided in onActivityResult.在 Android 10 中,您无法使用 onActivityResult 中提供的 uri 访问图像。 Try this.尝试这个。 I'm sure it will work for you.我相信它对你有用。 This is will work when you are selecting an image from gallery.当您从图库中选择图像时,这将起作用。 For taking pictures from camera photo, the approach is a little different.对于从相机照片拍摄照片,方法略有不同。

Kotlin Solution :科特林解决方案:

val imageType = contentResolver.getType(data.data!!)

data.data!!.let {
                application.contentResolver.openInputStream(it).use { inputStream ->
                    filePartImage = MultipartBody.Part.createFormData(
                        "image",     //should be same as the key of your parameter
                        "filename" + ".jpg",  // extension of file name is must
                        inputStream!!.readBytes().toRequestBody(imageType.toMediaTypeOrNull())
                    )
                }
            }

Later pass this filePartImage as your image parameter for uploading image to server.稍后将此 filePartImage 作为您的图像参数传递以将图像上传到服务器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM