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

时间:2017-04-27 18:26:30

标签: 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;

    }
}

1 个答案:

答案 0 :(得分:0)

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

您应该在后台作业中的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());
        }
    }
}