Android(安卓)7.0 之 FileProvider运用:拍照获取头像并设置
16lz
2021-01-24
FileProvider 是android 7.0 之后才有的一个东西,其目的也是加强管理碎片化严重的android文件夹,避免其内的应用随意使用手机的内存。
使用一个例子来具体实操一下,拍照获取图片,并设置到ImageView中:
把大象放到冰箱需要几个步骤?
步骤一:打开相机:
// 相机public static final int CAMERA_REQUEST_CODE = 1004;SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy_MM_dd_HH_ss");private File tempFile; // 中转的文件private Uri mImgUri;/** * 开启相机 * @param activity */ public void toCamera(Activity activity) { Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); String fileName = simpleDateFormat.format(new Date()); tempFile = new File(Environment.getExternalStorageDirectory(), fileName + ".jpg"); // 7.0 以下 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { mImgUri = Uri.fromFile(tempFile); } else { // 7.0 利用FileProvider String authority = activity.getPackageName() + ".fileprovider"; // 需要在配置文件中配置 mImgUri = FileProvider.getUriForFile(activity, authority, tempFile); // 添加权限 i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); } LogUtils.i("toCamera mImgUri = " + mImgUri); i.putExtra(MediaStore.EXTRA_OUTPUT, mImgUri); activity.startActivityForResult(i, CAMERA_REQUEST_CODE); }
步骤二:设置拍摄图片的回调:
private File uploadFile = null; @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { LogUtils.i("onActivityResult requestCode = " + requestCode); if (resultCode == Activity.RESULT_OK) { if (requestCode == CAMERA_REQUEST_CODE) { uploadFile = FileHelper.getInstance().getTempFile(); } } // 设置头像 if (uploadFile != null) { Bitmap bitmap = BitmapFactory.decodeFile(uploadFile.getPath()); iv_photo.setImageBitmap(bitmap); } super.onActivityResult(requestCode, resultCode, data); }
步骤三:设置FileProvider
小步骤1.设置xml/file_path.xml 文件
小步骤2.设置AndroidManifest文件
在Application节点中添加
其中authorities 就是上面 步骤一 中设置的 authority,包名自己设置好即可。
解释一下其中几个标签:
android:exported="false" //不允许跨进程访问
android:grantUriPermissions="true" // 步骤一种添加的flag的权限
是不是跟把大象放进冰箱的步骤一样多?哈哈哈
过程中遇到的问题:
1. 如果系统拍照的图片过大,那么直接设置进去将发生OOM
解决办法:可以看我之前的博客,进行一下图片压缩
2. URI获取不到真实地址的问题,具体是:头像如果从相册中获取的话,获取到的图片路径并非真实路径,而是如下:
/external/images/media/134216
解决办法:
1.首先通过 onActivityResult 中拿到系统返回的intent,通过intent.getData(),拿到返回的Uri
2.处理Uri并返回真实路径:
/storage/emulated/0/MagazineUnlock/magazine-unlock-01-2.3.4332-_035B5B61EAFA5DB2B9982DCA612BA53C.jpg
/** * 根据Uri获取真实的图片地址 * @param context * @param uri * @return */ public String getRealImgPathFromUri(Context context, Uri uri) { String[] proj = {MediaStore.Images.Media.DATA}; CursorLoader cursorLoader = new CursorLoader(context, uri, proj, null, null, null); Cursor cursor = cursorLoader.loadInBackground(); int columnIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATA); cursor.moveToFirst(); String path = cursor.getString(columnIndex); cursor.close(); return path; }
下面把 跳转相册 的方法,也给大家贴一下:
// 相册 public static final int ALBUM_REQUEST_CODE = 1005; /** * 跳转到相册 * * @param activity */ public void toAlbum(Activity activity) { Intent i = new Intent(Intent.ACTION_PICK); i.setType("image/*"); activity.startActivityForResult(i, ALBUM_REQUEST_CODE); }
遇到问题不要害怕,咱们见招拆招,没有解决不了的问题,如果有,那看看别人有啥好的解决办法没,skr~~
更多相关文章
- 基于WiEngine游戏引擎--背景移动
- Android中对于Bitmap的处理
- android studio更改module名字
- Android原生应用的CTS测试步骤
- 【Android开发】基本组件-图像视图
- 新浪微博客户端源码 android
- Android中Gallery图片与视频选择冲突的原因
- android bitmap compress(图片压缩)
- Android小案例——简单图片浏览器