1

I am a newbie in android development. I am doing a project where I have to upload data with an image attached. I developed an app which is working fine in android version 5.1.1 and below but crashes for version 6.0 and above. I am using retrofit 2.4 and room database. I am storing the real path of the image URI and then in a separate process, I am uploading image and data reading from room database.

here is the saving image path code.

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == SELECT_PICTURE && resultCode == RESULT_OK) {
        selectedImageUri = data.getData();
        vispic = RealPathUtils.getRealPathFromURI_API19(getContext(), selectedImageUri);
        Toast.makeText(getActivity(), vispic, Toast.LENGTH_LONG).show();
    }
}

this function where URI getting converted to RealPath

public static String getRealPathFromURI_API19(Context context, Uri uri){
    String filePath = "";
    String wholeID = DocumentsContract.getDocumentId(uri);

    // Split at colon, use second item in the array
    String id = wholeID.split(":")[1];

    String[] column = { MediaStore.Images.Media.DATA };

    // where id is equal to
    String sel = MediaStore.Images.Media._ID + "=?";

    Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
            column, sel, new String[]{ id }, null);

    int columnIndex = cursor.getColumnIndex(column[0]);

    if (cursor.moveToFirst()) {
        filePath = cursor.getString(columnIndex);
    }
    cursor.close();
    return filePath;
}

here I am converting realpath to URI to requestbody

for (int i = 0; i < ListofData.size(); i++) {
                idx = i ;
                Uri uri = Uri.fromFile(new File(ListofData.get(i).getVisit_pic()));
                imageView.setImageURI(uri);
                RequestBody requestFile = RequestBody.create(MediaType.parse("image/jpeg"), convertImageToByte(uri));
                MultipartBody.Part visit_pic = MultipartBody.Part.createFormData("visit_pic", "image.jpg", requestFile);

here the app keeps crashing...please someone help me...

2 Answers2

1

If you have file path then you can direct use it.

reqFile = RequestBody.create(MediaType.parse(fileType), file)
MultipartBody.Part.createFormData(keyName, file.name, reqFile)
Pang
  • 9,564
  • 146
  • 81
  • 122
Rashpal Singh
  • 633
  • 3
  • 13
0

Try using the FileProvider to get the URI of the image. Will work for all the versions of android.

Steps to follow:

1) Add dependency to your build file compile 'com.android.support:support-v4:<version>'

2) Create an xml file file_provider_paths.xml in xml resources folder and add

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="shared" path="shared/"/>
</paths>

3) In your ApplicationManifest.xml

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="<your provider authority>"
    android:exported="false"
    android:grantUriPermissions="true">
  <meta-data
      android:name="android.support.FILE_PROVIDER_PATHS"
      android:resource="@xml/file_provider_paths"/>
</provider>

4) Get the shared file’s Uri

Uri sharedFileUri = FileProvider.getUriForFile(this, <your provider auhtority>, sharedFile);

Here is simple Rx code with kotlin:

private val NEWS_FOLDER = File(Environment.getExternalStorageDirectory(), "FOLDER_NAME")

fun shareImage(bitmap: Bitmap) {
        Flowable.create<Uri>({ emitter ->
            if (!NEWS_FOLDER.exists())
                NEWS_FOLDER.mkdirs()
            val file = File(NEWS_FOLDER, "image_${random_id}.jpg")
            if (file.exists()) file.delete()
            file.createNewFile()
            try {
                val out = FileOutputStream(file)
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out)
                **val uri = FileProvider.getUriForFile(this, applicationContext.packageName + ".fileprovider", file)**
                emitter.onNext(uri)
                out.flush()
                out.close()
                emitter.onComplete()
            } catch (exception: Exception) {
                emitter.onError(exception)
            }
        }, BackpressureStrategy.BUFFER)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeWith(this,
                        onNext = {
                           //Get uri
                        },
                        onError = {}
                )
    }
Prithvi Bhola
  • 3,041
  • 1
  • 16
  • 32
  • "Uri uri = Uri.fromFile(new File(ListofData.get(i).getVisit_pic()));" - this is returning null object...that is the main issue – Debasish Dasgupta Aug 08 '18 at 04:11
  • @DebasishDasgupta you have to use `val uri = FileProvider.getUriForFile(this, applicationContext.packageName + ".fileprovider", file)` to get the `Uri`. Just follow the steps that I have mentioned and that will resolve your issue. – Prithvi Bhola Aug 08 '18 at 06:02