由于从Android 6.0开始,一些敏感权限_android 13 相机权限">
赞
踩
首先应该在“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() {
@Override
public 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中自带有返回的uri photoUri=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获取Bitmap options.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() );
}
https://blog.csdn.net/happy_fsyy/article/details/51986444
——————————————————————————
最后贴一下我的个人公众号:微信搜索“茶迁”或扫描下图。平时会更新一些编程相关的文章,欢迎大家关注~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。