相机拍摄新照片时,Android 7 JobScheduler获取事件 [英] Android 7 JobScheduler get event when new picture is taken by the camera

查看:82
本文介绍了相机拍摄新照片时,Android 7 JobScheduler获取事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Android 7上遇到了一个问题,该问题不再支持广播事件"android.hardware.action.NEW_PICTURE".我现在为Android 7编写JobService,但是当内部相机拍摄图片时,它不会启动.我不知道出了什么问题,每个人都可以帮我吗.

I have a problem on Android 7 that not support the broadcast event "android.hardware.action.NEW_PICTURE" longer. I write now for Android 7 a JobService but it will not fire when a Picture is shot by the internal camera. I don't know what is the problem, can everybody help me.

如果www中有用于Android 7和JobService进行替换的示例源,则广播"android.hardware.action.NEW_PICTURE" .

If any example source in the www that's for Android 7 and JobService for the replacement the broadcast "android.hardware.action.NEW_PICTURE" .

感谢您的帮助!

Thanks for help !

这是我的示例代码:

  @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;

    }
}

推荐答案

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

In the below code you can pass the flag immediate as false for normal operation (i.e. schedule within system guidelines for an app's good behaviour). When your app's main activity starts you can pass immediate as true to force a quick retrieval of media content changes.

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

You should run code in the onStartJob() method in a background job. (As shown below.)

如果您只想从摄像机而不是其他来源接收媒体,则应仅根据其路径过滤掉URI.因此,仅包含"*/DCIM/*" .(尽管我没有在下面的代码中放置它.)

If you only want to receive media from the camera and not other sources you should just filter out URI's based on their path. So only include "*/DCIM/*". (I haven't put this in the below code though.)

此外,Android作业调度程序还具有一项策略,如果该策略检测到滥用情况,它将拒绝您的服务.也许是您的测试在您的应用中造成了这种情况,所以只需卸载并重新安装即可将其重置.

Also the Android job scheduler has a policy where it denies your service if it detects over abuse. Maybe your tests have caused this in your app, so just uninstall and reinstall to reset it.

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());
        }
    }
}

这篇关于相机拍摄新照片时,Android 7 JobScheduler获取事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