在清单文件里添加权限和配置需<Provider>(要对Android 7.0及以后的机型适配,采用FileProvider方式。)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication">
<uses-permission android:name="android.permission.CAMERA"/>
<!-- 因为拍照需要写入文件 所以需要申请读取内存的权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.myapplication"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
配置定可共享的文件路径
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external"
path="." />
<external-files-path
name="external_files"
path="." />
<cache-path
name="cache"
path="." />
<external-cache-path
name="external_cache"
path="." />
<files-path
name="files"
path="." />
</paths>
动态申请权限及其调用拍照逻辑
package com.example.myapplication;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.StrictMode;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_PERMISSION_CODE = 10;
Button mCameraBtn;
ImageView mCameraImg;
public String imgPath = "sdcard/test/img.jpg";
Uri mUri;
private static final String TAG = "zgq";
private static int SystemCapture = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_layout);
StrictMode.VmPolicy.Builder builder =new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
builder.detectFileUriExposure();
init();
mCameraBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "onClick:=====> ");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//大于Android 6.0
if (!checkPermission()) { //没有或没有全部授权
requestPermissions(); //请求权限
}
} else {
takePhoto();;//拍照逻辑
}
}
});
}
//检查权限
private boolean checkPermission() {
//是否有权限
boolean haveCameraPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
boolean haveWritePermission = ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
return haveCameraPermission && haveWritePermission;
}
// 请求所需权限
@RequiresApi(api = Build.VERSION_CODES.M)
private void requestPermissions() {
requestPermissions(new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSION_CODE);
}
// 请求权限后会在这里回调
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_PERMISSION_CODE:
boolean allowAllPermission = false;
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {//被拒绝授权
allowAllPermission = false;
break;
}
allowAllPermission = true;
}
if (allowAllPermission) {
takePhoto();//开始拍照或从相册选取照片
} else {
Toast.makeText(this, "该功能需要授权方可使用", Toast.LENGTH_SHORT).show();
}
break;
}
}
private void init(){
mCameraBtn = (Button) findViewById(R.id.camera_btn);
mCameraImg = (ImageView) findViewById(R.id.img);
}
private void takePhoto() {
// 步骤一:创建存储照片的文件
String path = getFilesDir() + File.separator + "images" + File.separator;
File file = new File(path, "test.jpg");
if(!file.getParentFile().exists())
file.getParentFile().mkdirs();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//步骤二:Android 7.0及以上获取文件 Uri
mUri = FileProvider.getUriForFile(this, "com.example.myapplication", file);
} else {
//步骤三:获取文件Uri
mUri = Uri.fromFile(file);
}
//步骤四:调取系统拍照
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, mUri);
startActivityForResult(intent, SystemCapture);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(TAG, "onActivityResult: resultCode==>"+resultCode);
Log.i(TAG, "onActivityResult: SystemCapture==>"+SystemCapture);
if (requestCode == SystemCapture) {
if (resultCode == RESULT_OK) {
try {
mCameraImg.setImageURI(mUri);
}catch (Exception e){
e.getMessage();
}
}
}
}
}
布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="@+id/img"
android:layout_width="210dp"
android:layout_height="210dp"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_launcher_background"/>
<Button
android:id="@+id/camera_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="打开相机"
android:layout_gravity="center_horizontal|center_vertical"/>
</LinearLayout>