android7.0适配

使用FileProvider

使用FileProvider的大致步骤如下: 

第一步:在manifest清单文件中注册provider

<!--注册provider    赋予Uri权限(grantUriPermissions)-->
<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.cjy.fileprovider"
    android:grantUriPermissions="true"
    android:exported="false">

    <!--设置要分享的路径-->
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

第二步:指定共享的目录

为了指定共享的目录我们需要在资源(res)目录下创建一个xml目录,然后创建一个名为“file_paths”(名字可以随便起,只要和在manifest注册的provider所引用的resource保持一致即可)的资源文件

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <paths>
        <external-path path="cjy" name="myFile" />
    </paths>
</PreferenceScreen>

注:上述代码中path="",是有特殊意义的,它代码根目录,也就是说你可以向其它的应用共享根目录及其子目录下任何一个文件了,如果你将path设为path="pictures", 那么它代表着根目录下的pictures目录(eg:/storage/emulated/0/pictures),如果你向其它应用分享pictures目录范围之外的文件是不行的。

1.调用系统相机拍照

以调用系统相机拍照为例,我们需要将上述拍照代码修改为如下:

private Uri imageUri;
public void useCamera(){
   Intent intent = new Intent(Intent.ACTION_VIEW);
   intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);//设置Action为拍照
    intent.putExtra("camerasensorytpe", 2); // 调用前置摄像头
    intent.putExtra("autofocus", true); // 自动对焦
    intent.putExtra("fullScreen", false); // 全屏
    intent.putExtra("showActionIcons", false);
    File file=new File(Environment.getExternalStorageDirectory(), "/cjy/"+System.currentTimeMillis() + ".jpg");
    if (!file.getParentFile().exists())file.getParentFile().mkdirs();
    // 判断是否是7.0
    if(Build.VERSION.SDK_INT >= 24){
        // 适配android7.0 ,不能直接访问原路径
        // 需要对intent 授权
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        imageUri = FileProvider.getUriForFile(MainActivity.this, "com.example.administrator.myapplication3.fileprovider", file);//通过FileProvider创建一个content类型的Uri
    } else {
        imageUri = Uri.fromFile(file);
    }
    intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);//将拍取的照片保存到指定URI
    startActivityForResult(intent,1006);
}

上述代码中主要有两处改变: 

1. 将之前Uri的scheme类型为file的Uri改成了有FileProvider创建一个content类型的Uri。 

2. 添加了intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);来对目标应用临时授权该Uri所代表的文件。

2.裁切照片
File file=new File(Environment.getExternalStorageDirectory(), "/cjy/"+System.currentTimeMillis() + ".jpg");
if (!file.getParentFile().exists())file.getParentFile().mkdirs();
Uri outputUri = FileProvider.getUriForFile(context, "com.cjy.fileprovider",file);
Uri imageUri=FileProvider.getUriForFile(context, "com.cjy.fileprovider", new File("/storage/emulated/0/temp/1474960080319.jpg");//通过FileProvider创建一个content类型的Uri
Intent intent = new Intent("com.android.camera.action.CROP");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(imageUri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", true); // no face detection

startActivityForResult(intent,1008);

3.获取文件的Uri

Intent i = new Intent(Intent.ACTION_VIEW);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// 判断是否是7.0
if(Build.VERSION.SDK_INT >= 24){
    // 适配android7.0 ,不能直接访问原路径
    // 需要对intent 授权
    i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    i.setDataAndType(FileProvider.getUriForFile(context, context.getPackageName() + ".fileProvider",new File(filePath)),"application/vnd.android.package-archive");
}
else{
    i.setDataAndType(Uri.fromFile(new File(filePath)), "application/vnd.android.package-archive");
}
context.startActivity(i);

Android 7.0 应用了以下优化措施:

  • 在 Android 7.0上 应用不会收到 CONNECTIVITY_ACTION 广播,即使你在manifest清单文件中设置了请求接受这些事件的通知。 但,在前台运行的应用如果使用BroadcastReceiver 请求接收通知,则仍可以在主线程中侦听 CONNECTIVITY_CHANGE。
  • 在 Android 7.0上应用无法发送或接收 ACTION_NEW_PICTURE 或ACTION_NEW_VIDEO 类型的广播。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值