一.简介
Android 7.0 除了提供诸多新特性和功能外,还对系统和 API 行为做出了各种变更。本文重点介绍您应该了解并在开发应用时加以考虑的一些主要变更。
二.主要的变化
Android 7.0都有哪些变化呢,我们作为开发者需要注意什么呢。下面一一讲解常用的几个变化。
<1> 共享文件(访问系统相机)
(1) 简介
对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode API 政策禁止在您的应用外部公开 file:// URI。如果一项包含文件 URI 的 intent 离开您的应用,则应用出现故障,并出现 FileUriExposedException 异常。
要在应用间共享文件,您应发送一项 content:// URI,并授予 URI 临时访问权限。进行此授权的最简单方式是使用 FileProvider 类。如需了解有关权限和共享文件的详细信息,请参阅共享文件。
(2) 代码
【1】清单文件
<provider
android:name="androidx.core.content.FileProvider" androidx包
android:name="android.support.v4.content.FileProvider" v4包
android:authorities="com.example.test.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepath" />
</provider>
<!-- 相机权限 -->
<uses-permission android:name="android.permission.CAMERA"/>
<!--读写存储卡权限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.PERMISSIONS_STORAGE"/>
【2】 项目配置
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external_files"
path="."/>
</paths>
【3】 相关代码
package com.wjn.viewlistdemo.activity.fragment;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.Nullable;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.wjn.viewlistdemo.R;
import java.io.File;
import java.util.Calendar;
import java.util.Locale;
public class MyActivity extends AppCompatActivity {
public static final int REQUEST_CODE_TAKE_PHOTO = 1;
public static String PICTURTemporary_Path = "ViewListDemo/Temporary/";//图片临时文件
private String filePath;
private TextView textView;
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
initView();
}
/**
* 初始化各种View
*/
private void initView() {
textView = findViewById(R.id.activity_my_textview);
imageView = findViewById(R.id.activity_my_imageview);
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
takePhoto();
}
});
}
/**
* 手机拍照
*/
public void takePhoto() {
if (isSdCardExist()) {
Uri photoURI = null;
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
//创建一个File
String name = String.valueOf(System.currentTimeMillis());
filePath = createAvatarPathPicture(name);
File photoFile = new File(filePath);
Log.d("MyActivity", "name----:" + name);
Log.d("MyActivity", "filePath----:" + filePath);
if (photoFile != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//如果是7.0及以上的系统使用FileProvider的方式创建一个Uri
photoURI = FileProvider.getUriForFile(MyActivity.this, "com.wjn.viewlistdemo.fileprovider", photoFile);
takePictureIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
takePictureIntent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
} else {
//7.0以下使用这种方式创建一个Uri
photoURI = Uri.fromFile(photoFile);
}
//将Uri传递给系统相机
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_CODE_TAKE_PHOTO);
}
}
} else {
Toast.makeText(MyActivity.this, "内存卡不可用", Toast.LENGTH_LONG).show();
}
}
/**
* 内存卡是否可用
*/
private boolean isSdCardExist() {
return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
}
/**
* 获取sd卡根路径
*/
private String getTheRootDirectory() {
String result = "";
if (isSdCardExist()) {
result = Environment.getExternalStorageDirectory() + "/";
}
return result;
}
/**
* 保存图片的文件夹
*/
private String createAvatarPathPicture(String userName) {
String dir = getTheRootDirectory() + PICTURTemporary_Path;
File destDir = new File(dir);
if (!destDir.exists()) {
destDir.mkdirs();
}
File file;
if (userName != null) {
file = new File(dir, userName + ".png");
} else {
file = new File(dir, new DateFormat().format("yyyy_MMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".png");
}
return file.getAbsolutePath();
}
/**
* onActivityResult
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_TAKE_PHOTO && resultCode == RESULT_OK) {
if (!TextUtils.isEmpty(filePath)) {
File file = new File(filePath);
Uri uri = Uri.fromFile(file);
String path = uri.getPath();
if (!TextUtils.isEmpty(path)) {
Bitmap bitmap = BitmapFactory.decodeFile(path);
imageView.setImageBitmap(bitmap);
Log.d("MyActivity", "设置Bitmap");
}
}
}
}
}
注意:一般相机获取的图片上传服务器成功后,要把临时存储的图片删除,这样对于用户想的好接受。
附:权限相关:https://blog.csdn.net/weixin_37730482/article/details/71158257
附:官网:https://developer.android.google.cn/about/versions/nougat