目录
声明权限拍照按钮触发事件`后记参考文章:声明权限
首先应该在“AndroidManifest”文件中声明手机内存读写权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
由于从Android 6.0开始,一些敏感权限需要在对应的Activity再次进行动态申请,因此,需要在我们编写的Activity里再次申请权限:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);Log.d("进入:", "requestPermissions");}if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 0);Log.d("进入:", "requestPermissions");}
拍照按钮触发事件`
1.拍照按钮的点击事件如下:
mBtnUpload.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//点击事件:进行拍照Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);File photoFile=createImgFile();photoUri= Uri.fromFile(photoFile);intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);startActivityForResult(intent,1);}});
2.上述“createImgFile()”函数的功能是自定义图片名,获取照片的file,具体代码如下:
/*** 自定义图片名,获取照片的file*/private File createImgFile(){//确定文件名String fileName="img_"+new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date())+".jpg";File dir;if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){dir=Environment.getExternalStorageDirectory();}else{dir=getExternalFilesDir(Environment.DIRECTORY_PICTURES);}File tempFile=new File(dir,fileName);try{if(tempFile.exists()){tempFile.delete();}tempFile.createNewFile();}catch (IOException e){e.printStackTrace();}//获取文件路径photoPath = tempFile.getAbsolutePath();return tempFile;}
3.由于上述代码采用了“startActivityForResult()”方法,因此在拍照完成后会调用“onActivityResult()”函数。我们重写该函数(以实现照片存储、添加到相册中的功能):
protected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if(resultCode==RESULT_OK){switch (requestCode){case 1:setImageBitmap();galleryAddPic();break;case 2://data中自带有返回的uriphotoUri=data.getData();//获取照片路径String[] filePathColumn={MediaStore.Audio.Media.DATA};Cursor cursor=getContentResolver().query(photoUri,filePathColumn,null,null,null);cursor.moveToFirst();photoPath=cursor.getString(cursor.getColumnIndex(filePathColumn[0]));cursor.close();//有了照片路径,之后就是压缩图片,和之前没有什么区别setImageBitmap();break;}}}
注:此处的“case 2”语句块用于从手机本地相册选取照片,由于代码类似,不再进行演示。
4.“setImageBitmap()”函数的功能是压缩我们刚刚拍到的图片,并将该图片展示在我们声明的“ImageView”控件中。具体代码如下:
/*** 压缩图片*/private void setImageBitmap(){Log.d("Record", "进入压缩图片");//获取imageview的宽和高int targetWidth=photoImageView.getWidth();int targetHeight=photoImageView.getHeight();//根据图片路径,获取bitmap的宽和高BitmapFactory.Options options=new BitmapFactory.Options();options.inJustDecodeBounds=true;BitmapFactory.decodeFile(photoPath,options);int photoWidth=options.outWidth;int photoHeight=options.outHeight;Log.d("Record", "获取长和高:"+ photoHeight + "Width:" + photoWidth);//获取缩放比例int inSampleSize=1;if(photoWidth>targetWidth||photoHeight>targetHeight){int widthRatio=Math.round((float)photoWidth/targetWidth);int heightRatio=Math.round((float)photoHeight/targetHeight);inSampleSize=Math.min(widthRatio,heightRatio);Log.d("Record", "进入缩放比例");}//使用现在的options获取Bitmapoptions.inSampleSize=inSampleSize;options.inJustDecodeBounds=false;Bitmap bitmap=BitmapFactory.decodeFile(photoPath,options);photoImageView.setImageBitmap(bitmap);//调用转换函数,将ImageView文件转换为String类型数据,以便传输到云端String bitmapToString = putImageToShare(getApplicationContext(), photoImageView);mTvChange.setText(bitmapToString);//调用上传函数,将String类型数据传送到服务器UploadImage(getApplicationContext(), bitmapToString);Log.d("Record", "ToString:" + bitmapToString);Log.d("Record", "获取Bitmap");}
其中的“putImageToShare()”、“UploadImage()”方法作用分别是图片转换成String类型的数据、将该数据上传至服务器。如果不需要实现照片上传至服务器的功能,可以删除这两行代码。如果需要实现上传功能,可以看这篇文章:
Android平台实现图片传输到服务器并在服务器文件夹中重现(客户端程序+服务器端程序)
5.“galleryAddPic()”函数的功能是将我们刚刚拍到的照片添加到手机相册中,具体代码如下:
//将图片添加进手机相册private void galleryAddPic(){Intent mediaScanIntent=new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);mediaScanIntent.setData(photoUri);this.sendBroadcast(mediaScanIntent);}
后记
记录一些编程过程中踩到的坑:
1.在Android 10中,读写手机内存权限还需要进行额外的操作:
在“AndroidManifest”文件中添加语句:
android:requestLegacyExternalStorage="true"
否则ImageView控件无法显示我们的图片。
2.在Android 10中,执行上述代码时,调用相机会闪退。解决方法如下:
在对应Activity中添加语句:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();StrictMode.setVmPolicy( builder.build() );}
参考文章:
/happy_fsyy/article/details/51986444
——————————————————————————
最后贴一下我的个人公众号:微信搜索“茶迁”或扫描下图。平时会更新一些编程相关的文章,欢迎大家关注~
如果觉得《Android实现调用手机摄像头进行拍照并存储为文件》对你有帮助,请点赞、收藏,并留下你的观点哦!