Android Camera应用初探一
16lz
2021-01-23
Android相机应用有调用系统相机和自己制作相机两种,在本文中先介绍一下系统相机的应用:
首先你要先调用系统的相机你就应该确保该手机有拍照的硬件:
显示判断:/** Check if this device has a camera */ private boolean checkCameraHardware(Context context) { if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){ // this device has a camera return true; } else { // no camera on this device return false; } }
隐式判断:(当不符合条件的时候你的手机将不会安装成功,默认情况下required为true,当你置为false的时候就能进行安装,此时如果涉及调用系统拍照要进行显示判断)
<manifest ... > <uses-feature android:name="android.hardware.camera" android:required="true" /> ...</manifest>
在这里值得注意一点,上面有了判断是否有拍照硬件的代码,这里也应该有判断相机是否可用
if(intent.resolveActivity(getPackageManager()) != null){ //相机应用可用}else{ //相机应用不可用}
系统拍照模式一(返还缩略图)
点击事件:Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);/** * MediaStore.ACTION_IMAGE_CAPTURE也是android.media.action.IMAGE_CAPTURE字符串 * 当start之后就会去查找系统中的Action为android.media.action.IMAGE_CAPTURE的应用 * 如果你在AndroidManifest.xml其中的Activity添加 * <intent-fileter> * <action android:name="android.media.action.IMAGE_CAPTURE"/> * <category android:name="android.intent.category.DEFAULT"/> * </intent-fileter> * 之后该应用就会具有拍照的功能,当其它应用调用系统拍照就会调用该应用 */if(takePictureIntent.resolveActivity(getPackageManager()) != null){//判断相机是否可用 //相机应用可用 startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);}else { Toast.makeText(CameraActivity.this, "相机不可用", Toast.LENGTH_SHORT).show();}
回调方法:
@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(resultCode == Activity.RESULT_OK && requestCode == REQUEST_IMAGE_CAPTURE){ //成功返回,下面的方法将得到拍照之后的缩略图 Bundle extras = data.getExtras(); Bitmap imageBitmap = (Bitmap) extras.get("data"); img_iv.setImageBitmap(imageBitmap); }}
系统拍照模式二(返还拍照的图片)
点击事件:take_picture.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); image = createImageFile2(); if (takePictureIntent.resolveActivity(getPackageManager()) != null) { //设置拍照完成之后的保存的位置 takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image)); startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO); } else { Toast.makeText(CameraActivity2.this, "相机不可用", Toast.LENGTH_SHORT).show(); } }});
相应的方法:
/** * 第一种创建File * @return */private File createImageFile1(){ File file = new File(Environment.getExternalStorageDirectory(),"test.jpg"); return file;}/** * 第二种创建File * @return * @throws IOException */private File createImageFile2() { String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; File storageDir = Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES);//在sd卡下新建pictures目录,该位置可以被所有的app所共享可读可写 /** * 如果你想设置为私有的可以用getExternalFilesDir().在Android 4.3 and lower可以被其他app访问 * 自从Android 4.4将不再被其他应用所访问 * 使用getExternalFilesDir()会随着你应用的卸载而删除 * 为此你可以: * <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" * android:maxSdkVersion="18" /> */ File file = null; try { file = File.createTempFile( imageFileName, /* prefix */ ".jpg", /* suffix */ storageDir /* directory */ ); } catch (IOException e) { e.printStackTrace(); } return file;}
拍照之后回调:
@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(resultCode == RESULT_OK && requestCode == REQUEST_TAKE_PHOTO){ iv.setImageURI(Uri.fromFile(image)); }}以上的实现因为涉及到了写文件的操作所以应该加上权限:
<manifest ...> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> ...</manifest>
写权限也允许读,如果有读有写,则只需要添加这一个权限即可
为了避免出现OOM通常会对图片进行缩放之后再展示代码如下:
/** * 对图片进行缩放 */private void pic(){ //得到控件的宽高 int targetW = iv.getWidth(); int targetH = iv.getHeight(); BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true;//这将通知BitmapFactory类只需返回该图像的范围,而无需尝试解码图像本身 //当设置为false则对其进行解码 BitmapFactory.decodeFile(image.getAbsolutePath(),options); int photoW = options.outWidth; int photoH = options.outHeight; int scaleFactor = Math.max(photoW / targetW, photoH / targetH);//这里帅选出最大的,也就是缩放的时候按最少的比例进行缩放 //解码 options.inJustDecodeBounds = false;//对图片进行解码 options.inSampleSize = scaleFactor;//例如,将inSampleSize = 8时,产生一幅图的大小是原始大小的1/8 options.inPurgeable = true;//当inPurgeable设置为true的时候,当系统内存不足的时候就会回收部分Bitmap占据的内存空间,防止 //出现OOM异常,当为false的时候就不会回收 Bitmap bitmap = BitmapFactory.decodeFile(image.getAbsolutePath(),options); iv.setImageBitmap(bitmap);}
更多相关文章
- FAQ00366]如何使Android应用程序获取系统权限
- android拦截短信并屏蔽系统的Notification
- android——wifi系统架构
- Android学习系列(40)--Android主题和样式之系统篇(下)
- Android 打开系统蓝牙设置