java.util.Timerよりjava.util.concurrent.ScheduledExecutorServiceのほうが柔軟

サービスの中でタイマー処理を入れようとTimerを使ったのですが、停止と再開の処理が難しく例外が多く出ました。Javaの1.5より追加された、concurrentを使うようです。
concurrentのScheduledExecutorServiceを使うと思った操作になりました。

これを使って、ネットワーク接続を監視するサービスを作りました。3GChekerという名前で公開しています。
ソース貼っときます。

package jp.co.acl_inc.G3Checker;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.Vibrator;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;


public class ChekerService extends Service{
	private Context context = this;
	private  Timer timer = new Timer(true);
	private final Handler handler = new Handler();
	private ScheduledExecutorService service;
	private ScheduledFuture  future = null;
	/**
	 * サービスをはずすときの処理です。
	 */
	@Override
	public boolean onUnbind(Intent intent) {
		stopSelf();
		service.shutdown();
		return super.onUnbind(intent);
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		service.shutdown();
	}

	/**
	 * startServiceでサービスが呼ばれたときに最初に呼ばれる処理です。
	 */
	@Override
	public void onCreate() {
		super.onCreate();
		service = Executors.newSingleThreadScheduledExecutor();
		Log.d("--ACL--", "Start Service On Create");
	}

	@Override
	public IBinder onBind(Intent arg0) {
		return iChekerServiceBinder;
	}
	/**
	 * サービスをバインドします。
	 */
	private final IChekerService.Stub iChekerServiceBinder = new IChekerService.Stub() {
		//チェックサービスをスタートします。
		public void startChecker() throws RemoteException {
			future = service.scheduleAtFixedRate(r, 0, 60 * 1000, TimeUnit.MILLISECONDS);
    		Log.d("--ACL--", "start checker");
		}
		//チェックサービスをストップします(サービスの一時停止)。
		public void stopChecker() throws RemoteException {
			if (future != null) {
				future.cancel(true);
			}
    		Log.d("--ACL--", "stop checker");
		}
	};
	/**
	 * スケジュールタスク
	 */
	Runnable r = new Runnable() {
		@Override
		public void run() {
			handler.post(new Runnable() {
				public void run() {
					myTask();
				}
			});
		}
	};
	/**
	 * タイマータスク
	 */
	private TimerTask timerTask = new TimerTask() {
		@Override
		public void run() {
			handler.post(new Runnable() {
				public void run() {
					myTask();
				}
			});
		}
	};
	/**
	 * タスクの実処理
	 */
	private void myTask() {
		Log.d("--ACL--", "In Run of Service");
        ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo ni = cm.getActiveNetworkInfo();
        TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
        if( ni == null ){
    		Toast.makeText(context, "ネットワークに接続していません。", Toast.LENGTH_SHORT).show();
    		openActivity();
    		Log.d("--ACL--", "Network is null");
    		vibrate();
        } else {
    		Log.d("--ACL--", ni.toString());
        	if (ni.getType() == ConnectivityManager.TYPE_MOBILE) {
	    		if(!ni.isAvailable()) {
		    		Toast.makeText(context, "ネットワークが非活性です。", Toast.LENGTH_SHORT).show();
		    		openActivity();
		    		Log.d("--ACL--", "Not Available");
		    		vibrate();
	    		}
	    		if (!ni.isConnected()) {
		    		Toast.makeText(context, "ネットワークに接続していません。", Toast.LENGTH_SHORT).show();
		    		openActivity();
		    		Log.d("--ACL--", "Not Connected");
		    		vibrate();
	    		}
        	}
    	}
	}
	/**
	 * バイブレーション
	 */
	private void vibrate() {
		Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
		long[] pattern = {1000, 1000, 1000, 1000, 1000, 1000}; 
		vibrator.vibrate(pattern, -1);
	}
	/**
	 * アクティビティを開く
	 */
	private void openActivity() {
		Intent i = new Intent(getApplicationContext(),G3CheckerAvtivity.class);
		i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		startActivity(i);
	}

}