当应用程序被杀死时,Android 警报管理器不起作用

Roh*_*nde 9 android

我想安排一个每 1 分钟触发一次的闹钟并唤醒我的应用程序。它适用于模拟器,但不适用于定制的操作系统手机,如 VIVO、OPPO、MIUI 等。我编写了粘性服务和广播接收器。当服务将被销毁或 TaskRemoved 时,我调用了名为 sendBroadcast() 的方法,该方法将触发我的广播接收器,而我的 Brodcast 接收器将通过调用 startservice(intent) 方法再次启动服务。但这在应用程序被杀死时不起作用。当应用程序在前台时它工作正常。我希望警报管理器在应用程序被杀死时能够工作。

这是我下面的代码--

我的 MainActivity.java 文件启动服务--

public class MainActivity extends AppCompatActivity
{

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Intent alarmIntent = new Intent(this, AlarmService.class);
    startService(alarmIntent);


}   }
Run Code Online (Sandbox Code Playgroud)

我的粘性服务代码是——

public class AlarmService extends Service
{

private String TAG ="AlarmService";
@Override
public void onCreate()
{
    sendBroadcast();
    super.onCreate();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
    Log.e(TAG, "onStartCommand");
    //return super.onStartCommand(intent, flags, startId);
    return Service.START_STICKY;
}


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


@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}


@Override
public void onTaskRemoved(Intent rootIntent) {
    sendBroadcast();
    super.onTaskRemoved(rootIntent);
}

private void sendBroadcast()
{
    Intent intent = new Intent(this,AlarmReceiver.class);
    //intent.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(
            this.getApplicationContext(), 234324243, intent, 0);
    AlarmManager alarmManager = (AlarmManager) getApplicationContext().getSystemService(ALARM_SERVICE);

    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 5);
    if (alarmManager != null)
    {
        //System.currentTimeMillis() + (i * 100),
        alarmManager.setRepeating(
                AlarmManager.RTC_WAKEUP,
                System.currentTimeMillis(),
                60000,
                pendingIntent);
    }
}}
Run Code Online (Sandbox Code Playgroud)

我的广播接收器如下——

public class AlarmReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
    // For our recurring task, we'll just display a message
    Toast.makeText(context, "I'm running", Toast.LENGTH_LONG).show();
    generateNotification(context);

    //restartJobScheduler(context);
    if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.O) restartJobScheduler(context);
    else restartService(context);

}

private void restartJobScheduler(Context context)
{
    Log.i("MyBroadCastReceiver", "onReceive");
    //context.startForegroundService(service);
    FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(context));
    Job myJob = dispatcher.newJobBuilder()
            .setService(MyJobService.class)
            .setTag("myFCMJob")
            .build();
    dispatcher.mustSchedule(myJob);
}

private void restartService(Context context)
{
    Intent restartServiceIntent = new Intent(context, AlarmService.class);
    context.startService(restartServiceIntent);

}}
Run Code Online (Sandbox Code Playgroud)

我的 Android.Manifest 文件如下---

<receiver android:name=".AlarmReceiver">
        <intent-filter>

            <action android:name="android.intent.action.BOOT_COMPLETED" />

        </intent-filter>
    </receiver>

    <service
        android:name=".MyJobService"
        android:exported="false"
        android:stopWithTask="false">
        <intent-filter>
            <action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE" />
        </intent-filter>
    </service>

    <service android:name=".AlarmService"
        android:exported="false"
        android:label="Alarm Service"
        android:stopWithTask="false">

        <intent-filter>
            <action android:name="com.example.tas9.alarmmanager.AlarmService" />
        </intent-filter>

    </service>
Run Code Online (Sandbox Code Playgroud)

小智 17

好的,所以我今天个人浪费了 6 个小时,做官方文档中描述的一切 - https://developer.android.com/training/scheduling/alarms.html。我还尝试了不同的设置,如 - ELAPSED_REALTIME_WAKEUP、RTC_WAKEUP 等。没有什么能真正帮助我,我的闹钟只有在应用程序打开时才起作用,而且一旦我关闭应用程序(从任务栏中删除它),就不会触发任何闹钟。我在这里偶然找到了解决方案 - https://issuetracker.google.com/issues/150080941#comment5 - 我们只有在通过工作室的绿色播放按钮启动应用程序时才会看到这一点,而不是在独立会话中例如在旁加载 apk 或单击设备上的应用程序图标时。

TL;DR - 尝试通过旁加载 apk 来测试您的警报管理器功能,而不是通过 Android Studio 中的绿色播放按钮启动它。

  • 拯救了这一天,伙计! (2认同)

小智 12

问题在于方式,您正在尝试安装该应用程序。

应用程序处于前台或后台状态: 在这种情况下,通过 Android Studio 的运行(播放)按钮安装应用程序将正常工作

应用程序被杀死: 构建APK,下载并安装到您的手机中,它会正常工作。通过 Android Studio 安装应用程序将不起作用。

总而言之,只需构建 APK(构建 --> 构建 APK),它就可以在任何场景下工作。

这只是@nvr 对上述答案的澄清

  • 这是我成功销毁3小时后的解决方案 (2认同)

Dav*_*ser 9

在某些设备上,您需要手动将您的应用添加到允许在后台运行的应用列表中。否则,即使使用 "sticky" Service,Service一旦进程被终止,Android 也不会重新启动。制造商这样做是为了节省电池寿命。

在设置中,应该有一种方法可以将您的应用添加到“受保护的应用”或“允许在后台运行的应用”列表中。查看电源管理设置或应用程序设置。