简体   繁体   中英

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.

 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'

@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

  <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. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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