java - 即使使用 START_STICKY,Android 也不会重新创建服务

标签 java android

我正在尝试创建一项服务并通过它设置警报。我需要在后台运行该服务,以保持广播接收器运行,即使应用程序已关闭。我尝试使用 START_STICKY,在单独的子进程以及全局进程中运行服务,但一切都是徒劳的。我该怎么办?

报警.java

package com.simpleapps.simpleweather;
import ...

public class Alarm extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        ToneGenerator toneGen1 = new ToneGenerator(AudioManager.STREAM_MUSIC, 100);
        toneGen1.startTone(ToneGenerator.TONE_CDMA_PIP,150);
        Toast.makeText(context, "Alarm !!!!!!!!!!", Toast.LENGTH_LONG).show();
    }

    public void setAlarm(Context context)
    {
        Log.d("Alarm","Started");
        AlarmManager am =( AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        Intent i = new Intent(context, Alarm.class);
        PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
        am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60, pi); // Millisec * Second * Minute
    }

    public void cancelAlarm(Context context)
    {
        Intent intent = new Intent(context, Alarm.class);
        PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        alarmManager.cancel(sender);
    }
}

HelloService.java

package com.simpleapps.simpleweather;
import ...

public class HelloService extends Service
{
    Alarm alarm = new Alarm();
    public void onCreate()
    {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        Log.d("Alarm","New Service");
        alarm.setAlarm(this);
        return START_STICKY;
    }

    @Override
    public void onStart(Intent intent, int startId)
    {
        alarm.setAlarm(this);
    }

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

Manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.simpleapps.simpleweather">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".today_details" />
        <activity android:name=".forecast_details"/>
        <receiver android:process=":remote" android:name=".Alarm" android:exported="true">
        </receiver>

        <service
            android:name=".HelloService"
            android:enabled="true">
        </service>

    </application>

</manifest>

启动服务 -

Intent intent = new Intent(this, HelloService.class);
startService(intent);

更新:它适用于除我的 Lollipop 5.0 设备 AsusZenfone2 之外的所有设备。

最佳答案

我已经尝试过你的代码,它在模拟器上运行正常。我注意到的一件事是:

 * setRepeating
 * <b>Note:</b> Beginning in API 19, the trigger time passed to this method
 * is treated as inexact: the alarm will not be delivered before this time, but
 * may be deferred and delivered some time later.  The OS will use
 * this policy in order to "batch" alarms together across the entire system,
 * minimizing the number of times the device needs to "wake up" and minimizing
 * battery use.  In general, alarms scheduled in the near future will not
 * be deferred as long as alarms scheduled far in the future.

所以我将警报更改为如下所示(这只是说明,您可以在没有静态字段的情况下做到这一点):

public class Alarm extends BroadcastReceiver
{
    private static boolean sAlarmCanceled = false;

    @Override
    public void onReceive(Context context, Intent intent)
    {
        if (sAlarmCanceled)
            return;


        ToneGenerator toneGen1 = new ToneGenerator(AudioManager.STREAM_MUSIC, 100);
        toneGen1.startTone(ToneGenerator.TONE_CDMA_PIP,150);
        Toast.makeText(context, "Alarm !!!!!!!!!!", Toast.LENGTH_SHORT).show();
        scheduleNextAlarm(context);
    }

    public static void enableAlarm(Context context) {
        sAlarmCanceled = false;
        scheduleNextAlarm(context);
    }

    public static void disableAlarm() {
        sAlarmCanceled = true;
    }

    private static void scheduleNextAlarm(Context context)
    {
        AlarmManager am =( AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        Intent i = new Intent(context, Alarm.class);
        PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, PendingIntent.FLAG_ONE_SHOT);
        am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 10000, pi);
    }
}

现在它每 10 秒精确执行一次。服务运行正常,我能够删除应用程序任务并看到警报。

关于java - 即使使用 START_STICKY,Android 也不会重新创建服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39280675/

相关文章:

java - Ant 如何根据参数从 build.xml 调用另一个 xml 文件

java - JUnit 测试无法找到要测试的类

java - 有没有读取/var/spool/mail/files的库?

android - Android SQLite 中的选择语句

android - 模拟器崩溃,android

android - 由于后台位置权限,应用程序在 Play 商店被拒绝

android - 可以在自定义对话框中使用 ViewPager 吗?

java - 线程 "main"com.google.api.client.auth.oauth2.TokenResponseException : 401 Unauthorized when trying to access Google classroom API 中出现异常

android - android rest 客户端不支持的媒体类型

java - 异常: submitTopology failed: out of sequence response