安卓Service拍照

package com.example.phoneguard.service;


import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.widget.Toast;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;


public class BackgroundPhoto extends Service implements SurfaceHolder.Callback {
    private static BackgroundPhoto instance;
    private int caremaid;

    public BackgroundPhoto() {
    }

    public BackgroundPhoto(int caremaid) {
        this.caremaid = caremaid;
    }

    public static BackgroundPhoto getInstance(int caremaid) {
        if (instance == null) {
            instance = new BackgroundPhoto(caremaid);
        }
        return instance;
    }

    private WindowManager windowManager;
    private SurfaceView surfaceView;
    private Camera camera = null;

    String TAG = "BackgroundPhoto";
    Context mContext;
    private Camera.Parameters mParameters;

    @Override
    public void onCreate() {
        mContext = this;


        // Create new SurfaceView, set its size to 1x1, move it to the top left corner and set this service as a callback
        windowManager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
        surfaceView = new SurfaceView(this);
        WindowManager.LayoutParams params = new WindowManager.LayoutParams();
        params.width = 1;
        params.height = 1;
        params.alpha = 0;
        //检查版本,注意当type为TYPE_APPLICATION_OVERLAY时,铺满活动窗口,但在关键的系统窗口下面,如状态栏或IME
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        } else {
            params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
        }

        // 屏蔽点击事件
        params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;

        windowManager.addView(surfaceView, params);
        surfaceView.getHolder().addCallback(this);

    }

    // Method called right after Surface created (initializing and starting MediaRecorder)
    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {

       /* camera = Camera.open();

        camera.unlock();*/

        initCamera();

    }

    // 初始化摄像头
    private void initCamera() {

        // 如果存在摄像头
        if (checkCameraHardware(mContext.getApplicationContext())) {
            // 获取摄像头(首选前置,无前置选后置)
            if (openFacingFrontCamera()) {
                Log.i(TAG, "openCameraSuccess");
                // 进行对焦
                autoFocus();
            } else {
                Log.i(TAG, "openCameraFailed");
            }

        }
    }

    // 对焦并拍照
    private void autoFocus() {

        try {
            // 因为开启摄像头需要时间,这里让线程睡两秒
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        startPreview();
        // 自动对焦
        camera.autoFocus(myAutoFocus);

        // 对焦后拍照
        //  camera.unlock();
        camera.takePicture(null, null, myPicCallback);
    }

    private void startPreview() {

        setCameraParameters();
        camera.startPreview();
    }

    /**
     * 设置Camera参数
     * 设置预览界面的宽高,图片保存的宽、高
     */
    private void setCameraParameters() {
        if (camera != null) {
            Log.d(TAG, "setCameraParameters >> begin. mCamera != null");
            if (mParameters == null) {
                mParameters = camera.getParameters();
            }

            int PreviewWidth = 0;
            int PreviewHeight = 0;
            List<Camera.Size> sizeList = mParameters.getSupportedPreviewSizes();
            if (sizeList.size() > 1) {
                Iterator<Camera.Size> itor = sizeList.iterator();
                while (itor.hasNext()) {
                    Camera.Size cur = itor.next();
                    if (cur.width >= PreviewWidth
                            && cur.height >= PreviewHeight) {
                        PreviewWidth = cur.width;
                        PreviewHeight = cur.height;
                        break;
                    }
                }
            } else if (sizeList.size() == 1) {
                Camera.Size size = sizeList.get(0);
                PreviewWidth = size.width;
                PreviewHeight = size.height;
            }
            mParameters.setPreviewSize(PreviewWidth, PreviewHeight); //获得摄像区域的大小
            mParameters.setPictureSize(PreviewWidth, PreviewHeight);//设置拍出来的屏幕大小


            try {
                camera.setParameters(mParameters);
            } catch (Exception e) {
                Camera.Parameters parameters = camera.getParameters();// 得到摄像头的参数
                camera.setParameters(parameters);

            }

        } else {
            Log.e(TAG, "setCameraParameters >> mCamera == null!!");
        }
    }

    // 判断是否存在摄像头
    private boolean checkCameraHardware(Context context) {

        if (context.getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_CAMERA)) {
            // 设备存在摄像头
            return true;
        } else {
            // 设备不存在摄像头
            return false;
        }

    }

    // 得到后置摄像头
    private boolean openFacingFrontCamera() {

        // 尝试开启前置摄像头
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
       camera = Camera.open(camIdx);

        try {
            // 这里的myCamera为已经初始化的Camera对象
            camera.setPreviewDisplay(surfaceView.getHolder());
        } catch (IOException e) {
            e.printStackTrace();
            camera.stopPreview();
            camera.release();
            camera = null;
        }

        camera.startPreview();

        return true;
    }

    // 自动对焦回调函数(空实现)
    private Camera.AutoFocusCallback myAutoFocus = new Camera.AutoFocusCallback() {
        @Override
        public void onAutoFocus(boolean success, Camera camera) {
        }
    };

    // 拍照成功回调函数
    private Camera.PictureCallback myPicCallback = new Camera.PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            // 完成拍照后关闭Activity


            // 将得到的照片进行270°旋转,使其竖直
            Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
            Matrix matrix = new Matrix();

            matrix.preRotate(90);


            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                    bitmap.getHeight(), matrix, true);

            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA);
            String imageFileName = "Photo" + dateFormat.format(new Date(System.currentTimeMillis())) + ".jpg";
            // 创建并保存图片文件
            File pictureFile = new File(Environment.getExternalStorageDirectory() + "/1/", imageFileName);
            try {
                FileOutputStream fos = new FileOutputStream(pictureFile);
                bitmap.compress(Bitmap.CompressFormat.JPEG, 75, fos);
                fos.close();
            } catch (Exception error) {
                Toast.makeText(mContext, "拍照失败", Toast.LENGTH_SHORT)
                        .show();
                Log.i(TAG, "保存照片失败" + error.toString());
                error.printStackTrace();
                camera.stopPreview();
                camera.release();
                camera = null;
            }

            Log.i(TAG, "获取照片成功" + pictureFile.getAbsolutePath());
            Toast.makeText(mContext, "获取照片成功", Toast.LENGTH_SHORT)
                    .show();

            camera.stopPreview();
            camera.release();
            camera = null;

        }
    };

    // Stop recording and remove SurfaceView
    @Override
    public void onDestroy() {


        camera.release();

        windowManager.removeView(surfaceView);

    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
    }


    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

