首先介绍下该程序能实现的功能(就是基本的两个):
1,调用手机相机进行拍照,然后返回给应用。
2,将拍好的照片保存到系统相册中。
讲讲有的没的,我这个是照着官方给的例子写的,但是过程中遇到一些问题。
先贴上代码把。首先是AndroidManifest.xml
它需要添加的权限
<uses-feature android:name="android.hardware.camera" android:required="true" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
其次还需要添加一个内容提供者:
android:name这里很多网上的,包括开发文档都是v4包下的.但是我这边会出错,我就找到了这个
<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/provider_paths" />
</provider>
然后还需要一个xml文件:
官方文档中这里是external-files-path。
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="Android/data/cn.twle.android.opencvtest/files/Pictures" />
</paths>
打开相机,进行拍照保存相片
public void open(View view){
dispatchTakePictureIntent();
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
}
if (photoFile != null) {
Uri uriForFile = FileProvider.getUriForFile(this,
"cn.twle.android.opencvtest.fileprovider",
photoFile);
Uri photoURI = uriForFile;
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
private File createImageFile() throws IOException {
// Create an image file name
//获得时间。yyyy(年),MM(月),dd(日),HH(小时),mm(分),ss(秒)。
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
//进行图片名称进行拼接
imageFileName = "JPEG_" + timeStamp + "_";
//获得该应用包下文件的Pictures目录(如果没有会自动创建)
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
//创建image文件
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
//获取图片的绝对路径+图片名
currentPhotoPath = image.getAbsolutePath();
Log.e("TAG---------------",currentPhotoPath+"");
return image;
}
在官方文档中用的是利用广播来进行图片保存,但是我试了一下,我没有成功就改用了下面的方法
//保存照片到相册
public void save(View view){
if(currentPhotoPath==null)//如果该图片文件为空
return;
try {
Log.e("TAG","yes");
MediaStore.Images.Media.insertImage(getContentResolver(), currentPhotoPath, photoFile.getName(), photoFile.getName());
} catch (FileNotFoundException e) {
Log.e("TAG","no");
e.printStackTrace();
}
}
//打开相机后返回该程序,会回调这个方法
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//如果相机有拍照resultCode会返回1,如果没有则返回0。如果手机成功打开相机,则requestCode会返回1,否则返回0
Log.e("onActivityResult:",requestCode+"----"+resultCode+"--------"+data+"");
//如果没拍照怎么把文件删除。不然会留下一个0bit的空白文件
if(resultCode==0){
photoFile.delete();
currentPhotoPath=null;
return;
}
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
//这里不是很明白,为什么明明有拍照,但是data是返回null...(有时间再探究)
if(data==null){
image_main.setImageURI(Uri.fromFile(photoFile));
}else {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
image_main.setImageBitmap(imageBitmap);
}
}
super.onActivityResult(requestCode, resultCode, data);
}
拍照后的照片会保存在Android/data/packageName/files/Pictures目录下
/*
创建一个文件。prefix:前缀;suffix:后缀;directory:目录
File.createTempFile(prefix ,suffix ,directory)
*/
public class MainActivity extends AppCompatActivity {
private ImageView image_main;
static final int REQUEST_IMAGE_CAPTURE = 1;
static final int REQUEST_TAKE_PHOTO = 1;
String currentPhotoPath; //图片的绝对路径
File photoFile; //操作时将创建个文件
String imageFileName; //该图片名称
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupOpenCV();
initView();
}
private void initView() {
image_main=findViewById(R.id.image_main);
}
private void setupOpenCV() {
boolean mInitSuccess = OpenCVLoader.initDebug();
if (mInitSuccess) {
Log.e("TAG", "OpenCV init success");
} else {
Log.e("TAG", "OpenCV init failed");
}
}
public void open(View view){
dispatchTakePictureIntent();
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
}
if (photoFile != null) {
Uri uriForFile = FileProvider.getUriForFile(this,
"cn.twle.android.opencvtest.fileprovider",
photoFile);
Uri photoURI = uriForFile;
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
private File createImageFile() throws IOException {
// Create an image file name
//获得时间。yyyy(年),MM(月),dd(日),HH(小时),mm(分),ss(秒)。
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
//进行图片名称进行拼接
imageFileName = "JPEG_" + timeStamp + "_";
//获得该应用包下文件的Pictures目录(如果没有会自动创建)
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
//创建image文件
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
//获取图片的绝对路径+图片名
currentPhotoPath = image.getAbsolutePath();
Log.e("TAG---------------",currentPhotoPath+"");
return image;
}
//打开相机后返回该程序,会回调这个方法
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//如果相机有拍照resultCode会返回1,如果没有则返回0。如果手机成功打开相机,则requestCode会返回1,否则返回0
Log.e("onActivityResult:",requestCode+"----"+resultCode+"--------"+data+"");
//如果没拍照怎么把文件删除。不然会留下一个0bit的空白文件
if(resultCode==0){
photoFile.delete();
currentPhotoPath=null;
return;
}
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
//这里不是很明白,为什么明明有拍照,但是data是返回null...(有时间再探究)
if(data==null){
image_main.setImageURI(Uri.fromFile(photoFile));
}else {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
image_main.setImageBitmap(imageBitmap);
}
}
super.onActivityResult(requestCode, resultCode, data);
}
//保存照片到相册
public void save(View view){
if(currentPhotoPath==null)//如果该图片文件为空
return;
try {
Log.e("TAG","yes");
MediaStore.Images.Media.insertImage(getContentResolver(), currentPhotoPath, photoFile.getName(), photoFile.getName());
} catch (FileNotFoundException e) {
Log.e("TAG","no");
e.printStackTrace();
}
}
//-----------获取的应用权限------------------------------
// public void one(View v) {
// if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
// ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, 1);
// }
// }
// public void two(View v) {
// if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
// ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},2);
// }
//
// }
// public void three(View v) {
// if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
// ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},3);
// }
// }
}