Android-----调用系统相机拍照并把照片展示在图库中
此博客主要实现调用系统相机拍照,并把图片保存到指定目录下,更新数媒库将图片在图库中显示,布局xml代码:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center" android:background="@drawable/back_1" tools:context="com.org.youtu.MainActivity"> <Button android:id="@+id/btn_photo" android:layout_width="80dp" android:layout_height="60dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:background="@drawable/image" android:layout_marginBottom="30sp"/> </LinearLayout>
逻辑处理代码:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private Button takePhoto; private Uri imageUri;//图片路径 private String filename;//图片名称 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.requestWindowFeature(Window.FEATURE_NO_TITLE); this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_main); requestPermissions(); //权限申请 takePhoto = this.findViewById(R.id.btn_photo); takePhoto.setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()){ case R.id.btn_photo: Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); //照相 startActivityForResult(intent,1008); //启动照相 break; } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode,resultCode,data); if (resultCode != RESULT_OK){ Toast.makeText(MainActivity.this, "ActivityResult返回码错误!", Toast.LENGTH_SHORT).show(); return; } switch (requestCode){ case 1008: saveCameraImage(data); break; } } /**【申请手机相机和内存读取权限】**/ public void requestPermissions(){ String [] permissions = new String[] { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO, }; ActivityCompat.requestPermissions(MainActivity.this,permissions,100); } /**【保存相机拍的图片】**/ public void saveCameraImage(Intent data){ String path = Environment.getExternalStorageDirectory().toString() + "/DCIM/youtu/"; File newFolder = new File(path); if (!newFolder.exists()){ boolean isfal = newFolder.mkdirs(); Log.e("isfal","创建目录:"+path+"<-状态->" + isfal); } Log.e("path","路径:"+path); SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); Date date = new Date(System.currentTimeMillis()); filename = format.format(date); File outputImage = new File(newFolder,filename+".jpg"); FileOutputStream out = null; BufferedOutputStream bos = null; try { out = new FileOutputStream(outputImage); bos = new BufferedOutputStream(out); Bitmap bitmap = (Bitmap) data.getExtras().get("data");// 解析返回的图片成bitmap bitmap.compress(Bitmap.CompressFormat.JPEG,100,bos); /**【通知媒体库更新数据库,在图库中能看到图片】**/ MediaStore.Images.Media.insertImage(getContentResolver(),bitmap,null,null); } catch (FileNotFoundException e) { e.printStackTrace(); }finally { try { bos.flush(); bos.close(); } catch (IOException e) { e.printStackTrace(); } } } }
不要忘了在AndroidManifest.xml中加入
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.RECORD_AUDIO" />
以上皆参考网上资料实现。
以上实现方法会存在两份照片,指定目录中有一份,图库中有一份,且我发现图库中的图片拍出来的效果较模糊
下面获取较清晰图片的解决办法
public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private Button takePhoto , btn_setting , btn_write , btn_mske , btn_icon; private Uri imageUri;//图片路径 private String filename;//图片名称 private File operateFile;//操作文件 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.requestWindowFeature(Window.FEATURE_NO_TITLE); this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_main); /** * android.os.FileUriExposedException: file:///storage/emulated/0/ilive/images/photophoto.jpeg * exposed beyond app through ClipData.Item.getUri() * 下面三行解决此处问题 * **/ StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(builder.build()); builder.detectFileUriExposure(); requestPermissions(); //权限申请 takePhoto = this.findViewById(R.id.btn_photo); takePhoto.setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()){ case R.id.btn_photo: Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); //照相 filename = saveFileName(); operateFile = new File(filename); imageUri = Uri.fromFile(operateFile); intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); //指定图片输出地址 startActivityForResult(intent,1008); //启动照相 break; } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode,resultCode,data); if (resultCode != RESULT_OK){ deleteFile(operateFile); //将指定路径图片删去仅保留图库图片 Toast.makeText(MainActivity.this, "ActivityResult返回码错误!", Toast.LENGTH_SHORT).show(); return; } switch (requestCode){ case 1008: saveCameraImage(data); deleteFile(operateFile); //将指定路径图片删去仅保留图库图片 break; } } /**【申请手机相机和内存读取权限】**/ public void requestPermissions(){ String [] permissions = new String[] { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO, }; ActivityCompat.requestPermissions(MainActivity.this,permissions,100); } /**【保存相机拍的图片】**/ public void saveCameraImage(Intent data){ FileInputStream inputStream = null; try { inputStream = new FileInputStream(filename); Bitmap bitmap = BitmapFactory.decodeStream(inputStream); /**【通知媒体库更新数据库,在图库中能看到图片,且图片是另外再保存一张】**/ MediaStore.Images.Media.insertImage(getContentResolver(),bitmap,null,null); } catch (FileNotFoundException e) { e.printStackTrace(); }finally { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } /**【保存文件的名字以及目录】**/ private String saveFileName(){ String path = Environment.getExternalStorageDirectory().toString() + "/DCIM/youtu/"; File newFolder = new File(path); if (!newFolder.exists()){ boolean isfal = newFolder.mkdirs(); Log.e("isfal","创建目录:"+path+"<-状态->" + isfal); } Log.e("path","路径:"+path); SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); Date date = new Date(System.currentTimeMillis()); String name = path + format.format(date) +".jpg"; Log.e("FileName","保存文件路径和名字:" + name); return name; } /**【删除文件】**/ private void deleteFile(File file){ if (file.exists()){ //文件是否存在 if (file.isFile()){ //是否是文件 boolean isDel = file.delete(); Log.e("文件删除状态","<-=->"+isDel); } } } }
以上能实现保留原图。