如何在Android Oreo中使用前景服务捕获图像

时间:2018-10-20 09:48:56

标签: android service camera capture foreground

我正在尝试从相机拍摄照片而不进行预览并使用服务, 因为我需要它来拍照而不打开任何UI。 我使用的是android-hidden-camera,它在API <26中也可以正常工作,但是从奥利奥开始,它可以工作,但是在服务正常工作时冻结UI, 大约3秒钟。

这是我正在使用的代码:

public class BackService extends HiddenCameraService {


private void toast(String msg) {
    Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
}

private class DoInBackground extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        BackService.this.takePicture();
        return "Captured";
    }

    @Override
    protected void onPreExecute() {   }

    @Override
    protected void onProgressUpdate(Void... values) {}

    @Override
    protected void onPostExecute(String result) {   }


}

@Override
public void onCreate() {
    createNotification();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {


    if (ContextCompat.checkSelfPermission(this, "android.permission.CAMERA") != 0) {
        toast("Camera permission not granted");
    } else if (HiddenCameraUtils.canOverDrawOtherApps(this)) {
        startCamera(new CameraConfig().getBuilder(getApplicationContext())
                .setCameraFacing(CameraFacing.REAR_FACING_CAMERA)
                .setCameraResolution(CameraResolution.MEDIUM_RESOLUTION)
                .setImageFormat(CameraImageFormat.FORMAT_JPEG)
                .setImageRotation(CameraRotation.ROTATION_270)
                .build());

        new DoInBackground().execute("");
    } else {
        HiddenCameraUtils.openDrawOverPermissionSetting(this);
    }


    return START_NOT_STICKY;
}


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

@Override
public void onImageCapture(File imageFile) {
    toast(imageFile.getAbsolutePath());
    System.out.println("FULL PATH: "+imageFile.getAbsolutePath());
    stopForeground(true);
    stopSelf();

}

@Override
public void onCameraError(int errorCode) {
    toast("onCameraError() called");
    switch (errorCode) {
        case CameraError.ERROR_CAMERA_OPEN_FAILED:
            toast("CANNOT OPEN CAMERA");
            break;
        case CameraError.ERROR_IMAGE_WRITE_FAILED:
            toast( "EXT STORAGE PERM FALSE");
            break;
        case CameraError.ERROR_CAMERA_PERMISSION_NOT_AVAILABLE:
            toast("CAMERA PERMISSION FALSE");
            break;
        case CameraError.ERROR_DOES_NOT_HAVE_OVERDRAW_PERMISSION:
            toast("OVERDRAW PERMISSIONS FALSE");
            HiddenCameraUtils.openDrawOverPermissionSetting(this);
            break;
        case CameraError.ERROR_DOES_NOT_HAVE_FRONT_CAMERA:
            toast("Your device does not have front camera.");
            break;
    }
}


private void createNotificationChannel() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        CharSequence name = Constants.CHANNEL_NAME;
        String description = Constants.NOTIFICATION_TEXT;
        int importance = NotificationManager.IMPORTANCE_LOW;
        NotificationChannel channel = new NotificationChannel(Constants.NOTIF_CHANNEL_ID, name, importance);
        channel.setDescription(description);
        NotificationManager notificationManager = getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(channel);
    }
}


private void createNotification(){
    createNotificationChannel();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

        Notification.Builder builder = new Notification.Builder(this, Constants.NOTIF_CHANNEL_ID)
                .setContentTitle(getString(R.string.app_name))
                .setContentText(Constants.NOTIFICATION_TEXT)
                .setAutoCancel(true);

        Notification notification = builder.build();
        startForeground(1, notification);

    } else {

        NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                .setContentTitle(getString(R.string.app_name))
                .setContentText(Constants.NOTIFICATION_TEXT)
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                .setAutoCancel(true);

        Notification notification = builder.build();
        startForeground(1, notification);
    }
}

startCamera()是需要一些时间才能完成的任务,在执行takePicture()之前,我需要至少睡一秒钟

1 个答案:

答案 0 :(得分:0)

看起来这是库的问题,似乎 viks178 解决了它:

<块引用>

我也有同样的问题。拍照时冻结 应用。 Android 版本:8 CameraConfig:REAR_FACING_CAMERA

我认为 HiddenCameraService.java 中的一些更改可以解决这个问题。

更改这一行(在 HiddenCameraService.java 中,第 130 行) WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH 到一行 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE

https://github.com/kevalpatel2106/android-hidden-camera/issues/27