簡體   English   中英

當應用程序被殺死時,Android 警報管理器不起作用

[英]Android Alarm Manager Not working when app is Killed

我想安排一個每 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);


}   }

我的粘性服務代碼是——

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

我的廣播接收器如下——

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>

好的,所以我今天個人浪費了 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 中的綠色播放按鈕啟動它。

問題在於方式,您正在嘗試安裝該應用程序。

應用程序處於前台或后台狀態:在這種情況下,通過 Android Studio 的運行(播放)按鈕安裝應用程序將正常工作

應用程序被殺死:構建APK,下載並安裝到您的手機中,它會正常工作。 通過 Android Studio 安裝應用程序將不起作用。

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

這只是@nvr 對上述答案的澄清

在某些設備上,您需要手動將您的應用添加到允許在后台運行的應用列表中。 否則,即使使用“粘性” Service ,一旦進程被終止,Android 也不會重新啟動Service 制造商這樣做是為了節省電池壽命。

在設置中,應該有一種方法可以將您的應用添加到“受保護的應用”或“允許在后台運行的應用”列表中。 查看電源管理設置或應用程序設置。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM