Android记录一次安卓10的图片读取
Posted woodwhale
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android记录一次安卓10的图片读取相关的知识,希望对你有一定的参考价值。
【android】记录一次安卓10的图片读取
非常的难受,这个读写内容。因为Android 10没有读取sd的权限了,Android 11都恢复了部分读写权限,但是Android 10的适配是真的难受。
好在有内容提供者
这个组件,通过这个中介可以获取Uri,再从Uri转为InputSteam,之后转为byte[]
从Uri到InputSteam再到byte[]
在学okhttp post上传图片文件的时候,因为读取不了文件,所以File对象无法生成,导致RequestBody fileBody = RequestBody.create(mediaType,content);
方法中,content无法成为file对象,如何解决上传图片的问题?
查看create方法的传参:
发现可以用byte[]数组进行上传,ok那就换一种方式——从Uri到InputSteam到byte[]
我编写了一个工具类,其中的方法可以看看注释:
import ...;
public class QStorageUtils
// 从图片路径转为Uri
public static Uri imagePath2Uri(Context context, String path)
Cursor cursor = null;
try
cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA + "=? ",
new String[]path, null);
if (cursor != null && cursor.moveToFirst())
@SuppressLint("Range") int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID));
Uri baseUri = Uri.parse("content://media/external/images/media");
return Uri.withAppendedPath(baseUri, "" + id);
else
// 如果图片不在手机的共享图片数据库,就先把它插入。
if (new File(path).exists())
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, path);
return context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
else
return null;
catch (Exception e)
e.printStackTrace();
finally
closeSteam(cursor);
return null;
// Uri转为Bytes数组
public static byte[] Uri2Bytes(Context context, Uri uri)
InputStream is = null;
ByteArrayOutputStream baos = null;
try
baos = new ByteArrayOutputStream();
is = context.getContentResolver().openInputStream(uri);
byte[] buf = new byte[1024];
int len = 0;
String content = null;
while ((len=is.read(buf)) != -1)
baos.write(buf,0,len);
return baos.toByteArray();
catch (Exception e)
e.printStackTrace();
finally
closeSteam(is);
closeSteam(baos);
return new byte[0];
// 关闭流
public static void closeSteam(Closeable stream)
try
if (stream != null)
stream.close();
catch (IOException e)
e.printStackTrace();
okhttp使用post上传文件的方法如下:
@SuppressLint("Range")
private void btnDoUploadFile()
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10000,TimeUnit.MILLISECONDS)
.build();
Uri imageContentUri = QStorageUtils.imagePath2Uri(this, "/storage/emulated/0/Download/1195405.jpg");
Log.d(TAG,"pic uri --> " + imageContentUri);
byte[] content = QStorageUtils.Uri2Bytes(this,imageContentUri);
MediaType mediaType = MediaType.parse("image/jpeg");
RequestBody fileBody = RequestBody.create(mediaType,content);
RequestBody requestBody = new MultipartBody.Builder()
.addFormDataPart("file","1.jpg",fileBody)
.build();
Request request = new Request.Builder()
.url(BASE_URL + "file/upload")
.post(requestBody)
.build();
Call task = client.newCall(request);
task.enqueue(new Callback()
@Override
public void onFailure(Call call, IOException e)
Log.d(TAG,"onFailure --> " + e.toString());
@Override
public void onResponse(Call call, Response response) throws IOException
if (response.isSuccessful())
Log.d(TAG,"response code --> " + response.code());
ResponseBody body = response.body();
assert body != null;
Log.d(TAG,"response body --> " + body.string());
);
测试上传成功:
以上是关于Android记录一次安卓10的图片读取的主要内容,如果未能解决你的问题,请参考以下文章
安卓10(Android10API29)保存图片到相册DCIM/Camera
安卓10(Android10API29)保存图片到相册DCIM/Camera