安卓 6.0 以上除了清单文件申明权限外,还要动态申请权限。
<!-- 授予程序可以向SD卡中保存文件的权限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <!-- 授予程序使用摄像头的权限 --> <uses-permission android:name="android.permission.CAMERA"/> <uses-feature android:name="android.hardware.camera.autofocus"/> <uses-feature android:name="android.hardware.camera"/>
1.帧布布局:
package com.camera; import android.Manifest; import android.annotation.SuppressLint; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.PixelFormat; import android.hardware.Camera; import android.net.Uri; import android.os.Environment; import android.provider.MediaStore; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.WindowManager; import android.widget.ImageButton; import android.widget.Toast; import com.zengjx.androidbaseproject.R; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import permissions.dispatcher.NeedsPermission; import permissions.dispatcher.OnShowRationale; import permissions.dispatcher.RuntimePermissions; import permissions.dispatcher.PermissionRequest; @RuntimePermissions public class CameraActivity extends AppCompatActivity { private ImageButton imageButton_Camera,imageButton_PreView; private SurfaceView surfaceView; SurfaceHolder surfaceHolder; private boolean isPreView=false; private Camera camera; private final String TAG="CameraActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_camera); setTitle("相机"); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); //sdcard if(!android.os.Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ Toast.makeText(this,"SD未安装",Toast.LENGTH_SHORT).show(); } initView(); } //实现将照片保存到系统图库中 final Camera.PictureCallback jpeg2 = new Camera.PictureCallback() { //照片回调函数 @Override public void onPictureTaken(byte[] data, Camera camera) { // 根据拍照所得的数据创建位图 final Bitmap bm = BitmapFactory.decodeByteArray(data, 0, data.length); camera.stopPreview(); //停止预览 isPreView = false; //设置为非预览状态 //获取sd卡根目录 File appDir = new File(Environment.getExternalStorageDirectory(), "/DCIM/Camera/"); if (!appDir.exists()) { //如果该目录不存在 appDir.mkdir(); //就创建该目录 } String fileName = System.currentTimeMillis() + ".jpg"; //将获取当前系统时间设置为照片名称 File file = new File(appDir, fileName); //创建文件对象 try { //保存拍到的图片 FileOutputStream fos = new FileOutputStream(file); //创建一个文件输出流对象 bm.compress(Bitmap.CompressFormat.JPEG, 100, fos); //将图片内容压缩为JPEG格式输出到输出流对象中 fos.flush(); //将缓冲区中的数据全部写出到输出流中 fos.close(); //关闭文件输出流对象 } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } //将照片插入到系统图库 try { MediaStore.Images.Media.insertImage(CameraActivity.this.getContentResolver(), file.getAbsolutePath(), fileName, null); } catch (FileNotFoundException e) { e.printStackTrace(); } // 最后通知图库更新 CameraActivity.this.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + ""))); Toast.makeText(CameraActivity.this, "照片保存至:" + file, Toast.LENGTH_LONG).show(); resetCamera(); //调用重新预览resetCamera()方法 } }; final Camera.PictureCallback jpeg = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] bytes, Camera camera) { //1根据拍照创建位图对象 final Bitmap bitmap= BitmapFactory.decodeByteArray(bytes,0,bytes.length); camera.stopPreview(); // 2停止预览 //3标志位 复位为 非预览 isPreView=false; //4获取Sd 目录 目录不存在 创建目录 // String dir=Environment.getExternalStorageDirectory(),"/DICM/Camera/"; // Log.i(TAG,"dir="+dir); File appDir=new File( Environment.getExternalStorageDirectory(),"/DICM/Camera/"); if(!appDir.exists()){ Log.i(TAG,"创建目录"); appDir.mkdir();//目录不存在创建 Log.i(TAG,"创建目录--2"+appDir.exists()); }else{ Log.i(TAG,"目录存在"); } //保存拍到的图片 String fileName=System.currentTimeMillis()+".jpg";//系统时间作为图片名称 File file= new File(appDir,fileName);//创建文件对象 try{ //拍到图片 FileOutputStream fos =new FileOutputStream(file); //创建文件输出流对象 //将图片压缩为JPEG 格式 输出到文件输出流 bitmap.compress(Bitmap.CompressFormat.JPEG,100,fos); fos.flush();//将缓冲区中的数据全部写出到输出流中 fos.close();//关闭文件输出流对象 Log.i(TAG,"关闭文件输出流对象"); }catch (FileNotFoundException e){ e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } //将图片插入到系统图库 try{ MediaStore.Images.Media.insertImage(CameraActivity.this.getContentResolver(), file.getAbsolutePath(), fileName, null); }catch (FileNotFoundException e){ e.printStackTrace(); } //最后通知图库更新 // CameraActivity.this.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+""))); // 最后通知图库更新 CameraActivity.this.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + ""))); Toast.makeText(CameraActivity.this,"图片保存至"+file,Toast.LENGTH_SHORT).show(); resetCamera();//重新预览 } }; public void resetCamera(){ if(!isPreView){ isPreView=true; camera.startPreview(); } } public void initView(){ surfaceView =(SurfaceView) findViewById(R.id.surface); //获取 SurfaceHolder surfaceHolder =surfaceView.getHolder(); //设置 sufaceholder 不自己维护缓冲 surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); imageButton_Camera= (ImageButton) findViewById(R.id.btn_camera) ; imageButton_PreView= (ImageButton)findViewById(R.id.btn_preview); imageButton_Camera.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if(camera!=null){ camera.takePicture(null,null,jpeg); } } }); imageButton_PreView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if(!isPreView){ // cameratest(); // checkselfPermisssion2(); cameratest(); } } }); } /* @NeedsPermission(Manifest.permission.CAMERA,Manifest.p) void camera() { { camera=Camera.open(); if(camera==null){ Toast.makeText(this,"无权限",Toast.LENGTH_SHORT).show(); return; } isPreView=true; try { camera.setPreviewDisplay(surfaceHolder); //获取摄像头参数 Camera.Parameters parameters = camera.getParameters(); parameters.setPictureSize(640,480); parameters.setPictureFormat(PixelFormat.JPEG); parameters.set("jpeg-quality",80); //重新设置摄像头参数 camera.setParameters(parameters);//重新设置预览 camera.startPreview();//开始预览 camera.autoFocus(null);//设置自动对焦 } catch (IOException e) { e.printStackTrace(); } } } */ @SuppressLint("NeedOnRequestPermissionsResult") @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); CameraActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults); } @OnShowRationale(Manifest.permission.CAMERA) void camera_show(PermissionRequest request) { } @NeedsPermission({Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}) void cameratest() { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1); camera=Camera.open(); if(camera==null){ Toast.makeText(this,"无权限",Toast.LENGTH_SHORT).show(); return; }else{ Toast.makeText(this,"打开成功",Toast.LENGTH_SHORT).show(); } isPreView=true; try { camera.setPreviewDisplay(surfaceHolder); //获取摄像头参数 Camera.Parameters parameters = camera.getParameters(); // parameters.setPictureSize(480,480); parameters.setPictureFormat(PixelFormat.JPEG); parameters.set("jpeg-quality",80); //重新设置摄像头参数 camera.setParameters(parameters);//重新设置预览 camera.startPreview();//开始预览 camera.autoFocus(null);//设置自动对焦 } catch (IOException e) { e.printStackTrace(); } Toast.makeText(this,"cameratest",Toast.LENGTH_SHORT).show(); } @OnShowRationale({Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}) void cameratest_show(final PermissionRequest request) { Toast.makeText(this,"cameratest_show",Toast.LENGTH_SHORT).show(); } //当停止Activity 暂停时候 停止 @Override protected void onPause() { //当暂停Activity时,停止预览并释放资源 if (camera != null) { //如果相机不为空 Toast.makeText(this,"onPause!!!!!",Toast.LENGTH_SHORT).show(); // camera.stopPreview(); //停止预览---这种方式在 安卓6.0 7.0 会不显示预览界面 // camera.release(); //释放资源 } super.onPause(); } @Override protected void onStop() { Toast.makeText(this,"onStop!!!!!",Toast.LENGTH_SHORT).show(); // camera.stopPreview(); //停止预览-- 安卓6.0 7.0 会不显示预览界面 // camera.release(); //释放资源 super.onStop(); } @Override protected void onDestroy() { Toast.makeText(this,"onDestroy!!!!!",Toast.LENGTH_SHORT).show(); camera.stopPreview(); //停止预览 camera.release(); //释放资源 super.onDestroy(); } public void checkselfPermisssion2(){ if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) { //第一次全新进入时,shouldShowRequestPermissionRationale方法将返回false,这里将会执行。 //请求权限时如果点了拒绝但是没勾选不再提醒,shouldShowRequestPermissionRationale方法将返回true,这里将不执行。 //点了拒绝且勾选了不再提醒,再次进入时,shouldShowRequestPermissionRationale方法也将返回false,并且权限请求将无任何响应,然后可以在下面方法中做些处理,提示用户打开权限。 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1);//1 表示用户唯一标识一个权限请求以便回调时进行判断 Log.i("permission","request"); } else { Log.i("permission","request2"); ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, 1); } } } }