从最近使用的应用程序中删除应用程序后,AlarmManager 停止

AlarmManager Stops after removing app from recents apps

我是 android 这部分的新手,在这里我的目标是使用警报管理器 运行 每 2 分钟轮询一次服务器的代码片段(使用网站的 api) 并根据返回的 JSON 生成通知。 在查看网络后,我认为对我来说最好的选择之一是使用意图服务和 android.

服务和接受者清单

<service
    android:name=".NotifyService"
    android:enabled="true"
    android:exported="false" >
</service>
<receiver
    android:name=".TheReceiver"
    android:enabled="true"
    android:exported="true" >
</receiver>
<receiver
    android:name=".OnOffReceiver"
    android:enabled="true"
    android:exported="true" >
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

在闪屏 activity 中调用负责轮询通知的意图服务的部分:

Intent msgIntent = new Intent(this, NotifyService.class);
    startService(msgIntent);

在设备启动时启动警报的接收器:

public class OnOffReceiver extends BroadcastReceiver
{
    private AlarmManager alarmMgr;
    private PendingIntent alarmIntent;
    public OnOffReceiver(){}
    @Override
    public void onReceive(Context context, Intent intent)
    {
        Intent service = new Intent(context, NotifyService.class);
        service.setAction(NotifyService.CREATE);
        context.startService(service);
    }
} 

IntentServiceClass

public class NotifyService extends IntentService
{
    public NotifyService()
    {
        super("NotifyService");
    }
    public static final int STATUS_RUNNING = 0;
    public static final int STATUS_FINISHED = 1;
    public static final int STATUS_ERROR = 2;

    @Override
    protected void onHandleIntent(Intent intent)
    {
        if (intent != null)
        {
            final String action = intent.getAction();
        }
        StartStuff();
    }

    public void StartStuff()
    {
        Intent intent = new Intent(this, TheReceiver.class);
        PendingIntent pend_intent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,1200,1200, pend_intent); 
     //1200ms to make it easier to test
    }

}

设置通知的接收器class,为了测试目的,我在这里没有做任何与网络相关的工作,只是发出一个简单的通知来检查应用程序是否在所有情况下都运行ning

public class TheReceiver extends BroadcastReceiver
{
    public TheReceiver(){}
    @Override
    public void onReceive(Context context, Intent intent)
    {
         Toast.makeText(context, " Success ", Toast.LENGTH_SHORT).show();
         Log.d("Notification", "The Receiver Successful");
        showNotification(context);

    }
    private void showNotification(Context context)
    {         
        NotificationCompat.Builder mBuilder =
            new NotificationCompat.Builder(context).setContentTitle("My notification").setContentText("Hello World!");
        mBuilder.setDefaults(Notification.DEFAULT_SOUND);
        mBuilder.setAutoCancel(true);
        NotificationManager mNotificationManager =
            (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.notify(1, mBuilder.build());

    }  
} 

但是,只有当应用 运行正在运行或在最近的应用托盘中时才会收到通知。 它不会在 phone 重新启动时开始通知,也不会在应用程序从最近的应用程序托盘中删除后通知。

该应用程序需要像其他应用程序(如 gmail、whatsapp)一样通知用户,即使他们已从最近的应用程序托盘中滑出。 及时性和准时性不是很大的问题,因为延迟最多 5 到 10 分钟是可以容忍的。 (不过我打算每 2 分钟轮询一次。)

我哪里错了?另外,有没有更好的方法来解决这个问题?

如果一个应用程序被最近的应用程序或 "force stop" 杀死,它不会自行重启。用户必须再次启动该应用程序才能使其再次 运行。没有办法阻止这种情况。这就是 android 的工作方式。

不过,有一种方法可以让您的应用 运行 立即启动。查看 this link.

要在关闭应用程序后保持接收器处于活动状态,请使用

android:process=":remote"

在需要保持活动状态的接收器的清单文件中。

 <receiver
        android:name=".TheAlarmReceiver"
        android:process=":remote">
 </receiver>

在我们需要在应用程序关闭后保持活动状态的接收器(在本例中为 TheReceiver)的清单中。

P.S。 : 我还改变了我在应用程序中使用 IntentsService 和 AlarmManager 的方式,因为我以前(上面)的实现不是解决它的好方法。