我试图创建弹出在状态栏中提醒的提醒应用程序。据我了解,在Android NotificationManager是使用但需要以重新安排通知的BootService安排通知如期事件不会在引导生存的标准工具。
我拼凑低于该调度单提醒在启动时的应用程序,并弹出后在状态栏中的通知。如果您单击该通知,它将启动MainActivity其中,在未来,将有选择添加更多的提醒,删除它们,或什么的。
时遇到的问题是,提醒工作正常首次但是它似乎被重新调度本身和在随机时间由于某种原因重新弹出。我应该启动另一个活动,而不是将安装BootAlarmService的人?
更新:所以,我想我发现了一些线索与logcat中。显然,服务崩溃,并正在重新启动是重置的通知。任何想法这是为什么?
更新二: code改为工作模型
ActivityManager我不再想com.example.alarm_boot_test(PID 1428):隐藏#16在5000毫秒坠毁服务com.example.alarm_boot_test / .BootAlarmService的ActivityManagerW¯¯调度重启在15000ms坠毁服务com.example.alarm_boot_test / .NotificationAlarmService的ActivityManagerW¯¯调度重启ActivityManager我开始PROC com.example.alarm_boot_test服务com.example.alarm_boot_test / .BootAlarmService:PID = 2321 UID = 10069导报= {} dalvikvmÐ调试器分离;对象注册了1项 szipinfÐ初始化状态膨胀BootAlarmServiceð的OnCreate()BootAlarmServiceð报警周四一月17集CST 8时03分00秒2013的 MainActivity.java 的
包com.example.alarm_boot_test;进口android.app.Activity;进口android.os.Bundle;公共类MainActivity扩展活动{ @覆盖 保护无效的onCreate(捆绑savedInstanceState) { super.onCreate(savedInstanceState); 的setContentView(R.layout.activity_main); }}的 BootAlarmService.java 的
包com.example.alarm_boot_test;进口的java.util.Calendar;进口android.app.AlarmManager;进口android.app.PendingIntent;进口android.app.Service;进口android.content.Intent;进口android.os.IBinder;进口android.util.Log;公共类BootAlarmService延伸服务{ 私人最终字符串标记= this.getClass().getName(); @覆盖 公共无效的onCreate() { Log.d(TAG的OnCreate()); super.onCreate(); } @覆盖 公众诠释onStartCommand(意向意图,诠释旗帜,INT startId) { Log.d(TAG,alarm_test:BootAlarmService.onStartCommand()开始收到的ID为+ startId +:+意向); //如果意图== NULL,服务已被杀害/由系统重新启动 如果(意向!= NULL) createNotificationOnBoot(); 其他 Toast.makeText(getBaseContext(),。意图是BootAlarmService空,Toast.LENGTH_LONG).show(); 返回START_STICKY; } 私人无效createNotificationOnBoot() { 意向书的inotify =新意图(这一点,NotificationAlarmService.class); inotify.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); AlarmManager AMGR =(AlarmManager)getSystemService(ALARM_SERVICE); 的PendingIntent的PendingIntent = PendingIntent.getService(在此,0,inotify的,0); // 2分钟从现在熄灭 台历挂历= Calendar.getInstance(); calendar.set(Calendar.SECOND,0); calendar.set(Calendar.MINUTE,calendar.get(Calendar.MINUTE)+ 2); amgr.set(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),的PendingIntent); Log.d(TAG,+ calendar.getTime()的ToString()报警组); } @覆盖 公众的IBinder onBind(意向意图) { 返回null; }}的 BootReceiver.java 的
包com.example.alarm_boot_test;进口android.content.BroadcastReceiver;进口android.content.Context;进口android.content.Intent;公共类BootReceiver扩展广播接收器{ @覆盖 公共无效的onReceive(最终上下文的背景下,最终的意图bootintent) { 意图I =新意图(); i.setAction(com.example.alarm_boot_test.BootAlarmService); context.startService(ⅰ); }}的 NotificationAlarmService.java 的
包com.example.alarm_boot_test;进口android.app.Notification;进口android.app.NotificationManager;进口android.app.PendingIntent;进口android.app.Service;进口android.content.Intent;进口android.os.IBinder;进口android.util.Log;公共类NotificationAlarmService延伸服务{ 私人最终字符串标记= this.getClass()的getName()。 @覆盖 公共无效的onCreate() { super.onCreate(); } @覆盖 公众诠释onStartCommand(意向意图,诠释旗帜,INT startId) { Log.d(TAGalarm_test:NotificationAlarmService.onStartCommand()); 如果(意向!= NULL) createNotification(); 其他 Toast.makeText(getBaseContext(),。意图是NotificationAlarmService空,Toast.LENGTH_LONG).show(); 返回super.onStartCommand(意向,旗帜,startId); } 私人无效createNotification() { NotificationManager notificationManager =(NotificationManager)getSystemService(NOTIFICATION_SERVICE); 通知通知=新的通知(android.R.drawable.stat_sys_warning,注意从AlarmService,System.currentTimeMillis的()); 意图I =新意图(这一点,ViewReminder.class); 的PendingIntent的PendingIntent = PendingIntent.getActivity(在此,0,I,0); notification.setLatestEventInfo(这一点,新通知,你已经被AlarmService通知的PendingIntent); notificationManager.notify(10001,通知); } @覆盖 公众的IBinder onBind(意向意图) { 返回null; }}* activity_main.xml中*
<的RelativeLayout的xmlns:机器人=http://schemas.android/apk/res/android 的xmlns:工具=http://schemas.android/tools 机器人:layout_width =match_parent 机器人:layout_height =match_parent 工具:上下文=MainActivity。> <的TextView 机器人:layout_width =WRAP_CONTENT 机器人:layout_height =WRAP_CONTENT 机器人:layout_centerHorizontal =真 机器人:layout_centerVertical =真 机器人:文字=服务开始重新启动! />< / RelativeLayout的>AndroidManifest.xml中
<?XML版本=1.0编码=UTF-8&GT?;<清单的xmlns:机器人=http://schemas.android/apk/res/android 包=com.example.alarm_boot_test 安卓版code =1 机器人:=的versionName1.0> <使用许可权的android:NAME =android.permission.RECEIVE_BOOT_COMPLETED/> <用途-SDK 安卓的minSdkVersion =9 机器人:targetSdkVersion =9/> <应用 机器人:allowBackup =真 机器人:图标=@绘制/ ic_launcher 机器人:标签=@字符串/ APP_NAME 机器人:主题=@风格/ AppTheme> <服务机器人:名字=com.example.alarm_boot_test.BootAlarmService> &所述;意图滤光器> <作用机器人:名字=com.example.alarm_boot_test.BootAlarmService> < /作用> &所述; /意图滤光器> < /服务> <接收机器人:名字=com.example.alarm_boot_test.BootReceiver> &所述;意图滤光器> <作用机器人:名字=android.intent.action.BOOT_COMPLETED> < /作用> &所述; /意图滤光器> < /接收器> <服务机器人:名字=com.example.alarm_boot_test.NotificationAlarmService> < /服务> <活动 机器人:名字=com.example.alarm_boot_test.MainActivity 机器人:标签=@字符串/ APP_NAME> &所述;意图滤光器> <作用机器人:名字=android.intent.action.MAIN/> <类机器人:名字=android.intent.category.LAUNCHER/> &所述; /意图滤光器> < /活性GT; < /用途>< /清单>解决方案
在情况下,它可以帮助其他人,我想我需要检查NULL传递的意图在onStartCommand()方法,无论是在BootAlarmService.java以及NotificationAlarmService的.java。只有在测试这几天,但它看起来像意图是NULL,如果系统杀死/重新启动该服务。只是这个测试使我创造只有当服务在系统启动时启动的通知(当传递意图不是为null)。
I'm trying to create a reminder application that pops up a reminder in the status bar. As I understand, the Android NotificationManager is the standard tool to use to schedule notifications however a BootService is needed in order to re-schedule notifications as scheduled events do not survive across boots.
I've pieced together an application below which schedules a single reminder at boot time, and pops up a notification in the status bar. If you click the notification, it launches MainActivity which, in the future, will have options to add more reminders, delete them, or whatever.
The problem I'm having is that the reminder works correctly the first time however it seems to be re-scheduling itself and popping up again at random times for some reason. Should I be launching another activity rather than the one which installs the BootAlarmService?
UPDATE: So I think I found some clues with logcat. Apparently the Service is crashing and being restarted which is resetting the Notification. Any ideas why this is?
UPDATE II : code changed to working model
ActivityManager I No longer want com.example.alarm_boot_test (pid 1428): hidden #16 ActivityManager W Scheduling restart of crashed service com.example.alarm_boot_test/.BootAlarmService in 5000ms ActivityManager W Scheduling restart of crashed service com.example.alarm_boot_test/.NotificationAlarmService in 15000ms ActivityManager I Start proc com.example.alarm_boot_test for service com.example.alarm_boot_test/.BootAlarmService: pid=2321 uid=10069 gids={} dalvikvm D Debugger has detached; object registry had 1 entries szipinf D Initializing inflate state BootAlarmService D oncreate() BootAlarmService D alarm set for Thu Jan 17 08:03:00 CST 2013MainActivity.java
package com.example.alarm_boot_test; import android.app.Activity; import android.os.Bundle; public class MainActivity extends Activity { @Override protected void onCreate (Bundle savedInstanceState) { super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); } }BootAlarmService.java
package com.example.alarm_boot_test; import java.util.Calendar; import android.app.AlarmManager; import android.app.PendingIntent; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log; public class BootAlarmService extends Service { private final String TAG = this.getClass ().getName (); @Override public void onCreate () { Log.d (TAG, "oncreate()"); super.onCreate (); } @Override public int onStartCommand (Intent intent, int flags, int startId) { Log.d (TAG, "alarm_test: BootAlarmService.onStartCommand() Received start id " + startId + ": " + intent); // if intent == null, service has been killed/restarted by system if (intent != null) createNotificationOnBoot(); else Toast.makeText (getBaseContext (), "Intent was null in BootAlarmService.", Toast.LENGTH_LONG).show(); return START_STICKY; } private void createNotificationOnBoot () { Intent inotify = new Intent(this , NotificationAlarmService.class); inotify.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK); AlarmManager amgr = (AlarmManager)getSystemService(ALARM_SERVICE); PendingIntent pendingIntent = PendingIntent.getService(this, 0, inotify, 0); // go off two mins from now Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MINUTE, calendar.get (Calendar.MINUTE) + 2); amgr.set (AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis (), pendingIntent); Log.d (TAG, "alarm set for " + calendar.getTime ().toString ()); } @Override public IBinder onBind (Intent intent) { return null; } }BootReceiver.java
package com.example.alarm_boot_test; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; public class BootReceiver extends BroadcastReceiver { @Override public void onReceive (final Context context, final Intent bootintent) { Intent i = new Intent (); i.setAction ("com.example.alarm_boot_test.BootAlarmService"); context.startService (i); } }NotificationAlarmService.java
package com.example.alarm_boot_test; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log; public class NotificationAlarmService extends Service { private final String TAG = this.getClass().getName (); @Override public void onCreate () { super.onCreate (); } @Override public int onStartCommand (Intent intent, int flags, int startId) { Log.d (TAG, "alarm_test: NotificationAlarmService.onStartCommand()"); if (intent != null) createNotification (); else Toast.makeText (getBaseContext (), "Intent was null in NotificationAlarmService.", Toast.LENGTH_LONG).show(); return super.onStartCommand (intent, flags, startId); } private void createNotification() { NotificationManager notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); Notification notification = new Notification(android.R.drawable.stat_sys_warning, "Note from AlarmService", System.currentTimeMillis()); Intent i = new Intent(this, ViewReminder.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, i, 0); notification.setLatestEventInfo(this, "New Notification", "You have been notified by AlarmService", pendingIntent); notificationManager.notify(10001, notification); } @Override public IBinder onBind (Intent intent) { return null; } }*activity_main.xml*
<RelativeLayout xmlns:android="schemas.android/apk/res/android" xmlns:tools="schemas.android/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="Service started! Reboot!" /> </RelativeLayout>AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="schemas.android/apk/res/android" package="com.example.alarm_boot_test" android:versionCode="1" android:versionName="1.0" > <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="9" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <service android:name="com.example.alarm_boot_test.BootAlarmService" > <intent-filter> <action android:name="com.example.alarm_boot_test.BootAlarmService" > </action> </intent-filter> </service> <receiver android:name="com.example.alarm_boot_test.BootReceiver" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" > </action> </intent-filter> </receiver> <service android:name="com.example.alarm_boot_test.NotificationAlarmService" > </service> <activity android:name="com.example.alarm_boot_test.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>解决方案
In case it helps someone else, I think I needed to check the passed Intent for NULL in the onStartCommand() method both in BootAlarmService.java as well as NotificationAlarmService.java. Only been testing it a couple days but it looks like the Intent is NULL if the system kills/restarts the service. Simply testing for this allowed me to create the notification only when the service is started at Boot-time (when the passed Intent is NOT null).
更多推荐
Android的AlarmManager随机安排的通知?
发布评论