サンプルプログラム工場

AAKAKA Appで使われているプログラムのサンプルコードをそのまま公開!

サンプルプログラム工場 > android > [Android]AlarmManageを使って一定時間ごとに処理をするサンプル#tryService01
Google Play AAKAKAxSOFTへ

[Android]AlarmManageを使って一定時間ごとに処理をするサンプル#tryService01

実行ファイル(APK)やサンプル(zip)をダウンロードする
tryService01の実行イメージ

 AlarmManagerを使って一定期間ごとに処理をするサンプル
 サービスをずっと実行しっぱなしだと、OSの判断でサービスを終了させられてしまうので、アラームを使って指定の時間に呼び出して処理をするようにする。
 Preferenceを使って値を保持して、カウントをするように。
 これをすれば値を持っておきたいときに自由に使える。
 サービスでなくアプリ側からも値にアクセスできる。
adb shell dumpsys alarm > dump.txt
 を使えば 実行中のタイマーの一覧が表示される。(各ユーザーのフォルダに保存される)
 RTC_WAKEUPになってなかったら停止中

検索した事
android サービス
android service
android 常駐 アプリ
android サービス BroadcastReceiver
android サービス 常駐
NotificationCompat.Builder
android AlarmManager

開発環境
 Eclipse IDE バージョン: 4.2.1

package com.example.tryservice01;

import java.util.Calendar;

import android.os.Bundle;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {
	
	private static final String TAG = "MainActivity#";

	// ______________________________________________________________________________
	@Override	// 作られた
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		// 開始ボタン
		Button btn1 = (Button)this.findViewById(R.id.button1);
		btn1.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				
				// 呼び出したい時間をセットする
				Calendar cal = Calendar.getInstance();
				cal.setTimeInMillis(System.currentTimeMillis());
				cal.add(Calendar.SECOND, 10);
				
				// Pending Intent使ってレシーバーをセットする
				PendingIntent sender = MainActivity.this.getPending(MainActivity.this, 0);
				
				// アラームをセットする
				AlarmManager am = (AlarmManager)MainActivity.this.getSystemService(ALARM_SERVICE);
				am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
				
				// SharedPreferenceのカウントをリセット
				MainActivity.this.clearCountSp();
				
				Toast.makeText(MainActivity.this, TAG + ": Alarm !", Toast.LENGTH_SHORT).show();
			}
		});
		
		// 停止ボタン
		Button btn2 = (Button)this.findViewById(R.id.button2);
		btn2.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {

				// Pending Intent使ってレシーバーをセットする
				PendingIntent sender = MainActivity.this.getPending(MainActivity.this, 0);
				
				// アラームを解除する
				AlarmManager am = (AlarmManager)MainActivity.this.getSystemService(ALARM_SERVICE);
				am.cancel(sender);
				
				Toast.makeText(MainActivity.this, TAG + ": Alarmキャンセル!", Toast.LENGTH_SHORT).show();
			}
		});
	}
	
	// ______________________________________________________________________________
	/**
	 * メンバ変数として保存ではなくて、そのつど作らないとキャンセルが効かない場合があるみたい
	 * @param ctx コンテキスト
	 * @param uid 適当に識別するためのもの
	 * @return PendingIntent
	 */
	private PendingIntent getPending(Context ctx, int uid) {	
		Intent indent = new Intent(ctx, ReceiverAlert.class);
		
		// PendingIntentが同じ物の場合は上書きされてしまう
		PendingIntent pending = PendingIntent.getBroadcast(ctx, uid, indent, 0);
		
		return pending;
	}

	// ______________________________________________________________________________
	@Override	// メニューが押された
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	// ______________________________________________________________________________
	/**
	 * SharedPreferenceのカウントをリセットする
	 */
	private void clearCountSp() {
		String prefName = this.getPackageName() + "_preference";
		SharedPreferences sp = this.getSharedPreferences(prefName, Context.MODE_PRIVATE);
		
		// カウントをリセットする
		Editor editor = sp.edit();
		editor.putInt("count", 0);
		editor.commit();
	}
}

こちらはサービスとして登録されて呼び出される

package com.example.tryservice01;

import java.util.Calendar;

import android.app.AlarmManager;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.PendingIntent.CanceledException;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.PowerManager;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;

