android棉花糖及更高版本的图片上传问题

时间:2018-08-07 04:41:18

标签: android retrofit uri

我是android开发领域的新手。我正在做一个项目,必须上传带有图像的数据。我开发了一个在Android 5.1.1及以下版本中运行正常的应用,但在6.0及以上版本中崩溃。我正在使用改造2.4和房间数据库。我将存储图像URI的真实路径,然后在一个单独的过程中,我将从房间数据库中上传图像和数据读取。

这是保存图像的路径代码。

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();
    }
}

此功能,其中URI被转换为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;
}

在这里,我正在将realpath转换为URI到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);

该应用程序一直崩溃...请有人帮我...

2 个答案:

答案 0 :(得分:1)

如果您有文件路径,则可以直接使用它。

reqFile = RequestBody.create(MediaType.parse(fileType), file)
MultipartBody.Part.createFormData(keyName, file.name, reqFile)

答案 1 :(得分:0)

尝试使用FileProvider获取图像的URI。适用于所有版本的android。

要遵循的步骤:

1)将依赖项添加到构建文件compile 'com.android.support:support-v4:<version>'

2)在xml资源文件夹中创建一个xml文件file_provider_paths.xml并添加

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

3)在您的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)获取共享文件的Uri

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

以下是带有kotlin的简单Rx代码:

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 = {}
                )
    }