意图服务在打瞌睡模式下不工作

2023-12-12

我的一位同行开发人员写了一篇intent service进行 API 调用,然后休眠 2 分钟。醒来后,再次发送。

下面是代码:

public class GpsTrackingService extends IntentService {

....

@Override
    protected void onHandleIntent(Intent intent) {
      do{
        try{
          //make API call here

           //then go to sleep for 2 mins
          TimeUnit.SECONDS.sleep(120);
       
        } catch(InterruptedException ex){
            ex.printStackTrace();
        }
      } while (preferences.shouldSendGps()); //till the user can send gps.

    }

....

}


Manifest

<service android:name=".commons.GpsTrackingService" />

当手机处于活动状态时,此功能工作正常。但是,每当手机进入休眠模式时,它就无法唤醒。

将使用报警管理器WAKE permission解决这个问题吗?

我刚刚获得了代码库,需要在今天内修复这个问题。如果有人能帮忙那就太好了。


As the 文档 says:

在打瞌睡模式下,系统尝试通过限制 应用程序对网络和 CPU 密集型服务的访问。它还可以防止 应用程序访问网络并推迟其作业、同步和 标准警报。

系统会定期退出 Doze 状态一段时间,让应用程序 完成他们推迟的活动。在此维护窗口期间, 系统运行所有待处理的同步、作业和警报,并让应用程序 访问网络。

简而言之,在 Doze 模式下,系统暂停网络访问、忽略唤醒锁、停止从传感器获取数据、将 AlarmManager 作业推迟到下一个 Doze 维护时段(调用频率逐渐降低),并且 WiFi 扫描、JobScheduler 作业和同步适配器也不会运行.

对于每个应用程序,setAndAllowWhileIdle() 和 setExactAndAllowWhileIdle() 都不能每 9(?) 分钟多次触发警报。

看来前台服务也参与了这场“打瞌睡的戏剧”,至少在 MarshMellow (M) 中是这样。

为了在这种情况下生存,至少需要审查大量的申请。您能想象一个简单的 mp3 播放器在设备进入打瞌睡模式时停止播放音乐吗?

当设备拔掉电源并放在桌子上大约 1 小时左右时,或者甚至更早,当用户单击电源按钮关闭屏幕时,打瞌睡模式会自动启动,但我认为这可能取决于设备制造商也是如此。

我尝试了很多对策,其中一些真的很搞笑。

在测试结束时,我得出了一个可能的解决方案:

即使主机设备处于打瞌睡模式,也可以让应用程序运行的一种可能(也可能是唯一)的方法基本上是有一个前台服务(即使是假的,根本不做任何工作)运行另一个过程具有后天获得的部分唤醒锁定.

您需要做的基本上如下(您可以创建一个简单的项目来测试它):

  • 1 - 在您的新项目中,创建一个扩展应用程序 (myApp) 的新类,或使用 新项目的主要活动。
  • 2 - 在 myApp onCreate() 中启动一个服务 (myAntiDozeService)
  • 3 - 在 myAntiDozeService onStartCommand() 中,创建通知 需要将服务启动为前台服务,启动 使用 startForeground(id, notification) 的服务并获取 部分唤醒锁。

记住!这会起作用,但这只是一个起点,因为您必须小心此方法将产生的“副作用”:

  • 1 - 电池消耗:CPU 将永远为您的应用程序工作,如果您 不要使用某些策略并让 WakeLock 始终处于活动状态。

  • 2 - 即使在锁定屏幕中,也将始终显示一条通知, 而且这个通知不能通过简单地滑动来删除,它 将一直存在,直到您停止前台服务。

好的,让我们一起做。

myApp.java

    public class myApp extends Application {
    private static final String STARTFOREGROUND_ACTION = "STARTFOREGROUND_ACTION";
    private static final String STOPFOREGROUND_ACTION = "STOPFOREGROUND_ACTION";

        @Override
        public void onCreate() {

            super.onCreate();            

            // start foreground service
            startForeService();
    }

    private void stopForeService() {
        Intent service = new Intent(this, myAntiDozeService.class);
        service.setAction(STOPFOREGROUND_ACTION);
        stopService(service);
    }

    private void startForeService(){
        Intent service = new Intent(this, myAntiDozeService.class);
        service.setAction(STARTFOREGROUND_ACTION);
        startService(service);
    }

    @Override
    public void onTerminate() {
        stopForeService();
        super.onTerminate();
    }
}

myAntiDozeService.java

public class myAntiDozeService extends Service {

    private static final String TAG = myAntiDozeService.class.getName();
    private static boolean is_service_running = false;
    private Context mContext;
    private PowerManager.WakeLock mWakeLock;
    private static final int NOTIFICATION_ID = 12345678;
    private static final String STARTFOREGROUND_ACTION = "STARTFOREGROUND_ACTION";
    private static final String STOPFOREGROUND_ACTION = "STOPFOREGROUND_ACTION";

    @Override
    public void onCreate() {
        super.onCreate();
        mContext = getApplicationContext();

    }

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

        if (!is_service_running && STARTFOREGROUND_ACTION.equals(intent.getAction())) {
            Log.i(TAG, "Received Start Foreground Intent ");
            showNotification();
            is_service_running = true;
            acquireWakeLock();

        } else if (is_service_running && STOPFOREGROUND_ACTION.equals(intent.getAction())) {
            Log.i(TAG, "Received Stop Foreground Intent");
            is_service_running = false; 
            stopForeground(true);
            stopSelf();
        }

        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        releaseWakeLock();
        super.onDestroy();
    }

    private void showNotification(){

        Intent notificationIntent = new Intent(mContext, ActivityMain.class);
        notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, notificationIntent, 0);

        Notification notification = new NotificationCompat.Builder(mContext)
                .setContentTitle("myApp")
                .setTicker("myApp")
                .setContentText("Application is running")
                .setSmallIcon(R.drawable.ic_launcher)
                .setContentIntent(pendingIntent)
                .build();

        // starts this service as foreground
        startForeground(NOTIFICATION_ID, notification);
    }

    public void acquireWakeLock() {
        final PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        releaseWakeLock();
        //Acquire new wake lock
        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG+"PARTIAL_WAKE_LOCK");
        mWakeLock.acquire();
    }

    public void releaseWakeLock() {
        if (mWakeLock != null && mWakeLock.isHeld()) {
            mWakeLock.release();
            mWakeLock = null;
        }
    }
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

AndroidManifest.xml 更改。


在 AndroidManifest.xml 中添加此权限:

<uses-permission android:name="android.permission.WAKE_LOCK" />

不要忘记在中添加您的应用程序的名称<application> tag:

<application
        ....
        android:name=".myApp"
        ....

最后将运行的前台服务添加到另一个进程中:

   <service
        android:name=".myAntiDozeService"
        android:process=":MyAntiDozeProcessName">
    </service>

一些注释。

  • 在前面的示例中,单击时创建的通知, 打开测试项目的 ActivityMain 活动。

    Intent notificationIntent = new Intent(mContext, ActivityMain.class);

    但你也可以使用另一种意图。

  • 要测试它,您必须添加一些要执行的作业到您的 ActivityMain.java,例如一些重复闹钟(这是 当设备进入打瞌睡模式时通常会停止),或者成熟 网络访问,或者播放定时提示音,或者......任何你想要的。
  • 请记住,主要活动执行的作业必须运行 永远因为要测试此 AntiDoze,您需要等待至少 1 小时以确保设备进入打瞌睡模式。
  • 要进入打瞌睡模式,设备必须保持安静并拔掉插头,因此 调试时无法测试它。首先调试您的应用程序, 检查一切是否正在运行,然后停止它,拔掉插头,重新启动 再次应用程序,然后将设备安静地放在办公桌上。

  • The adb文档建议的命令模拟打瞌睡 和待机模式可以或不能给你正确的结果 (我想,这取决于设备制造商、驱动程序、bla 布拉)。请以真实行为进行测试。

在我的第一个测试中,我使用 AlarmManager 和音频发生器每 10 分钟播放一次音调,只是为了了解我的应用程序仍然处于活动状态。 从大约 18 小时开始,它仍然在运行,每隔 10 分钟就会发出一声响亮的声音,让我的耳朵受伤。 :-)

快乐编码!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

意图服务在打瞌睡模式下不工作 的相关文章

  • 如何从该 JAVA 文件中提取 Delphi 类以与 Android 一起使用?

    我的Delphi XE7项目需要与FTDI FT311 Android 配件芯片 http www ftdichip com Products ICs FT311D html 他们帮助提供了一个 Android 演示 其中包括他们的 JAV
  • 如何在 ADB 连接期间禁用电池充电?

    问题描述 每次我在电脑和手机之间连接 USB 线时 电池都会自动充电 我想使用 ADB 协议 但我不想在 ADB 连接期间为电池充电 是否可以关闭此充电功能 当然 我该怎么做呢 环境 Android 操作系统 4 及更高版本的手机 我只需要
  • Android 中的 Sugar ORM:更新 SQLite 中保存的对象

    我是在 Android 上使用 SQLite 和 Sugar ORM 进行应用程序开发的新手 并尝试阅读 Sugar ORM 文档 但没有找到有关如何更新 SQLite 中保存的对象的任何信息 更改对象属性后还可以保存对象吗 就像是 Cus
  • android中根据屏幕尺寸计算图像尺寸

    我正在尝试根据屏幕尺寸计算图像高度和宽度 我从后端获取 5 x 7 尺寸的图像 为了将像素乘以 72 进行转换 我有 360 X 504 尺寸的图像 对于 360 X 504 我的动态透明矩形区域将显示为 1 223 x 1 179 即 8
  • onScale 事件后触发奇怪的 onScroll 事件

    我有一个同时使用 SimpleOnScaleGestureListener 和 SimpleOnGestureListener 的应用程序 每当我进行捏缩放时 我都会得到预期的 onScale 但是当我抬起时 我会看到一个奇怪的 onScr
  • Android:如何使用后台线程?

    我开发了一个应用程序 它从互联网获取内容并相应地在设备的屏幕上显示它 该程序运行得很好 就是有点慢 加载并显示内容大约需要 3 4 秒 我想将获取内容并将其显示在后台线程中的所有代码放在一起 当程序执行这些功能时 我想显示一个进度对话框 你
  • Android中如何检测WIFI连接何时建立?

    我需要检测何时通过 WIFI 建立网络连接 发送什么广播来确定已建立有效的网络连接 我需要验证是否存在有效的 HTTP 网络连接 我应该监听什么以及需要进行哪些额外测试才能知道是否存在有效连接 您可以注册一个BroadcastReceive
  • 在选项卡上保存数据

    我有 3 个选项卡 每个选项卡都有一个单独的活动 我想在用户单击任一选项卡上的 保存 时保存数据 有几个选项可供选择 共享首选项 全局变量或将对象保存在上下文中 编辑 我必须保存图像和文本字段 Android 共享首选项 https sta
  • 使用 Android Studio 进行调试永远停留在“等待调试器”状态

    UPDATE The supposed重复是一个关于陷入 等待调试器 执行时Run 而这个问题就陷入了 等待调试器 执行时Debug 产生问题的步骤不同 解决方案也不同 每当我尝试使用Android Studio的调试功能时 运行状态总是停
  • Emma 不生成coverage.ec

    我设置了艾玛 它曾经对我有用 然后我们更改了源代码 现在它没有生成coverage ec根本不 它确实生成coverage em 测试临近结束时 出现错误消息 exec INSTRUMENTATION CODE 0 echo Downloa
  • 像 WhatsApp 一样发送图片

    我做了一个聊天应用程序 我想添加照片 文件共享我的应用程序中的概念与 WhatsApp 相同 我已经使用该应用程序制作了Xmpp Openfire目前我正在使用此功能进行照片共享 但它并不完全可靠 public void sendFile
  • Android 纹理仅显示纯色

    我正在尝试在四边形上显示单个纹理 我有一个可用的 VertexObject 它可以很好地绘制一个正方形 或任何几何对象 现在我尝试扩展它来处理纹理 但纹理不起作用 我只看到一种纯色的四边形 坐标数据位于 arrayList 中 the ve
  • 有多少种方法可以将位图转换为字符串,反之亦然?

    在我的应用程序中 我想以字符串的形式将位图图像发送到服务器 我想知道有多少种方法可以将位图转换为字符串 现在我使用 Base64 格式进行编码和解码 它需要更多的内存 是否有其他可能性以不同的方式做同样的事情 从而消耗更少的内存 现在我正在
  • 屏幕开/关检测

    在这里 我试图确定屏幕是否打开 但按下电源锁定 解锁按钮时它似乎不起作用 应用程序运行没有错误 但 if else 中的代码似乎没有效果 Edited现在代码可以工作了 谢谢Olgun 但媒体播放器播放不会停止 并且每次在屏幕上 离屏时都会
  • 我在 PopupMenu 中使用 ShareActionProvider,但显示两个 PopupMenu?

    我在 PopupMenu 中使用 ShareActionProvider 但是当我单击共享菜单项时 它会在屏幕上显示两个 PopupMenus 一个被另一个覆盖 一个显示应用程序图标和名称 另一个仅显示应用程序名称 除了这个问题之外 它工作
  • Activity 类型中的方法 showDialog(int) 在 Android 中已被弃用?

    方法showDialog int 从类型Activity is 已弃用 什么原因 以及如何解决 什么原因 http developer android com reference android app Activity html show
  • 在 Android 手机中通过耳机插孔发送数据

    我目前正在处理一个新项目 我必须通过具有特定电压的耳机插孔发送数据 然后我可以在该电压上工作 所以这里我需要根据我的数据来编程具体电压 我是否可以在android中访问耳机的输出电压 然后创建一个应用程序来控制该电压 这是一篇讨论此问题的
  • Flash 对象未显示在phonegap android 中

    我已经在 android 手机间隙创建了一个应用程序 我有一个屏幕 我想显示一个静态 flash obj 所以我在屏幕 HTML 页面中放入了以下代码
  • 为什么带处理程序的连续自动对焦相机不允许切换相机闪光灯?

    到目前为止我所做的 我已经实现了用于读取二维码的自定义相机 需要继续聚焦相机以获得更好的二维码读取 我的问题当我使用处理程序每 秒聚焦一次时 相机闪光灯开 关按钮不起作用 或者打开和关闭相机闪光灯需要太多时间 当我删除每秒自动对焦相机的代码
  • 将焦距(以毫米为单位)转换为像素 - Android

    在 Android 中 我当前正在访问camera s焦距通过使用getFocalLength in Camera1 Camera2不是一个选择 我正在尝试完全填充当前的计算 focal length pix focal length m

随机推荐

  • 使用地图的地图作为 Maven 插件参数

    是否可以使用地图的地图作为 Maven 插件参数 Parameter private Map
  • 如何编辑默认的 Xcode 模板?

    当我创建 NSObject 子类时 我总是得到一个空的实现 我总是在代码中放入一些东西 例如编译指示和 dealloc 方法 我更喜欢直接删除不需要的东西 而不是每次需要的时候都从头开始写错字 我几乎总是需要 dealloc 和 init
  • 如何从 RepaintManager 生成异常

    与我的联系question may be 我发现了另一种异常类型 我无法捕获并打印出来SwingWorker thread 我怎样才能生成RepaintManager例外情况 我读了这个CheckThreadViolationRepaint
  • 字符串比较结果 b/w == 和 String#replace with == 的差异[重复]

    这个问题在这里已经有答案了 可能的重复 Java 中的字符串比较和字符串驻留 我对 Java 中的字符串比较有一点疑问 请考虑以下代码 if String replace t T String replace t T System out
  • x64 上的 Visual Studio 2015 和 tesseract 3.05

    嗯 我真的需要帮助 我的问题是如何将 tesseract 3 05 和 leptonica 1 73 库添加到 Visual Studio 2015 x64 Windows 10 去年夏天 我设法使用 Visual Studio 2013
  • 使用 XSLT 作为 XML 预处理器

    这是我第一次使用 XSLT 或 XML 做任何事情 所以请原谅 我发现 XSLT Web 文档非常简洁 我有一个 XML 文件 我想要对其进行处理 以根据输入的定义集有选择地删除内容 该行为应该类似于处理 ifdef 块的简单代码预处理器
  • asyncio 事件循环可以在后台运行而不暂停 Python 解释器吗?

    asyncio 的文档给出了如何每两秒打印一次 Hello World 的两个示例 https docs python org 3 library asyncio eventloop html asyncio hello world cal
  • Firefox 上奇怪的页面错误

    我在用着Choosen and 推特引导程序在我的项目中 这是jsfiddle http jsfiddle net Wexcode 7HLyZ 3 尝试在 2 个浏览器上打开此 jsFiddle Firefox 和 Chrome 在 chr
  • 使用泛型链接任务

    我正在尝试创建一个用于链接任务的 API 首先 我设计了一个非常简单的界面来定义任务 public interface Task
  • Azure DevOps 服务器上的批处理命令 vcvarsall.bat 出现“输入行太长”错误

    我正在 Azure DevOps 服务器管道上运行批处理文件作为批处理脚本任务 此批处理文件在内部调用英特尔并行工作室编译器 2019 更新 3 如下所示 if ERRORLEVEL NEQ 0 call ICPP COMPILER19 b
  • 如何更改悬停时的文本框内容

    我无法弄清楚如何使文本框根据悬停在哪个链接上来更改内容 我可以让它与最接近 div 的任何一个一起工作 但其他链接似乎没有效果 然而 我不想在链接之间插入文本 也不想创建多个文本框 我的主要目标是让链接始终位于同一位置 当您将鼠标悬停在链接
  • Python 如何处理全局变量?

    我在 Python 中遇到过一些非常奇怪的全局变量处理方式 我希望有人能够解释并证明这些惊喜的合理性 A 此代码按预期打印 10 def func print a a 10 func B 此代码抛出有关过早引用 a 的异常 def func
  • Eclipse 条件调试

    我想知道是否有办法在调试时在 eclipse 中添加条件断点 示例 of city New York 然后中断 是的 右键单击断点 选择 断点属性 启用 条件 然后输入条件 注意city New York 由于 Java 中相等的工作方式
  • 重塑存储在集合中的数组并导出为 CSV

    我有一个 Facebook 页面点赞的集合 标题为页面赞数 存储在 Mongo 数据库 JSON 文件中 以下是一个条目的示例 id ObjectId 4725bf8731b8faf4c04595bb user id 0939bf9w980
  • Bash 中按数字文件名排序的 erge 文本文件

    有没有一种方法可以使用一个 bash 命令按文件名的数字顺序连接多个文本文件 我尝试了这个 但由于某种原因 前三行不按顺序 sort n txt gt all txt 添加这个答案只是因为目前接受的答案建议不好的做法 未来 Hellmar
  • CSS 旋转后 Firefox 中的抗锯齿文本

    所以我读了很多关于旋转文本的当前状态的文章 并且无法在所有浏览器中完美地实现真正的抗锯齿功能 它在 Chrome 中看起来像图片中的第一个框 但在 Firefox 中看起来像第二个锯齿状框 我尝试过最流行的修复程序 包括 webkit ba
  • 获取父级的类型

    给定以下课程 template
  • 无法查询表存储中的日期时间列

    我已使用逻辑应用程序中的 formatDateTime 将一列插入到表存储中 并输入正确的值 并且当我查看记录时 列类型显示为 DateTime 但是 当我尝试查询此字段时 它默认为字符串 即使我将其更改为 DateTime 也不会返回任何
  • 为什么编译 Bootstrap 3 RC1 时会出现 Grunt / Recess 错误,而 Lessc 不会出现错误?

    我向 mixins less 添加一些代码 img extend img responsive 也可以看看 Twitter Bootstrap 3 中的图像默认不响应 and https stackoverflow com a 155732
  • 意图服务在打瞌睡模式下不工作

    我的一位同行开发人员写了一篇intent service进行 API 调用 然后休眠 2 分钟 醒来后 再次发送 下面是代码 public class GpsTrackingService extends IntentService Ove