然后start此service就可以了

Android 中,你可以使用 Service 和 Camera API 来实现后台拍照。以下是一个简单的示例: 1.创建一个 Service 类,继承自 Service: ``` public class CameraService extends Service { private Camera mCamera; @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); // 打开摄像头 mCamera = Camera.open(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { // 设置摄像头参数 Camera.Parameters params = mCamera.getParameters(); params.setPictureSize(640, 480); mCamera.setParameters(params); // 拍照 mCamera.takePicture(null, null, mPictureCallback); // 返回 START_STICKY 或者 START_REDELIVER_INTENT,以确保 Service 能够在被销毁后重新启动 return START_STICKY; } @Override public void onDestroy() { super.onDestroy(); // 释放摄像头 mCamera.release(); } // 拍照回调函数 private Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { // 处理拍照数据 // ... // 拍照完成后再次启动 Service,以实现循环拍照 startService(new Intent(CameraService.this, CameraService.class)); } }; } ``` 2.在 AndroidManifest.xml 文件中注册 Service: ``` <service android:name=".CameraService" /> ``` 3.在 Activity 中启动 Service: ``` Intent intent = new Intent(this, CameraService.class); startService(intent); ``` 在上述示例中,Service 的 onCreate() 方法用于打开摄像头,onStartCommand() 方法用于设置摄像头参数并拍照,onDestroy() 方法用于释放摄像头。拍照回调函数 mPictureCallback 用于处理拍照数据,并再次启动 Service,以实现循环拍照。 需要注意的是,在 Android 9 或以上的版本中,禁止在后台调用摄像头,除非你的应用是系统应用或者具有特殊权限。因此,你需要确保你的应用具有相关权限。在 Android 11 中,你必须在应用运行时请求用户授权,以允许你的应用在后台调用摄像头。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值