我想安排一个每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>
答案 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
。制造商这样做是为了节省电池寿命。
在设置中,应该有一种方法可以将您的应用添加到“受保护的应用”或“允许在后台运行的应用”列表中。查看电源管理设置或应用程序设置。