7.0 Build.VERSION_CODES.N 24

为什么要适配

在7.0中 ,Uri.from(file),可能会触发FileUriExposedException
和动态权限一样,如果target选择24以下是不需要适配的,但还是应该尽早适配

解决办法:在24及以上,使用content:// 替代 file:// (Uri.from(file))

适配步骤

1.在res下,新建一个xml目录,在其中创建一个任意名字的xml文件,如file_provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external"
path="." />
</paths>

xml说明

external-path  等同于    Environment.getExternalStorageDirectory()
如果将path设置为path=“pic”,则共享的文件限制为/storage/emulated//pic/
为空,则共享文件目录为storage/emulated// <root-path/> 代表设备的根目录new File("/");
<files-path/> 代表context.getFilesDir()
<cache-path/> 代表context.getCacheDir()
<external-path/> 代表Environment.getExternalStorageDirectory()
<external-files-path>代表context.getExternalFilesDirs()
<external-cache-path>代表context.getExternalCacheDirs()

2.在Manifest文件中注册FileProvider对象

<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true"> <meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_paths"/>
</provider>

3.修改java代码,场景拍照,裁剪,安装apk

 fp=context.getPackageName()+".fileprovider";

3.1 拍照

imgPath = FileUtil.generateImgePath();
File imgFile = new File(imgPath); //设置拍照后的图片的保存位置
Log.i("TAG", imgFile.getAbsolutePath());
Uri imgUri = null;
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//通过FileProvider创建一个content类型的Uri
imgUri = FileProvider.getUriForFile(activity, fp, imgFile);
//添加这一句表示对目标应用临时授权该Uri所代表的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
imgUri = Uri.fromFile(imgFile);
} intent.putExtra(MediaStore.EXTRA_OUTPUT, imgUri); final Uri uri = imgUri;
activity.startActivityForResult(intent, new CallBackIntent() {
@Override
public void onResult(Intent data) {
if (data == null || data.getData() == null)
// ToastUtils.startShort(activity, "拍照数据返回为空");
Log.i("TAG", "拍照数据返回为空"); startPhotoZoom(uri, activity, new IntentCallBack() {
@Override
public void onIntent(Intent intent) {
callBack.onBitmap(getImageView(intent));
}
});
}
});

imgPath,就是拍照后图片保存的路径

3.2 裁剪

//适配7.0的uri,(文件uri转化为ContentUri)
public Uri getImageContentUri(Context context, File imageFile) {
String filePath = imageFile.getAbsolutePath();
Cursor cursor = context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[] { MediaStore.Images.Media._ID },
MediaStore.Images.Media.DATA + "=? ",
new String[] { filePath }, null); if (cursor != null && cursor.moveToFirst()) {
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 (imageFile.exists()) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, filePath);
return context.getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} else {
return null;
}
}
}

如果是由相机或者相册之后调用裁减,无需转化uri
如果是单独使用裁减功能,则需要利用上述方法进行转化

private void cropPicture(Uri uri) {
Intent innerIntent = new Intent("com.android.camera.action.CROP");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//添加这一句表示对目标应用临时授权该Uri所代表的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
innerIntent.setDataAndType(uri, "image/*");
innerIntent.putExtra("crop", "true"); //不是1比1 主要是为了适配华为手机一比一时,裁减是圆形的
innerIntent.putExtra("aspectX", );
innerIntent.putExtra("aspectY", ); innerIntent.putExtra("outputX", );
innerIntent.putExtra("outputY", );
innerIntent.putExtra("return-data", true);
innerIntent.putExtra("scale", true); activity.startActivityForResult(intent, new CallBackIntent() {
@Override
public void onResult(Intent data) {
callBack.onIntent(data);
//裁减后的图片
//Bitmap bitmap = data.getParcelableExtra("data");
}
}); }

3.3 安装apk

private void installAPK(UpdateInfo updateInfo) {
File apkfile = new File(mSavePath, updateInfo.getClientVersionName());
if (!apkfile.exists()) {
return;
}
String cmd = "chmod 777 " + apkfile.toString();
try {
Runtime.getRuntime().exec(cmd);
} catch (Exception e) {
e.printStackTrace();
}
// 通过Intent安装APK文件
Intent i = new Intent(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= ) { //适配安卓7.0
i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri apkFileUri = FileProvider.getUriForFile(context.getApplicationContext(), fp, apkfile);
i.setDataAndType(apkFileUri, "application/vnd.android.package-archive");
} else {
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setDataAndType(Uri.parse("file://" + apkfile.toString()),"application/vnd.android.package-archive");
}
context.startActivity(i);
//关闭当前程序
int pid = android.os.Process.myPid();
android.os.Process.killProcess(pid);
}

