2013-01-17 3 views
2

상태 표시 줄에 알림을 팝업하는 알림 응용 프로그램을 만들려고합니다. 알다시피, Android NotificationManager는 알림을 예약하는 데 사용하는 표준 도구이지만 일정 잡은 이벤트가 부팅시 생존하지 않으므로 알림을 다시 예약하려면 BootService가 필요합니다.Android AlarmManager 임의로 일정을 예약 하시겠습니까?

부팅 시간에 하나의 미리 알림 일정을 잡은 상태의 응용 프로그램을 결합하여 상태 표시 줄에 알림을 표시합니다. 알림을 클릭하면 MainActivity가 시작됩니다. MainActivity는 나중에 알림을 추가하거나 삭제할 수있는 옵션을 갖습니다.

내가 겪고있는 문제는 리마인더가 처음에는 올바르게 작동하지만 다시 일정을 잡아서 어떤 이유로 든 임의의 시간에 다시 팝업으로 나타나는 것입니다. BootAlarmService를 설치하는 활동이 아닌 다른 활동을 시작해야합니까?

업데이트 : 그래서 나는 logcat에 대한 단서를 발견했다고 생각합니다. 명백히 서비스가 충돌하고 다시 시작되어 알림을 재설정하고 있습니다. 이게 왜 어떤 아이디어일까요?

UPDATE II는 : 코드는

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


} 
,691 BootAlarmService.java

MainActivity.java 작업 모델

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 2013 

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


} 

변경 363,210

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="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/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

,

답변

1

다른 사람에게 도움이되는 경우에는 BootAlarmService.java와 NotificationAlarmService.java에서 onStartCommand() 메서드의 전달 된 Intent를 NULL로 확인해야한다고 생각합니다. 며칠 만 테스트했지만 시스템이 서비스를 죽이거나 다시 시작하면 Intent가 NULL 인 것처럼 보입니다. 이를 테스트하기 만하면 부트 타임에 서비스가 시작될 때 (전달 된 인 텐트가 null이 아닌 경우) 알림을 생성 할 수있었습니다.

+0

이 내용을 공유 했는데도 다른 질문이 있습니다. 하루에 여러 번 앱을 무작위로 알려주고 싶습니다. 어떻게해야할까요? – Recomer