Android警报管理器在应用程序被杀死时无效

时间:2018-04-20 10:12:31

标签: android

我想安排一个每1分钟发出一次警报并唤醒我的应用程序。它正在开发模拟器,但没有在VIVO,OPPO,MIUI等定制的OS手机上工作。我写了一个Sticky服务&广播接收器。当服务被销毁或TaskRemoved时,我调用了名为sendBroadcast()的方法,它将触发我的广播接收器,而我的Brodcast接收器将通过调用startservice(intent)方法再次启动服务。但是,当应用程序被杀时,这不起作用。当应用程序在Foreground时工作正常。我希望当应用程序被杀死时,Alarm Manger会工作。

这是我的代码 -

我的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);


}   }

我的粘性服务代码是 -

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

我的BroadcastReceiver如下 -

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

}}

我的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>

3 个答案:

答案 0 :(得分:14)

好吧,所以我今天个人浪费了6个小时,做了官方文档https://developer.android.com/training/scheduling/alarms.html中描述的所有事情。我还尝试了其他设置,例如-ELAPSED_REALTIME_WAKEUP,RTC_WAKEUP等。没有什么真正的帮助我,我的警报仅在打开应用程序后才起作用,并且一旦我关闭该应用程序(将其从任务栏中删除),就不会发出警报。我在这里偶然找到了解决方案-https://issuetracker.google.com/issues/150080941#comment5-我们仅在通过Studio的绿色播放按钮启动应用程序时才看到此问题,而在诸如侧面加载apk或单击时这样的独立会话中却没有看到设备上的应用图标。

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

答案 1 :(得分:7)

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

应用处于前台或后台状态: 在这种情况下,通过Android Studio的“运行”(播放)按钮安装应用程序会很好

应用被杀死: 构建APK,下载并安装到手机中,即可正常工作。通过Android Studio安装该应用程序无效。

总而言之,只需构建APK(构建->构建APK),它就可以在每种情况下使用。

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

答案 2 :(得分:1)

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

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