猫型iPS細胞研究所

Windows、Linux、iOS、DB、Network

Android

AlarmManagerで定期処理を行う

投稿日:2013年3月30日 更新日:

私のやりたいことは、定期的にあるアクションが起動するアプリの作成です。
serviceでいいかと思っていたのですが、何故か画面がスリープした状態で停止します。
そこでAlarmManagerを使用する方法に切り替えることにしました。

とりあえずsetRepeatingを使用すれば実現できそうです。
ここではAlarmManagerの詳細は省略です。。。

cancelでAlarmManagerが停止しない!

かなり困ったのですが、setActionがキーのようです。
呼び出し時と同じAction名でcancelしてやればいいようです。

BroadcastReceiverからActivityへ返したい

たんなるタイマーに使いたいだけですので、所定時間が経過すればActivityに処理を戻したいのですが、
どうすればよいかわかりません・・・。
あきらめて、BroadcastReceiverからPendingIntentを投げることにしました。
しかしこれでは、毎回onCreateが呼ばれるので、intentのアクションで処理を分けることにしました。
画面が毎回揺れるのは、とりあえずほっておくことにしました。

タイマーでカウントアップしたい

この方法ではAlarmによってBroadcastReceiverが呼ばれるのはonReceive。
BroadcastReceiverからActivityが呼ばれるのはonCreate。
どちらも変数が初期化されてしまい、うまくいきません。。。
プリファレンスあたりを使用して、カウンターの数を保存しておくことにする予定です。

とりあえず、AlarmManagerを使って呼び出し元のActivityをキックするサンプルです
不要なコードもついていますが、そろそろ整理不能になってきたので動作している間に・・・ :x001:

AlarmActivity.class

package com.nekotype;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class AlarmActivity extends Activity  {

	AlarmManager alarmManager = null;
	PendingIntent pendingIntent = null;
	final int ADD_COUNT= 15000;
	int count = 0;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		
		super.onCreate(savedInstanceState);
		setContentView(R.layout.alarm_main);
		
		Log.v("AlarmActivity", "onCreate");

		Button btnStart = (Button)findViewById(R.id.btnStart);
		btnStart.setOnClickListener((android.view.View.OnClickListener) new btnStartClickListener());

		Button btnEnd = (Button)findViewById(R.id.btnEnd);
		btnEnd.setOnClickListener((android.view.View.OnClickListener) new btnEndClickListener());
		
        Intent getintent = getIntent();        
        if (getintent != null ){
        		Log.v("AlarmActivity", getintent.getAction());
        		if (getintent.getAction().equals("RETURN")){
        			
        			Bundle extra = getIntent().getExtras();
        			
        			try {
        				
        				this.count += Integer.parseInt(extra.getString("count")) ;
						Log.v("AlarmActivity", String.valueOf(this.count) );
					} catch (Exception e) {
						Log.v("AlarmActivity", e.toString());
					}

        		}

	        	Toast.makeText(this, "AlarmActivity", Toast.LENGTH_SHORT).show();
        }
        
        
		Context context = AlarmActivity.this;
		Intent intent = new Intent(AlarmActivity.this,ReceivedActivity.class);
		//setActionを指定し、同じaction名でcancelしないと止まりません
		intent.setAction("REPEAT");
		intent.putExtra("count", ADD_COUNT);

		pendingIntent =  PendingIntent.getBroadcast(context, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);
        alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);

	}


	class btnStartClickListener implements android.view.View.OnClickListener{

		@Override
		public void onClick(View arg0) {
			
			Log.v("AlarmActivity", "click start");

			long currentTimeMillis = System.currentTimeMillis();
			alarmManager.setRepeating(AlarmManager.RTC, currentTimeMillis+1000, ADD_COUNT, pendingIntent);

		}
	}

	class btnEndClickListener implements android.view.View.OnClickListener{

		@Override
		public void onClick(View arg0) {
			Log.v("test","click end");
			try {
				alarmManager.cancel(pendingIntent);
			} catch (Exception e) {
				// TODO: handle exception
				Log.v("test",e.toString());
			}

		}
	}

}

ReceivedActivity.java

package com.nekotype;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.PendingIntent.CanceledException;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
import android.sax.StartElementListener;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

public class ReceivedActivity extends BroadcastReceiver {
	
	@Override
	public void onReceive(Context context, Intent intent) {
		
		Log.v("ReceivedActivity", "onCreate");

		Bundle extra = intent.getExtras();
		int count = extra.getInt("count");

		Intent intent2 = new Intent(context, AlarmActivity.class);
		intent2.setAction("RETURN");
		intent2.putExtra("count", String.valueOf(count));
		Log.v("ReceivedActivity", String.valueOf(count));
		PendingIntent pIntent = PendingIntent.getActivity(context, 0, intent2, 0);
		

		try {
			pIntent.send();
		} catch (CanceledException e) {
			e.printStackTrace();
		}

	}

}

AndroidManifest.xml

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

    <uses-sdk android:minSdkVersion="7" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".AlarmActivity"
            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=".ReceivedActivity" android:process=":remote" />
        <receiver android:name=".AlarmActivity" android:process=":remote" />
    </application>

</manifest>

layoutは省略・・・

Gooleアドセンス用336

Gooleアドセンス用336

-Android
-

執筆者:

関連記事

ListView(2行)

ListViewの各行に2行表示させるには、ListActivityをextendします。 また、かくリストのデータはmapで設定します。 TestActivity.java package com. …

SQLiteにadbでアクセスする

コマンドプロンプトでadbのあるディレクトリまでcdで移動します。 私の場合はD:\Users\xxx\android-sdks\platform-tools にしてあります。 # d: # cd D …

Micro USB の充電用とデータ転送用

以前 「SonyEricssonXPERIA SO-01Bのドライバのインストール」 というものを書きました。 このどうしようもない端末は、MicroUSBにも問題があります。 しかもこの端末、古すぎ …

バインドを利用したservice

バインドを利用しないserviceもありますが、serviceは勝手に動き続けるか、自動的に停止するようにするかになります。 実際にはバインドを利用してserviceが起動している時にもアクションを連 …

SonyEricssonXPERIA SO-01Bのドライバのインストール

二度とこの古い機種を接続することはないと思うのですが、 それだけに貴重な情報と思いメモしておきます :x002: adb で確認するとどうしても認識されません。 >adb devices Lis …