老规矩效果图
- 选照片
- 拍照
- 效果图
- 布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<Button
android:id="@+id/chooseLocalImage"
android:text="点击选择本地照片"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ImageView
android:id="@+id/Image_message"
android:layout_width="150dp"
android:layout_height="150dp"
/>
<Button
android:id="@+id/take_photo_message"
android:text="点击拍照"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ImageView
android:id="@+id/Image2_message"
android:layout_width="150dp"
android:layout_height="150dp"
/>
</LinearLayout>
注意 注意 注意
我是在Fragment中写的,如果是不是在Fragment中写的,getActivity()可换成 this
- 处理
/**
* 请求选择本地图片文件的请求码
*/
private static final int ACTION_CHOOSE_IMAGE = 0x201;
/**
* 请求权限的请求码
*/
private static final int ACTION_REQUEST_PERMISSIONS = 0x001;
/**
* 被处理的图片
*/
private Bitmap mBitmap = null;
private static final int PERMISSION_CAMERA_REQUEST_CODE = 0x00000012;
private boolean isAndroidQ = Build.VERSION.SDK_INT >= 29;
// 用于保存图片的文件路径,Android 10以下使用图片路径访问图片
private String mCameraImagePath;
//用于保存拍照图片的uri
private Uri mCameraUri;
//拍照的请求码
private static final int CAMERA_REQUEST_CODE = 1;
private Boolean imagestate=false; //为true 拍过一次照片了 否则是默认
/**
* 所需的所有权限信息
*/
private static String[] NEEDED_PERMISSIONS = new String[]{
Manifest.permission.CAMERA,//相机权限
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
onpen();//获取权限
}
private void onpen() {
/**
* 在选择图片的时候,在android 7.0及以上通过FileProvider获取Uri,不需要文件权限
*/
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
List<String> permissionList = new ArrayList<>(Arrays.asList(NEEDED_PERMISSIONS));
permissionList.add(Manifest.permission.READ_EXTERNAL_STORAGE);
NEEDED_PERMISSIONS = permissionList.toArray(new String[0]);
}
if (!checkPermissions(NEEDED_PERMISSIONS)) {
ActivityCompat.requestPermissions(getActivity(), NEEDED_PERMISSIONS, ACTION_REQUEST_PERMISSIONS);
} else {
//权限已经允许,点击处理
initOnclick();
}
}
/**
* 权限检查
* @param neededPermissions 需要的权限
* @return 是否全部被允许
*/
protected boolean checkPermissions(String[] neededPermissions) {
if (neededPermissions == null || neededPermissions.length == 0) {
return true;
}
boolean allGranted = true;
for (String neededPermission : neededPermissions) {
allGranted &= ContextCompat.checkSelfPermission(this, neededPermission) == PackageManager.PERMISSION_GRANTED;
}
return allGranted;
}
private void initOnclick() {
//点击选择本地照片
chooseLocalImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(intent, ACTION_CHOOSE_IMAGE);
}
});
//点击拍照
takePhotoMessage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
checkPermissionAndCamera();
}
});
}
/**
* 检查权限并拍照。
* 调用相机前先检查权限。
*/
private void checkPermissionAndCamera() {
int hasCameraPermission = ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.CAMERA);
if (hasCameraPermission == PackageManager.PERMISSION_GRANTED) {
//有调起相机拍照
openCamera();
} else {
//没有权限,申请权限。
ActivityCompat.requestPermissions(getActivity(),new String[]{Manifest.permission.CAMERA},
PERMISSION_CAMERA_REQUEST_CODE);
}
}
/**
* 调起相机拍照
*/
private void openCamera() {
Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// 判断是否有相机
if (captureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
File photoFile = null;
Uri photoUri = null;
if (isAndroidQ) {
// 适配android 10
photoUri = createImageUri();
} else {//10以下
try {
photoFile = createImageFile();
} catch (IOException e) {
e.printStackTrace();
}
if (photoFile != null) {
mCameraImagePath = photoFile.getAbsolutePath();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//适配Android 7.0文件权限,通过FileProvider创建一个content类型的Uri
photoUri = FileProvider.getUriForFile(getActivity(), getPackageName() + ".fileprovider", photoFile);
} else {
photoUri = Uri.fromFile(photoFile);
}
}
}
mCameraUri = photoUri;
if (photoUri != null) {
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
captureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
startActivityForResult(captureIntent, CAMERA_REQUEST_CODE);
}
}
}
/**
* 创建图片地址uri,用于保存拍照后的照片 Android 10以后使用这种方法
*/
private Uri createImageUri() {
String status = Environment.getExternalStorageState();
// 判断是否有SD卡,优先使用SD卡存储,当没有SD卡时使用手机存储
if (status.equals(Environment.MEDIA_MOUNTED)) {
return getActivity().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new ContentValues());
} else {
return getActivity().getContentResolver().insert(MediaStore.Images.Media.INTERNAL_CONTENT_URI, new ContentValues());
}
}
/**
* 创建保存图片的文件
*/
private File createImageFile() throws IOException {
String imageName = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
File storageDir = getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
if (!storageDir.exists()) {
storageDir.mkdir();
}
File tempFile = new File(storageDir, imageName);
if (!Environment.MEDIA_MOUNTED.equals(EnvironmentCompat.getStorageState(tempFile))) {
return null;
}
return tempFile;
}
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ACTION_CHOOSE_IMAGE) {
if (data == null || data.getData() == null) {
System.out.println("----错误");
return;
}
try {
System.out.println(data.getData()+"----");
mBitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), data.getData());
} catch (Exception e) {
e.printStackTrace();
return;
}
System.out.println("----"+mBitmap);
if (mBitmap == null) {
System.out.println("----mBitmap为null");
return;
}
// 转换为BitmapDrawable对象
BitmapDrawable bmpDraw=new BitmapDrawable(mBitmap);
// 显示位图
ImageMessage.setImageDrawable(bmpDraw);
}
if (requestCode == CAMERA_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
if (isAndroidQ) {
imagestate=true;
// Android 10 使用图片uri加载
//mCameraUri-content://media/external/images/media/3195
Log.e("TAG","mCameraUri-------------"+mCameraUri);
Image2Message.setImageURI(mCameraUri);
} else {
// 使用图片路径加载 No Network Location Provider is installed NLP is necessary for network location fixes
Image2Message.setImageBitmap(BitmapFactory.decodeFile(mCameraImagePath));
}
} else {
if (!imagestate){
Image2Message.setVisibility(View.GONE);
}
// Toast.makeText(this,"取消",Toast.LENGTH_LONG).show();
}
}
}
- android 7.0需要配置文件共享
<provider
android:name="androidx.core.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_paths" />
</provider>
- 在res目录下创建文件夹xml ,放置一个文件file_paths.xml(文件名可以随便取),配置需要共享的文件目录,也就是拍照图片保存的目录。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<!-- 这个是保存拍照图片的路径,必须配置。 -->
<external-files-path
name="images"
path="Pictures" />
</paths>
</resources>
-
位置如下图,参考
-
结尾