android - 如何从相机捕获图像并上传到 Retrofit multipart?
问题描述
我正在执行以下操作以从相机捕获图像并通过改造多部分图像上传将其上传到 Web 服务,但我在将位图转换为图像文件以便能够填充改造 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;
}
它运作良好。
推荐阅读
- sql-server - 对所有数据库执行查询
- php - 登录奏鸣曲系统用户
- oracle - Maven soa 使用 soa 插件进行测试
- asp.net - 如何在 Web 应用程序中创建新的 ASP.NET Web 表单的超链接
- python - python - 如何使用正则表达式来分隔输入
- android - android不能添加一个信号
- php - PHP 7 - error_log 中没有记录异常。error_log 根本没有得到处理
- spring - 使用 RabbitMQ 的 Spring Cloud Stream 消费者的多个 bindingRoutingKey
- c - 在两个哈希表之间移动项目
- javascript - jQuery find vs id 属性