Android 7 JobScheduler在相机拍摄新照片时获取事件

Mat*_*tze 7 android android-7.0-nougat

我在Android 7上遇到的问题是不支持广播事件"android.hardware.action.NEW_PICTURE"更长.我现在为Android 7写了一个JobService,但是当内部摄像头拍摄图片时它不会触发.我不知道是什么问题,大家可以帮助我.

如果www中的任何示例源代码为Android 7和JobService替换广播 "android.hardware.action.NEW_PICTURE".

感谢帮助 !

这是我的示例代码:

  @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class ZNJobService extends JobService {
   private static Zlog log = new Zlog(ZNJobService.class.getName());

    static final Uri MEDIA_URI = Uri.parse("content://" + MediaStore.AUTHORITY + "/");
    static final int ZNJOBSERVICE_JOB_ID = 777;
    static  JobInfo JOB_INFO;


    @RequiresApi(api = Build.VERSION_CODES.N)
    public static boolean isRegistered(Context pContext){

            JobScheduler js = pContext.getSystemService(JobScheduler.class);
            List<JobInfo> jobs = js.getAllPendingJobs();
            if (jobs == null) {
                log.INFO("ZNJobService not registered ");
                return false;
            }
            for (int i = 0; i < jobs.size(); i++) {
                if (jobs.get(i).getId() == ZNJOBSERVICE_JOB_ID) {
                    log.INFO("ZNJobService is registered :-)");
                    return true;
                }
            }
            log.INFO("ZNJobService is not registered");
            return false;

    }


    public static void registerJob(Context pContext){

        Log.i("ZNJobService","ZNJobService init");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ) {

            if (! isRegistered(pContext)) {
                Log.i("ZNJobService", "JobBuilder executes");
                log.INFO("JobBuilder executes");
                JobInfo.Builder builder = new JobInfo.Builder(ZNJOBSERVICE_JOB_ID, new ComponentName(pContext, ZNJobService.class.getName()));
                // Look for specific changes to images in the provider.
                builder.addTriggerContentUri(new JobInfo.TriggerContentUri(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                                                                           JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS));
                // Also look for general reports of changes in the overall provider.
                //builder.addTriggerContentUri(new JobInfo.TriggerContentUri(MEDIA_URI, 0));
                JOB_INFO = builder.build();
                log.INFO("JOB_INFO created");

                JobScheduler scheduler = (JobScheduler) pContext.getSystemService(Context.JOB_SCHEDULER_SERVICE);
                int result = scheduler.schedule(JOB_INFO);
                if (result == JobScheduler.RESULT_SUCCESS) {
                    log.INFO(" JobScheduler OK");
                } else {
                    log.ERROR(" JobScheduler fails");
                }
            }

        } else {
            JOB_INFO = null;
        }
    }


    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    public boolean onStartJob(JobParameters params) {
        log.INFO("onStartJob");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            if (params.getJobId() == ZNJOBSERVICE_JOB_ID) {
                if (params.getTriggeredContentAuthorities() != null) {

                    for (Uri uri : params.getTriggeredContentUris()) {
                        log.INFO("JobService Uri=%s",uri.toString());
                    }

                }
            }
        }
        this.jobFinished(params,false);
        return false;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            log.INFO("onStopJob");
        }
        return true;

    }
}
Run Code Online (Sandbox Code Playgroud)

int*_*dis 0

在下面的代码中,您可以将标志传递immediate为 false 以进行正常操作(即在系统指南内安排应用程序的良好行为)。当您的应用程序的主要活动开始时,您可以传递immediatetrue 以强制快速检索媒体内容更改。

onStartJob()您应该在后台作业中运行该方法中的代码。(如下所示。)

如果您只想从摄像机接收媒体而不是其他来源,您应该根据 URI 的路径过滤掉它们。所以只包括"*/DCIM/*". (不过我没有把它放在下面的代码中。)

此外,Android 作业调度程序有一项策略,如果检测到过度滥用,它会拒绝您的服务。也许您的测试导致您的应用程序出现此问题,因此只需卸载并重新安装即可重置它。

public class ZNJobService extends JobService {

    //...

    final Handler workHandler = new Handler();
    Runnable workRunnable;

    //...

    public static void registerJob(Context context, boolean immediate) {
        final JobInfo jobInfo = createJobInfo(context, immediate);
        final JobScheduler js = context.getSystemService(JobScheduler.class);
        final int result = js.schedule(jobInfo);
        if (result == JobScheduler.RESULT_SUCCESS) {
            log.INFO(" JobScheduler OK");
        } else {
            log.ERROR(" JobScheduler fails");
        }
    }

    private static JobInfo createJobInfo(Context context, boolean immediate) {
        final JobInfo.Builder b =
            new JobInfo.Builder(
            ZNJOBSERVICE_JOB_ID, new ComponentName(context, ZNJobService.class));

        // Look for specific changes to images in the provider.
        b.addTriggerContentUri(
            new JobInfo.TriggerContentUri(
                MediaStore.Images.Media.INTERNAL_CONTENT_URI,
                JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS));
        b.addTriggerContentUri(
            new JobInfo.TriggerContentUri(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS));

        if (immediate) {
            // Get all media changes within a tenth of a second.
            b.setTriggerContentUpdateDelay(1);
            b.setTriggerContentMaxDelay(100);
        } else {
            // Wait at least 15 minutes before checking content changes.
            // (Change this as necessary.)
            b.setTriggerContentUpdateDelay(15 * 60 * 1000);

            // No longer than 2 hours for content changes.
            // (Change this as necessary.)
            b.setTriggerContentMaxDelay(2 * 60 * 60 * 1000);
        }

        return b.build();
    }

    @Override
    public boolean onStartJob(final JobParameters params) {
        log.INFO("onStartJob");

        if (params.getTriggeredContentAuthorities() != null && params.getTriggeredContentUris() != null) {
            // Process changes to media content in a background thread.
            workRunnable = new Runnable() {
                @Override
                public void run() {
                    yourMethod(params.getTriggeredContentUris());

                    // Reschedule manually. (The 'immediate' flag might have changed.)
                    jobFinished(params, /*reschedule*/false);
                    scheduleJob(ZNJobService.this, /*immediate*/false);
                }};
            Postal.ensurePost(workHandler, workRunnable);

            return true;
        }

        // Only reschedule the job.
        scheduleJob(this, /*immediate*/false);
        return false;
    }

    @Override
    public boolean onStopJob(final JobParameters params) {
        if (workRunnable != null) {
            workHandler.removeCallbacks(workRunnable);
            workRunnable = null;
        }
        return false;
    }

    private static void yourMethod(Uri[] uris) {
        for (Uri uri : uris) {
            log.INFO("JobService Uri=%s", uri.toString());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)