2016년 2월 13일 토요일

안드로이드) AlarmManager와 BroadcastReceiver 를 이용한 주기적인 작업 수행

예를 들어서 주기적으로 사용자에게 물을 마시라고 notification을 날리는 앱을 만들어보자.

먼저 AlarmManager 라는 녀석을 얻어온다.

 AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);

주기를 생각하자. 5초 이후부터 5초에 한번씩이라고 하면


long period = 1000 * 5;
long after = 1000 * 5;

그러면 AlarmManager의 호출을 받아줄 BroadcastReceiver 를 만들자.



public class MyReceiver extends BroadcastReceiver {
    public MyReceiver() { }

    private NotificationManager mManager;

    @Override
    public void onReceive(Context context, Intent intent) {
        NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

        Notification.Builder mBuilder = new Notification.Builder(context);
        mBuilder.setSmallIcon(R.mipmap.ic_launcher);
        mBuilder.setTicker("hi");
        mBuilder.setContentTitle("hi1");
        mBuilder.setContentText("hi3");

        mBuilder.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE);
        //mBuilder.setContentIntent(pendingIntent);
        mBuilder.setAutoCancel(true);

        nm.notify(111, mBuilder.build());

    }
}

이 BroadcastReceiver 는 alramManager에 의해 5초 주기로 호출이 될 것이다.
호출이 되면 무엇을 할 것인지를onReceive에서 정의해준다.
위 코드에서는 간단한 notification 을 구현하였다.

그럼, AlarmManager에 작성한 BroadCastReceiver를 등록시키자.


AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);

Intent receiverIntent = new Intent(MainActivity.this, MyReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, receiverIntent, 0);

long period = 1000 * 5;
long after = 1000 * 5;
long t = SystemClock.elapsedRealtime();

alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, t + after, period, pendingIntent);


AlarmManager.setRepeating() 을 통해 등록이 되어

이후부터 5초 주기로 notifcation이 발생한다.

notifcation 발생을 취소하고 싶으면 cancel() 함수를 호출해주면 된다.



Intent myIntent = new Intent(MainActivity.this, MyReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, 0);
alarmManager.cancel(pendingIntent);


그런데 이렇게 하면 리붓하고 나서는 알람이 발생하지 않는다.

리붓이 되었다는 메시지를 받아서 위 알람을 다시 등록해줘야 껏다 켜도 다시 알람이

발생하게 된다.

그러면 boot 이벤트를 받아들이는 BroadCastReceiver를 만들어야 한다.

먼저 권한이 있어야 boot  이벤트를 받아들일 수 있으므로

AndroidManifest.xml 에 등록해주자.

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<receiver    android:name=".BootReceiver"    android:enabled="true"    android:exported="false" >    <intent-filter>        <action android:name="android.intent.action.BOOT_COMPLETED" />    </intent-filter></receiver>


BootReceiver 는 인텐트 필터링을 통해 BOOT_COMPLETED 에 의해 호출이 되도록 한다.


public class BootReceiver extends BroadcastReceiver {
    public BootReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {

        AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);

        Intent myIntent = new Intent(context, MyReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, myIntent, 0);

        long period = 1000 * 5;
        long after = 1000 * 5;
        long t = SystemClock.elapsedRealtime();
        alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, t + after, period, pendingIntent);
    }
}

여끼까지 하고 나면 껐다 켜도 다시 알람에 의해서 notification 이 발생하게 된다.


댓글 없음:

댓글 쓰기