7.0 FileProvide适配的更多相关文章

  1. Android 6.0权限适配

    targetSdkVersion 23以上,必须适配新的权限模式 安卓6.0及之后,权限分为三类  1.不涉及隐私的正常权限,如innernet2.危险权限 3.特殊权限 system_alert_w ...

  2. Android项目实战(四十九):Andoird 7.0+相机适配

    解决方案类似: Android项目实战(四十):Andoird 7.0+ 安装APK适配 解决方法: 一.在AndroidManifest.xml 文件中添加 四大组件之一的 <provider ...

  3. 【Android】我有放入Icon到mipmap,但不显示,只显示安卓机器人Icon(Android 8.0 图标适配)

    首先,放上别人写的博客,而我自己的博客,只会写大概思路,给自己留给备忘 https://blog.csdn.net/guolin_blog/article/details/79417483 其实会发生 ...

  4. GreenDao2.2升级GreenDao3.0的适配之路

    前言.为什么要升级到Greendao3.0? 1. 多人开发 以往的数据库建表建Dao等操作要新开一个module,在统一的地方管理数据库建表,现在可以直接写Entity.多人开发时自己管自己的Ent ...

  5. android9.0系统适配遇到的问题

    一.apk在9.0以下的系统上安装运行,没有问题.但是在9.0系统上运行会弹出一个框 解决办法: private void closeAndroidPDialog() { try { Class aC ...

  6. [转]cocos2d-js 3.0 屏幕适配方案 分辨率适应

    首先介绍一个api和相应的参数: cc.view.setDesignResolutionSize(1024, 768, cc.ResolutionPolicy.FIXED_WIDTH); 这里设置游戏 ...

  7. cocos2d-js 3.0 屏幕适配方案 分辨率适应

    首先介绍一个api和相应的参数: cc.view.setDesignResolutionSize(1024, 768, cc.ResolutionPolicy.FIXED_WIDTH); 这里设置游戏 ...

  8. Win10《芒果TV》商店版更新v3.1.4.0:适配Xbox手柄B键后退、手机支持暗色主题不伤眼

    在双十一全球剁手节.光棍节欢庆之际,<芒果TV>UWP版迅速更新v3.1.4版,适配Xbox手柄B键全局后退,支持手机切换暗色主题,优化并解决启动卡顿等问题. 芒果TV UWP V3.1. ...

  9. Android权限管理之RxPermission解决Android 6.0 适配问题

    前言: 上篇重点学习了Android 6.0的运行时权限,今天还是围绕着Android 6.0权限适配来总结学习,这里主要介绍一下我们公司解决Android 6.0权限适配的方案:RxJava+RxP ...

随机推荐

  1. c++中char类型字符串拼接以及int类型转换为char类型 && 创建文件夹

    如下所示: #include <iostream> #include <windows.h> #include <cstring> using namespace ...

  2. Python+selenium+webdriver 安装与环境配置

    1.python安装:访问python.org/download,下载最新版本,安装过程与其他windows软件类似.记得下载后设置path环境变量,然后Windows命令行就可以调用: 2.Sele ...

  3. Python高级特性:迭代器和生成器

    在Python中,很多对象都是可以通过for语句来直接遍历的,例如list.string.dict等等,这些对象都可以被称为可迭代对象.至于说哪些对象是可以被迭代访问的,就要了解一下迭代器相关的知识了 ...

  4. 实现一个简易的vue的mvvm(defineProperty)

    这是一个最近一年很火的面试题,很多人看到这个题目从下手,其实查阅一些资料后,简单的模拟还是不太难的: vue不兼容IE8以下是因为他的实现原理使用了 Object.defineProperty 的ge ...

  5. org.apache.commons.lang.StringUtils的常用方法

    org.apache.commons.lang.StringUtils是apache的commons-lang-x.x.jar下的包,里面包含很多字符串操作方法, 官网(http://commons. ...

  6. Quartz2D简单图形

    这些天一直准备学绘图和核心动画这块,可一直找不到合适系统的教材,没有大纲,比较纠结,在网上搜了又搜,看着其他的博文写的 第一遍来学习绘制简单的图形 // 若想利用Quartz 2D在View上绘制信息 ...

  7. C# Azure 设置云端应用程序的默认时间

    在微软云Azure中,应用程序(website)的默认时间是按照美国UTC的时间的. 例如,在应用程序中获取DateTime.Now,的时候,是获取UTC的时间,不是中国的时间. 所以我们开始在这里设 ...

  8. 当DataTable的列名遇上特殊字符"["和"]"时

    刚才有看到一个问题http://bbs.csdn.net/topics/390781072.是在DataTable获取某列最小值,但是在动态生生DataTable时,列名有遇上特特殊字符"[ ...

  9. asp.net core webapi 使用ef 对mysql进行增删改查,并生成Docker镜像构建容器运行

    1.构建运行mysql容器,添加数据库user 参考Docker创建运行多个mysql容器,地址 http://www.cnblogs.com/heyangyi/p/9288402.html 添加us ...

  10. Git(二)_基本命令

    0. 开始查看所有配置:git config --listgit config --global user.name "runoob"git config --global use ...