随着Android版本的不断升级,好多的系统方法以及调用都已经过时,造成无法实现预期的效果,本文实现对系统相机,系统图库封装,可以在Android 9.0之上实现,下来看具体实现方法。
因为在android 6.0之后,需要动态的申请调用相机和图库的权限,否则无法调起相机,所以首先我们对权限管理进行封装:
PermissionManager
public class PermissionManager {
/**
* 系统相机权限
* @param mContext
* @param mActivity
* @param REQUEST_CAMERA
* @return
*/
public static boolean checkCameraPermission(Context mContext, Activity mActivity, int REQUEST_CAMERA) {
if (ContextCompat.checkSelfPermission(mContext,
Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(mContext, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(mActivity,
new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_CAMERA);
return true;
} else {
return false;
}
}
/**
* 本地图库权限
* @param mContext
* @param mActivity
* @param REQUEST_CHOOSE_PHOTO
* @return
*/
public static boolean checkPhotoPermission(Context mContext, Activity mActivity, int REQUEST_CHOOSE_PHOTO) {
if (ContextCompat.checkSelfPermission(mContext,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(mActivity,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_CHOOSE_PHOTO);
return true;
} else {
return false;
}
}
}
调用相机和图库之前先判断权限是否开启,提示用户开启权限。
下来我们还需要对相机和图库进行本地的存储,下来我们封装文件管理:
FileManager
public class FileManager {
private static final String SD_PATH = "/sdcard/android/pic/";
private static final String IN_PATH = "/android/pic/";
// sd_card保存图片
public static File createFileIfNeed(String fileName) throws IOException {
String fileA = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath() + "/android";
File fileJA = new File(fileA);
if (!fileJA.exists()) {
fileJA.mkdirs();
}
File file = new File(fileA, fileName);
if (!file.exists()) {
file.createNewFile();
}
return file;
}
// 从存储的路径中获取文件
public static String readpic() {
String filePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath() + "/android/" + "filepath.png";
return filePath;
}
//随机产生文件名
public static String generateFileName() {
return UUID.randomUUID().toString();
}
//保存bitmap 到本地
public static String saveBitmap(Context context, Bitmap mBitmap) {
String savePath;
File filePic;
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
savePath = SD_PATH;
} else {
savePath = context.getApplicationContext().getFilesDir()
.getAbsolutePath()
+ IN_PATH;
}
try {
filePic = new File(savePath + generateFileName() + ".jpg");
if (!filePic.exists()) {
filePic.getParentFile().mkdirs();
filePic.createNewFile();
}
FileOutputStream fos = new FileOutputStream(filePic);
mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
return filePic.getAbsolutePath();
}
}
在7.0版本之后,获取相机的URI需要在主配置文件中配置:
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="link.android.file.provider"
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 version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="external_files"
path="."/>
</paths>
现在,准备工作已经完成,下来就是调用相机和图库:
public class MainActivity extends AppCompatActivity{
private static int REQUEST_CAMERA = 1;
private static int REQUEST_CHOOSE_PHOTO = 2;
//打开系统相机按钮
buttonCameraClick(){
//判断是否有权限
if (!PermissionManager.checkCameraPermission(this, this, REQUEST_CAMERA)) {
try {
//打开相机
openCamera();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//打开系统图库
buttonPictrueClick(){
//判断是否有权限
if (!PermissionManager.checkPhotoPermission(this, this, REQUEST_CHOOSE_PHOTO)) {
//打开系统图库
openGallery();
}
}
//打开系统相机
private void openCamera() throws IOException {
Intent intent = new Intent();
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
File file = FileManager.createFileIfNeed("filepath.png");
Uri uri;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
uri = Uri.fromFile(file);
} else {
uri = FileProvider.getUriForFile(this, "link.android.file.provider", file);
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
startActivityForResult(intent, 1);
}
//打开系统图库
private void openGallery() {
Intent picture = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(picture, 2);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1 && resultCode != Activity.RESULT_CANCELED) {
String state = Environment.getExternalStorageState();
if (!state.equals(Environment.MEDIA_MOUNTED))
return;
// 把原图显示到界面上
Tiny.FileCompressOptions options = new Tiny.FileCompressOptions();
Tiny.getInstance().source(FileManager.readpic()).asFile().withOptions(options).compress(new FileWithBitmapCallback() {
@Override
public void callback(boolean isSuccess, Bitmap bitmap, String outfile, Throwable t) {
sendCropImage(outfile);
}
});
} else if (requestCode == 2 && resultCode == Activity.RESULT_OK && null != data) {
try {
Uri selectedImage = data.getData();
Tiny.FileCompressOptions options = new Tiny.FileCompressOptions();
Tiny.getInstance().source(selectedImage).asFile().withOptions(options).compress(new FileWithBitmapCallback() {
@Override
public void callback(boolean isSuccess, Bitmap bitmap, String outfile, Throwable t) {
sendCropImage(outfile);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
private void sendCropImage(String imagePath) {
//可根据网络请求进行上传操作
}
如上所示,其中的Tiny框架是对获取到的图片进行压缩处理,便于后续的上传,可以在项目中进行引用。
implementation ‘com.zxy.android:tiny:0.1.0’
以上就是获取系统图库和系统相机的全部内容,如果有什么欠缺的地方,还希望各位指正!