// ______________________________________________________________________________
/**
 * アラート表示用レシーバ
 * @author ab
 *
 */
public class ReceiverAlert extends BroadcastReceiver {

	private static final String TAG = "ReceiverAlert#";
	
	// ______________________________________________________________________________
	@Override	// データを受信した
	public void onReceive(Context context, Intent intent) {
		
		// 時間の再設定が必要なもの
		if (intent.getAction() != null && (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)
		|| intent.getAction().equals(Intent.ACTION_DATE_CHANGED)
		|| intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)
		|| intent.getAction().equals(Intent.ACTION_TIME_CHANGED)
		|| intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED))) {
			
			// 表示
			Toast.makeText(context, TAG + ": アクションを受信 " + intent.getAction(), Toast.LENGTH_SHORT).show();
			
		} else {
			

			/*
			// スリープを解除する
			PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
			PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "TAG");
			wl.acquire(10000);
			*/
			String prefName = context.getPackageName() + "_preference";
			SharedPreferences sp = context.getSharedPreferences(prefName, Context.MODE_PRIVATE);
			
			// 今のカウントを取り出す
			int count = sp.getInt("count", 0);
			
			NotificationManager nm = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
			
			Notification n = new NotificationCompat.Builder(context)
                .setSmallIcon(R.drawable.ic_launcher)
                .setTicker("時間です!")
                .setWhen(System.currentTimeMillis())
                .setContentTitle(count + "回目")
                .setContentText("お時間となりましたよ。")
                .setDefaults(Notification.DEFAULT_ALL)
                .build();

			// 古い通知を削除
			nm.cancelAll();
			nm.notify(R.string.app_name, n);
			
			
			// カウントアップ
			Editor editor = sp.edit();
			editor.putInt("count", count + 1);
			editor.commit();


			
			
			Log.i(TAG + "onReceive", "時間です!" + count + " 回目");

			// 通常メッセージを受信
			Toast.makeText(context, TAG + " 時間です!" + count + " 回目", Toast.LENGTH_SHORT).show();
		
			// しばらくは再通知
			if (count < 5) {
				// 再度タイマーをセットする
				Calendar cal = Calendar.getInstance();
				cal.setTimeInMillis(System.currentTimeMillis());
				cal.add(Calendar.SECOND, 10);
				
				AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
				am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), getPending(context, 0));
			} else {
				// 通常メッセージを受信
				Toast.makeText(context, TAG + ": タイマー終了! ", Toast.LENGTH_SHORT).show();
			}

		}
	}
	
	// ______________________________________________________________________________
	/**
	 * メンバ変数として保存ではなくて、そのつど作らないとキャンセルが効かない場合があるみたい
	 * @param ctx コンテキスト
	 * @param uid ユニークなID
	 * @return PendingIntent
	 */
	private PendingIntent getPending(Context ctx, int uid) {
		Intent indent = new Intent(ctx, ReceiverAlert.class);
		PendingIntent pending = PendingIntent.getBroadcast(ctx, uid, indent, 0);
		
		return pending;
	}

}

<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"
    android:background="#aaffff"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button1"
        android:layout_alignRight="@+id/button1"
        android:layout_below="@+id/button1"
        android:layout_marginTop="52dp"
        android:text="停止" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="120dp"
        android:text="開始" />

</RelativeLayout>

ReceiverAlertをレシーバーとしてManifestファイスに書くのを忘れずに!

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.tryservice01"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.WAKE_LOCK"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.tryservice01.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>
        <!-- 通常の受付 -->
		<receiver android:name="ReceiverAlert" android:process=":remote">
		    <intent-filter>
				<action android:name="android.intent.action.BOOT_COMPLETED"/>
				<action android:name="android.intent.action.DATE_CHANGED"/>
				<action android:name="android.intent.action.TIMEZONE_CHANGED"/>
				<action android:name="android.intent.action.TIME_SET"/>
				<action android:name="android.intent.action.PACKAGE_REPLACED"/>
            </intent-filter>
        </receiver>
    </application>

</manifest>
サンプルプロジェクトをダウンロード

, , , ,

[Android]ギャラリーで開いた画像を表示するサンプル#tryGallery00 [Android]アプリケーションのリスト,自己署名を取り出すサンプル#tryAppLi...

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


*

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>