如何从相机捕获图像并上传到 Retrofit multipart?

How to capture image from camera and upload to Retrofit multipart?

我正在执行以下操作以从相机捕获图像并通过改造多部分图像上传将其上传到 Web 服务,但我在将位图转换为图像文件以便能够填充图像文件的多部分参数时遇到问题改造网络服务调用。我已经使用 URI 将位图从相机转换为文件,但我在该函数中遇到了空指针异常。

Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK)
    {
        final Bitmap photo = (Bitmap) data.getExtras().get("data");

        // CALL THIS METHOD TO GET THE URI FROM THE BITMAP
        Uri tempUri = getImageUri(getActivity(), photo);

        // CALL THIS METHOD TO GET THE ACTUAL PATH
        File file = new File(getRealPathFromURI(tempUri));

        MyWebService webService =
                MyWebService.retrofit.create(MyWebService.class);

        MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", file.getName(), RequestBody.create(MediaType.parse("image/*"), file));

        Call<com.syamantak.footsteps.models.response.Response> call = webService.set_profile_photo(filePart, "Bearer " + MainActivity.api_token);
        MainActivity.setProgressBarVisible();
        call.enqueue(new Callback<com.syamantak.footsteps.models.response.Response>() {
            @Override
            public void onResponse(Call<com.syamantak.footsteps.models.response.Response> call, Response<com.syamantak.footsteps.models.response.Response> response) {
                MainActivity.setProgressBarInVisible();
                com.syamantak.footsteps.models.response.Response jsonResponse = response.body();
                selfieImage.setImageBitmap(photo);
                Toast.makeText(getActivity(), jsonResponse.getMessage(), Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onFailure(Call<com.syamantak.footsteps.models.response.Response> call, Throwable t) {
                t.getLocalizedMessage();
            }
        });
    }
}


public Uri getImageUri(Context inContext, Bitmap inImage) {
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
    String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
    return Uri.parse(path);
}

public String getRealPathFromURI(Uri uri) {
    String path = "";
    if (getActivity().getContentResolver() != null) {
        Cursor cursor = getActivity().getContentResolver().query(uri, null, null, null, null);
        if (cursor != null) {
            cursor.moveToFirst();
            int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
            path = cursor.getString(idx);
            cursor.close();
        }
    }
    return path;
}

以下是我的清单文件

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.syamantak.footsteps">

<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true" />
<uses-feature android:name="android.hardware.camera"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET"/>

我遇到以下错误

E/MediaStore: Failed to insert image
java.lang.SecurityException: Permission Denial: writing com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=28108, uid=10237 requires android.permission.WRITE_EXTERNAL_STORAGE, or grantUriPermission()

java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=67424, result=-1, data=Intent { act=inline-data (has extras) }} to activity {com.syamantak.footsteps/com.syamantak.footsteps.activities.MainActivity}: java.lang.NullPointerException: uriString

我做错了什么?

我得出以下解决方案

        final Bitmap photo = (Bitmap) data.getExtras().get("data");
        File file = savebitmap(photo);

        MyWebService webService =
                MyWebService.retrofit.create(MyWebService.class);

        MultipartBody.Part filePart = MultipartBody.Part.createFormData("photo", file.getName(), RequestBody.create(MediaType.parse("image/*"), file));

        Call<com.syamantak.footsteps.models.response.Response> call = webService.set_profile_photo(filePart, "Bearer " + MainActivity.api_token);
        MainActivity.setProgressBarVisible();
        call.enqueue(new Callback<com.syamantak.footsteps.models.response.Response>() {
            @Override
            public void onResponse(Call<com.syamantak.footsteps.models.response.Response> call, Response<com.syamantak.footsteps.models.response.Response> response) {
                MainActivity.setProgressBarInVisible();
                com.syamantak.footsteps.models.response.Response jsonResponse = response.body();
                selfieImage.setImageBitmap(photo);
                Toast.makeText(getActivity(), jsonResponse.getMessage(), Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onFailure(Call<com.syamantak.footsteps.models.response.Response> call, Throwable t) {
                t.getLocalizedMessage();
            }
        });

和以下将位图转换为文件的函数

private File savebitmap(Bitmap bmp) {
    String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
    OutputStream outStream = null;
    // String temp = null;
    File file = new File(extStorageDirectory, "temp.png");
    if (file.exists()) {
        file.delete();
        file = new File(extStorageDirectory, "temp.png");

    }

    try {
        outStream = new FileOutputStream(file);
        bmp.compress(Bitmap.CompressFormat.PNG, 100, outStream);
        outStream.flush();
        outStream.close();

    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
    return file;
}

运行良好。