
[Android]アプリを閉じても常駐してバックグラウンドで処理をするサンプル#tryService00

アプリが閉じられても常駐して一定期間ごとにメッセージを表示するサンプル。
停止ボタンが押されるまでは、常駐し続ける。
何かを通知したい、タイマーなどに便利に使えるのでは?
Threadを立てて一定期間ごとにチェックみたいなやり方をする場合、このやり方は完璧ではない。
Androidは前面のアプリがメモリを使う場合、すぐにバックグラウンドの処理をKillしてしまう。
こういう場合だとAlarmManagerを使うのが便利らしい。
●検索した事
android サービス
android service
android 常駐 アプリ
android サービス BroadcastReceiver
android サービス 常駐
NotificationCompat.Builder
●開発環境
Eclipse IDE バージョン: 4.2.1
package com.example.tryservice00; import java.util.List; import android.os.Bundle; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManager.RunningServiceInfo; import android.content.Intent; import android.util.Log; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class ActivityService extends Activity { private static final String TAG = "ActivityService"; // ______________________________________________________________________________ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_service); // サービスを開始するボタン Button btn3 = (Button)this.findViewById(R.id.button3); btn3.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(ActivityService.this, com.example.tryservice00.TryService.class); startService(intent); } }); // サービスを停止するボタン Button btn4 = (Button)this.findViewById(R.id.button4); btn4.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(ActivityService.this, com.example.tryservice00.TryService.class); stopService(intent); } }); } // ______________________________________________________________________________ /** * サービスが実行中か * @param className サービスのクラス名 * @return true: 実行中です */ private boolean isServiceRunnig(String className) { ActivityManager am = (ActivityManager)this.getSystemService(ACTIVITY_SERVICE); List<RunningServiceInfo> listServiceInfo = am.getRunningServices(Integer.MAX_VALUE); Log.i(TAG + "isServiceRunnig", "Search Start: " + className); for (RunningServiceInfo curr : listServiceInfo) { Log.i(TAG + "isServiceRunnig", "Check: " + curr.service.getClassName()); if (curr.service.getClassName().equals(className)) { Log.i(TAG + "isServiceRunnig", ">>>>>>FOUND!"); return true; } } return false; } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity, menu); return true; } }
package com.example.tryservice00; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.Handler; import android.os.IBinder; import android.support.v4.app.NotificationCompat; import android.util.Log; import android.widget.Toast; // ______________________________________________________________________________ // サービス本体 public class TryService extends Service { private final static String TAG = "TryService#"; // Toastを何回表示されたか数えるためのカウント private int mCount = 0; // Toastを表示させるために使うハンドラ private Handler mHandler = new Handler(); // スレッドを停止するために必要 private boolean mThreadActive = true; // スレッド処理 private Runnable mTask = new Runnable() { @Override public void run() { // アクティブな間だけ処理をする while (mThreadActive) { try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO 自動生成された catch ブロック e.printStackTrace(); } // ハンドラーをはさまないとToastでエラーでる // UIスレッド内で処理をしないといけないらしい mHandler.post(new Runnable() { @Override public void run() { mCount++; showText("カウント:" + mCount); } }); } mHandler.post(new Runnable() { @Override public void run() { showText("スレッド終了"); } }); } }; private Thread mThread; // ______________________________________________________________________________ /** * テキストを表示する * @param text 表示したいテキスト */ private void showText(Context ctx, final String text) { Toast.makeText(this, TAG + text, Toast.LENGTH_SHORT).show(); } // ______________________________________________________________________________ /** * テキストを表示する * @param text テキスト */ private void showText(final String text) { showText(this, text); } // ______________________________________________________________________________ @Override // onBind:サービスがバインドされたときに呼び出される public IBinder onBind(Intent intent) { this.showText("サービスがバインドされました。"); return null; } // ______________________________________________________________________________ @Override // onStartCommand: public int onStartCommand(Intent intent, int flags, int startId) { super.onStartCommand(intent, flags, startId); this.showText("onStartCommand"); this.mThread = new Thread(null, mTask, "NortifyingService"); this.mThread.start(); // 通知バーを表示する showNotification(this); // 戻り値でサービスが強制終了されたときの挙動が変わる // START_NOT_STICKY,START_REDELIVER_INTENT,START_STICKY_COMPATIBILITY return START_STICKY; } // ______________________________________________________________________________ @Override // onCreate:サービスが作成されたときに呼びされる(最初に1回だけ) public void onCreate() { this.showText("サービスが開始されました。"); super.onCreate(); } // ______________________________________________________________________________ @Override // onDestroy: public void onDestroy() { this.showText("サービスが終了されました。"); // スレッド停止 this.mThread.interrupt(); this.mThreadActive = false; this.stopNotification(this); super.onDestroy(); } // ______________________________________________________________________________ // 通知バーを消す private void stopNotification(final Context ctx) { NotificationManager mgr = (NotificationManager)ctx.getSystemService(Context.NOTIFICATION_SERVICE); mgr.cancel(R.layout.activity_service); } // ______________________________________________________________________________ // 通知バーを出す private void showNotification(final Context ctx) { NotificationManager mgr = (NotificationManager)ctx.getSystemService(Context.NOTIFICATION_SERVICE); Intent intent = new Intent(ctx, ActivityService.class); PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0); // 通知バーの内容を決める Notification n = new NotificationCompat.Builder(ctx) .setSmallIcon(R.drawable.ic_launcher) .setTicker("サービスが起動しました。") .setWhen(System.currentTimeMillis()) // 時間 .setContentTitle("サービス起動中") .setContentText("このバーをタップ後に「サービス終了」を選択してください。") .setContentIntent(contentIntent)// インテント .build(); n.flags = Notification.FLAG_NO_CLEAR; mgr.notify(R.layout.activity_service, n); } }
<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="#aaffcc" 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=".ActivityService" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="サービスをどうしたい?" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView1" android:layout_below="@+id/textView1" android:layout_marginTop="15dp" android:text="サービスを開始する" /> <Button android:id="@+id/button4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/button3" android:layout_below="@+id/button3" android:layout_marginTop="24dp" android:text="サービスを終了する" /> </RelativeLayout>
サービスの追加をマニフェストファイルに忘れずに書く!
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.tryservice00" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.tryservice00.ActivityService" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name="TryService"></service> </application> </manifest>
[Android]設定画面を一定回数開くごとにポップアップダイアログを表示する... [Android]ギャラリーで開いた画像を表示するサンプル#tryGallery00