非常的难受,这个读写内容。因为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()); } } }); }
测试上传成功:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)