■常駐するサービスの作成

サービスは2つの形態があり、bindで呼び出し元からサービス内の関数のコールを行って通信が終わると終了するタイプと、
startServiceで開始されて動き続けて、開始と終了以外は外部から操作できない(関数のコールが出来ない)タイプがあります。

ココではバックグラウンドで動作する常駐サービスを作成します。
画面を切ったり、起動したアプリを終了させても見えない所で動き続けます。

まずは通常のアプリケーションに対して test_service.java というファイルを追加しました。



あまり変な所にファイルを追加するとややこしい事になります。
そのファイルの中に次の赤文字部分を書き込みます。
ただし、パッケージ名部分は自身のプロジェクトに合わせて書き換えてください。

▼作成したtest_service.javaファイル

package test.myapplication;

public class test_service extends android.app.Service
{

    static boolean flag;//スレッドを停止させるフラグ

    public android.os.IBinder onBind(android.content.Intent intent)
    {
        return null;
    }

    public void onCreate()
    {
        Thread th;
        th=new Thread(new test_thread());
        th.start();
    }

    private class test_thread implements Runnable {
        @Override
        public void run() {
            flag=true;
            android.media.ToneGenerator tg;
            tg = new android.media.ToneGenerator(android.media.AudioManager.STREAM_SYSTEM, android.media.ToneGenerator.MAX_VOLUME);
            while(flag) {
                try {
                    tg.startTone(android.media.ToneGenerator.TONE_SUP_ERROR,50);
                    Thread.sleep(2000);
                } catch (Exception e) {}
            }
        }
    }
}
サービス内でスレッドを立ててループ処理をしています。
変数 flag によりスレッド内のループを停止できるようにしました。


▼AndroidManifest.xml ファイル

次に AndroidManifest.xml ファイルを開いて以下の赤文字部分の行を追加します。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="">
    <application
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
            </intent-filter>
        </activity>

        <service android:name=".test_service"/>

    </application>
</manifest>

これで、2秒ごとに音が鳴るサービスが作成できました。
しかし起動させないと動きません。

▼サービスを起動させるには、プログラム中で次のようにします。

android.content.Intent _intent;
_intent=new android.content.Intent(getApplicationContext(), test_service.class);
getApplicationContext().startService(_intent);

▼サービスを停止させるには次にようにします。

test_service.flag=false;
android.content.Intent _intent;
_intent=new android.content.Intent(getApplicationContext(), test_service.class);
getApplicationContext().stopService(_intent);

1行目でスレッドのループを終了させています。
サービスを停止させるにはまず、サービス内のスレッドを停止させないとエラーが発生するので注意が必要です。
intentはクラスに対して一意のため、起動させたintentでなくても、新たに作成したintentで停止できます。


■サービス内のメソッド

public class test_service extends android.app.Service
{
    @Override
    public android.os.IBinder onBind(android.content.Intent intent)
    {
        return null;
    }

    @Override
    public void onCreate(){
        //サービスが作成され初期化された時に一度だけ動く部分
    }

    @Override
    public int onStartCommand(android.content.Intent intent, int flags, int startId) {
        //startServiceでサービスを起動させた場合に毎度動く部分
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        //サービスが破棄される時の後始末
    }
}
startServiceでサービスを起動させた場合には、サービスが起動していなかった場合にはonCreate()が呼ばれその後、onStartCommand()が呼ばれます。
サービスが起動している状態でstartServiceが呼ばれた場合にはonStartCommand()が呼ばれます。

つまり、何らかのトリガーでサービスに処理をさせたい場合にはonStartCommand()内に書いておき、アプリ側でstartServiceでサービスを起動させた方がよさそうです。


■電源ONしたらサービスを自動的に起動させる

まずは、 アプリケーションの自動起動 を見て自動起動するアプリケーションを作成してください。
BroadcastReceiverを継承したクラスの中のアプリケーション起動の部分を次のように書き換えます。

package test.myapplication;

public class test extends android.content.BroadcastReceiver {
    public void onReceive(android.content.Context context, android.content.Intent intent) {
        if(intent.getAction().equals(android.content.Intent.ACTION_BOOT_COMPLETED)) {

            android.content.Intent _intent;
            _intent=new android.content.Intent(context, test_service.class);
            context.startService(_intent);

        }
    }
}
このアプリケーションをインストールして一度起動させてからAndroidを再起動させると、サービスが自動的に起動するようになります。


■サービスが起動しているかを確認する

boolean isService(android.content.Context context, Class _class) {
    String className=_class.getName();
    android.app.ActivityManager _am = (android.app.ActivityManager) context.getSystemService(android.content.Context.ACTIVITY_SERVICE);
    java.util.List<android.app.ActivityManager.RunningServiceInfo> _list = _am.getRunningServices(Integer.MAX_VALUE);
    for (android.app.ActivityManager.RunningServiceInfo _info : _list) {
        if (className.equals(_info.service.getClassName())) {
            return true;
        }
    }
    return false;
}
システムサービスにより現在動いているサービスのリストを取得して対象のサービスの名前があるか確認して、 起動しているかどうかを判断しています。

▲トップページ > android