Android 7.0 牛轧糖适配心得


android7.0已经出来有一段时间,确切的说是7.1已经出来有些时间了,我们开始把7.0的适配提上了日程,适配7.0的主要工作有哪些。 把targetSdkVersion,compileSdkVersion都提升到24。

牛轧糖更加注重文件与隐私的保护。 首先提示这两个模式被弃用了。

@Deprecated
public static final int MODE_WORLD_READABLE = 0x0001;

 @Deprecated
public static final int MODE_WORLD_WRITEABLE = 0x0002;

使用的话有可能报安全异常,如果不是共享的话换成MODE_PRIVATE。 给其他应用传递 file:// URI 类型的Uri,可能会导致接受者无法访问该路径。 因此,在Android7.0中尝试传递 file:// URI 会触发 FileUriExposedException。

比较常见的是调取相机拍摄照片,调取裁剪照片,应用内升级。

下面是我们调取系统相机拍摄照片

        File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES), "maoyan");
        jumpUri = Uri.fromFile(mediaStorageDir);
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, jumpUri);
        startActivityForResult(intent, PHOTO_REQUEST);

直接调用 会报android.os.FileUriExposedException,我们需要使用FileProvider。

关于FileProvider的使用

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.sankuai.moviepro.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.xml

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

jumpUri获取通过FileProvider.getUriForFile(context, “com.sankuai.moviepro.fileprovider” ,file);

    Intent intent = new Intent("com.android.camera.action.CROP");
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    intent.setDataAndType(uri, "image/*");
    // 设置裁剪
    intent.putExtra("crop", "true");
    // aspectX aspectY 是宽高的比例
    intent.putExtra("aspectX", 1);
    intent.putExtra("aspectY", 1);
    intent.putExtra("return-data", false);
    Uri newPhotoUri = ImageUtil.getMediaFileUri(new SimpleDateFormat(
            "yyyyMMdd_HHmmss").format(new Date()) + "avatar.jpg");
    if (newPhotoUri == null || TextUtils.isEmpty(newPhotoUri.getPath())) {
        ToastUtils.makeText(this, R.string.modify_user_photo_fail).show();
        return;
    }
    presenter.setImgUri(newPhotoUri);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, newPhotoUri);
    startActivityForResult(intent, PHOTO_CROP_REQUEST);

这是裁剪照片的操作第一个uri需要使用FileProvider提供的Uri而第二个输出文件则使用Uri.fromFile(outputMediaFile);

            Intent notificationIntent = new Intent();
            notificationIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            notificationIntent.setAction(Intent.ACTION_VIEW);
            notificationIntent.setDataAndType(UriUtils.getFileProviderUri(MovieProApplication.getContext(), installFile), "application/vnd.android.package-archive");
            context.startActivity(notificationIntent);

跳转安装页面的代码。也需要使用FileProvider,但是通过FileProvider提供的Uri无法直接访问到文件,内部使用到的时候需要注意(⊙o⊙)…。

牛轧糖适配的第二个主要问题就是分屏显示。Activity和Application支持 android:resizeableActivity判断是否支持分屏,默认是true



本作品由 Tony Zhang 创作,采用 CC BY-NC-SA 3.0 许可协议 进行许可。

Comments