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

sky*_*sky 1 android alarmmanager android-service intentservice android-background

我是android的新手,在这里我的目标是使用警报管理器每2分钟运行一个代码段,该代码段将轮询服务器(使用网站的api),并基于返回的JSON生成通知。上网查找后,我认为最好的选择之一就是使用Intent服务和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>
Run Code Online (Sandbox Code Playgroud)

在Flash屏幕活动的一部分中,我将其称为意图服务,该服务负责轮询通知:

Intent msgIntent = new Intent(this, NotifyService.class);
    startService(msgIntent);
Run Code Online (Sandbox Code Playgroud)

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

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);
    }
} 
Run Code Online (Sandbox Code Playgroud)

IntentService类别

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
    }

}
Run Code Online (Sandbox Code Playgroud)

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

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());

    }  
} 
Run Code Online (Sandbox Code Playgroud)

但是,仅当应用程序正在运行或在最近的应用程序托盘中时,才会发出通知。它不会开始通知手机何时重启,也不会在从最近的应用程序托盘中删除该应用程序后发出通知。

该应用程序需要像其他应用程序(例如gmail,whatsapp)一样通知用户,即使将其从最近的应用程序栏中刷除也是如此。及时性和守时性不是一个很大的问题,因为可以忍受5到10分钟的延迟。(不过,我打算每2分钟进行一次投票。)

我要去哪里错了?另外,是否有更好的方法来解决该问题?

sky*_*sky 6

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

android:process=":remote"
Run Code Online (Sandbox Code Playgroud)

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

 <receiver
        android:name=".TheAlarmReceiver"
        android:process=":remote">
 </receiver>
Run Code Online (Sandbox Code Playgroud)

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

PS:我还更改了对应用程序使用IntentsService和AlarmManager的方式,因为以前的(以上)实现不是解决它的好方法。