【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 {// 从图片路径转为Uripublic 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() {@Overridepublic void onFailure(Call call, IOException e) {Log.d(TAG,"onFailure --> " + e.toString());}@Overridepublic 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());}}});}
测试上传成功: