【问题标题】:sendWakefulWork not always called with cwac-wakeful-1.1.0sendWakefulWork 并不总是使用 cwac-wakeful-1.1.0 调用
【发布时间】:2016-12-23 12:30:25
【问题描述】:

我有一个问题很久了,我发现了 cwac-wakeful,它可以解决我所有的问题。我想... :'( 简而言之,为了解决这个问题,我实现了一个最简单的应用程序,它每 60 秒安排一次警报,并且每次都记录一次。 这是我的代码:

主要活动:

package com.par.hasard.mysimpleapplication;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button)findViewById(R.id.myExportButton);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                MyLogManager.copyLogToClipboard(view.getContext());
                MyLogManager.emptyLogFile(view.getContext());
            }
        });
        try {
            MyLogManager.createLogFile(this);
            MyLogManager.write(this, "Application launched\n");
            MyAlarmPlanner.planAlarm_v2(this);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

MyAlarmPlanner:

package com.par.hasard.mysimpleapplication;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.SystemClock;
import android.widget.Toast;
import com.commonsware.cwac.wakeful.WakefulIntentService;
import java.io.IOException;

public class MyAlarmPlanner {
    public static void planAlarm_v2(Context context) throws IOException {
        MyLogManager.write(context, "Beginning of planAlarm_v2\n");
        WakefulIntentService.scheduleAlarms(new MyAppListener(), context, true);
        MyLogManager.write(context, "End of planAlarm_v2\n");
    }
}

MyAppListener:

package com.par.hasard.mysimpleapplication;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.os.SystemClock;

import com.commonsware.cwac.wakeful.AlarmReceiver;
import com.commonsware.cwac.wakeful.WakefulIntentService;

import java.io.IOException;

public class MyAppListener implements WakefulIntentService.AlarmListener {
    @Override
    public void scheduleAlarms(AlarmManager alarmManager, PendingIntent pendingIntent, Context context) {
        try {
            MyLogManager.write(context, "Beginning of scheduleAlarms\n");
            alarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+60000, pendingIntent);
            MyLogManager.write(context, "End of scheduleAlarms\n");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void sendWakefulWork(Context context) {
        try {
            MyLogManager.write(context, "Beginning of sendWakefulWork\n");
            WakefulIntentService.sendWakefulWork(context, MyAppService.class);
            MyLogManager.write(context, "End of sendWakefulWork\n");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public long getMaxAge(Context context) {
        return (AlarmManager.INTERVAL_FIFTEEN_MINUTES * 2);
    }
}

我的应用服务:

package com.par.hasard.mysimpleapplication;
import android.content.Intent;
import com.commonsware.cwac.wakeful.WakefulIntentService;
import java.io.IOException;

public class MyAppService extends WakefulIntentService {
    public MyAppService(){
        super("MyAppService");
    }

    @Override
    protected void doWakefulWork(Intent intent) {
        try {
            MyLogManager.write(this, "Beginning of doWakefulWork\n");
            MyAlarmPlanner.planAlarm_v2(this);
            MyLogManager.write(this, "End of doWakefulWork\n");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.par.hasard.mysimpleapplication">
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver android:name="com.par.hasard.mysimpleapplication.MySimpleWakefulReceiver">
            <intent-filter android:priority="1">
                <action android:name="com.par.hasard.mysimpleapplication.REGULAR_ALARM" />
            </intent-filter>
        </receiver>

        <receiver android:name="com.commonsware.cwac.wakeful.AlarmReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>

            <meta-data
                android:name="com.commonsware.cwac.wakeful"
                android:resource="@xml/wakeful"/>
        </receiver>
        <service android:enabled="true" android:name="com.par.hasard.mysimpleapplication.MySimpleWakefulService" />
        <service android:enabled="true" android:name="com.par.hasard.mysimpleapplication.MyAppService" />
    </application>

</manifest>

wakeful.xml:

<WakefulIntentService
    listener="com.par.hasard.mysimpleapplication.MyAppListener"
    />

所有这些都可以完美运行,但有时它不会记录任何内容。我认为这是由于我的手机(Sony Xperia)的睡眠模式。但它似乎在其他手机上具有相同的行为。 以下是日志示例:

18/12 2h47m37s304 => Beginning of sendWakefulWork
18/12 2h47m37s311 => End of sendWakefulWork
18/12 2h47m37s316 => Beginning of doWakefulWork
18/12 2h47m37s317 => Beginning of planAlarm_v2
18/12 2h47m37s320 => Beginning of scheduleAlarms
18/12 2h47m37s322 => End of scheduleAlarms
18/12 2h47m37s323 => End of planAlarm_v2
18/12 2h47m37s324 => End of doWakefulWork
18/12 2h48m37s332 => Beginning of sendWakefulWork
18/12 2h48m37s338 => End of sendWakefulWork
18/12 2h48m37s347 => Beginning of doWakefulWork
18/12 2h48m37s348 => Beginning of planAlarm_v2
18/12 2h48m37s350 => Beginning of scheduleAlarms
18/12 2h48m37s351 => End of scheduleAlarms
18/12 2h48m37s352 => End of planAlarm_v2
18/12 2h48m37s353 => End of doWakefulWork
18/12 3h35m6s293 => Beginning of sendWakefulWork    //nothing before ??
18/12 3h35m6s298 => End of sendWakefulWork
18/12 3h35m6s319 => Beginning of doWakefulWork
18/12 3h35m6s327 => Beginning of planAlarm_v2
18/12 3h35m6s331 => Beginning of scheduleAlarms
18/12 3h35m6s338 => End of scheduleAlarms
18/12 3h35m6s340 => End of planAlarm_v2
18/12 3h35m6s345 => End of doWakefulWork
18/12 3h36m7s307 => Beginning of sendWakefulWork
18/12 3h36m7s313 => End of sendWakefulWork
18/12 3h36m7s319 => Beginning of doWakefulWork
18/12 3h36m7s320 => Beginning of planAlarm_v2
18/12 3h36m7s322 => Beginning of scheduleAlarms
18/12 3h36m7s323 => End of scheduleAlarms
18/12 3h36m7s324 => End of planAlarm_v2
18/12 3h36m7s325 => End of doWakefulWork

有人可以帮我吗?

【问题讨论】:

    标签: android alarmmanager sony commonsware-cwac sony-xperia


    【解决方案1】:

    就时间间隔而言,您很可能正在 Android 6.0+ 设备上体验打盹模式,或者某些制造商在旧设备上提供的等效模式(例如 SONY 的 STAMINA 模式)。除了将您的应用添加到适当的白名单中(例如,对于打盹,设置 > 应用 >(齿轮图标)> 特殊访问 > 电池优化),您可以做的很少。

    欢迎您在 API 级别 23+ 设备上切换到 setExactAndAllowWhileIdle(),但是:

    • 你不会每分钟都得到控制(我认为它仅限于每 9 分钟)

    • 当您获得控制权时,您将无法访问 Internet(这可能是您真正尝试做的任何事情所必需的)

    • 这对于制造商特定的 6.0 之前的设备没有帮助(因为该方法不存在)

    总体而言,将您的应用设计为处理打盹模式,而不是假设它会在后台获得太多控制,是一种更可靠的方法。

    【讨论】:

    • 感谢您的回答!我只是将我的应用程序设置在白名单中(我不知道电池优化菜单)并启动它。我希望这能解决问题。但是,我同意你的看法,我宁愿编写一些没有参数化也可以工作的代码。最烦人的是 9 分钟的间隔......但是如果我在 T-10 时间安排一个 alarmManage,doWakefulWork 可以在 T-10 和 T-1 之间触发,然后我可以在 T 再次安排。再次感谢,您为我开辟了新的道路!我会及时通知你我的进展。
    • 我刚刚明白 9 分钟间隔是什么意思...只要设备不处于打瞌睡模式,doWakefulWork 就会每分钟触发一次,但是在打瞌睡时,它可以在正确的时间,但下一个将是 9 分钟后。明天早上我会用我的日志得到确认...
    • 咳咳...昨天,我将我的应用设置在白名单中,只是为了测试。但这并没有改变什么。 50 分钟无活动,然后 80、110、110 和 140 分钟。是否必须重新启动设备才能应用白名单更改?但是,我将使用 setExactAndAllowWhileIdle 进行测试。
    • 祝大家圣诞快乐!好消息,setExactAndAllowWhileIdle 真的更好!有了它和我的应用程序在白名单上,我仍然有时间差距,但最多 15 分钟。所以,这就是你解释的,设备在正确的时间以打盹模式唤醒,但下一个必须等​​待 15 分钟。我会尝试在白名单上没有应用程序,但无论如何,我认为你解决了我的问题。非常感谢!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-23
    • 2011-05-29
    • 2015-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多