Android - 如何更新小部件,但只有在可见时?

tom*_*ash 30 android visible android-appwidget

我将创建需要每分钟更新其内容的小部件(它显示与时间相关的数据).

但是,如果窗口小部件当前不可见,则无需更新窗口小部件,这意味着:

  • 屏幕已关闭
  • 另一个应用正在运行
  • 小部件放在另一个(不可见的)主屏幕选项卡上

每分钟仅更新可见小部件的最佳方法是什么 - 无需唤醒设备或进行不必要的计算?在小部件变得可见之后,更新前的小延迟是可接受的.

Mar*_*k B 17

要在屏幕关闭时不进行更新,请使用AlarmManager计划不会唤醒手机的重复闹钟.

你问题中的另外两个要点是不可能的.无法检测您的窗口小部件是否位于当前不可见的主屏幕上,并且无法确定是否正在运行隐藏主屏幕的应用程序.我已经在http://b.android.com上提交了一张票,要求将此功能添加到Android.如果你想主演它,它将有助于它获得优先权:http://code.google.com/p/android/issues/detail?id = 5529&q = reporter:mark.r.baird&solpec = ID%20Type%20Status% 20Owner%20Summary%20Stars

  • @ catalyst294这种方法的问题是updatePeriodMillis的最小值是30分钟,并且某些小部件需要较小的更新间隔。 (2认同)

小智 10

  1. 您可以向PowerManager询问isScreenOn()
  2. 您可以注册Intent ACTION_SCREEN_OFF/ACTION_SCREEN_ON并相应地打开/关闭计时器.

虽然上面关于AlarmManager的答案是正确的,但可能还不够,因为我发现许多手机即使不是*_WAKEUP类型也会发出警报.如果安装了其他正在唤醒设备的应用程序,则可能会发生这种情况.如果它一旦醒来,它会传递所有待处理的警报.


xan*_*ndy 6

我在一个名为24clock的项目中找到了goole代码.它尝试在用户离家时不更新小部件:

    ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);

    List<RunningTaskInfo> runningTasks = am.getRunningTasks(2);
    for (RunningTaskInfo t : runningTasks) {
        if (t != null && t.numRunning > 0) {
            ComponentName cn = t.baseActivity;
            if (cn == null) continue;

            String clz = cn.getClassName();
            String pkg = cn.getPackageName();

            // TODO make this configurable
            if (pkg != null && pkg.startsWith("com.android.launcher")) {
                return true;
            }

            return false;
        }
    }
Run Code Online (Sandbox Code Playgroud)

这可能是你的要求#2的答案.虽然它可能不适用于其他第三方发射器.

==更新==

几个月后,我突然想到如何检测主屏幕是否显示.我把它放在我的博客中,我对我的欲望进行测试,它运行正常.该方法是在Android上查询所有已安装的软件包,其中一个包含"Launcher"功能,然后检查它是否在运行堆栈的顶部.如果有人测试过,请告诉我结果,因为我无法访问其他Android设备.

  • 当在非标准主屏幕上运行时,这肯定会失败吗? (2认同)
  • 请看我更新的答案,我有一个更好的方法,应该适用于第三方. (2认同)