こんにちは。管理人のピヨ猫でーす。
Androidでバックグラウンドサービスを実装する方法を紹介します。
1.Service機能について
AndroidアプリにはService機能があります。
アプリを起動しなくてもバックグラウドで定期的に処理を行うためのもので、タイマーや通知機能の実現に使います。
アプリ開発でほぼ必須の機能なので確実に押さえておきましょう。
2.Service機能の実装方法の注意点(OSバージョン差異)
Service機能を実装する前に注意点があります。
それはService機能はAndroidのOSバージョンによって実装方法が異なることです。
AndroidのOSバージョンによりService機能の実装に使えるライブラリ(API)が異なります。
APIレベルとOSバージョンの違いは以下の記事が参考となるので貼っときます。
Service機能のAPIはAPIレベル26(Oreo)で大幅改定が入っており、Service機能を実装する場合は、Oreo以前とOreoの両方の実装をする必要があります。
3.Service機能の実装方法
/**
* サービス制御ユーティリティ
*/
public class ServiceUtil {
/**
* サービスの起動
*/
public static void startService(Context context, Intent intent) {
if(Build.VERSION.SDK_INT < 26){
context.startService(intent);
} else {
context.startForegroundService(intent);
}
}
/**
* 端末起動時のBootレシーバーからのサービスの起動
*/
public static void startServiceWithContextCompat(Context context, Intent intent) {
if(Build.VERSION.SDK_INT < 26){
context.startService(intent);
} else {
ContextCompat.startForegroundService(context, intent);
}
}
/**
* サービス停止
*/
public static void stopService(Context context, Intent intent) {
context.stopService(intent);
}
/**
* サービスクラスのonStartCommandで実行する処理。
* Android8以降はstartForegroundを呼び出す必要がある。
*/
public static void startForeground(Service context, byte appCode, Notification notify) {
if(Build.VERSION.SDK_INT < 26){
// TODO:何もしない
} else {
context.startForeground(appCode, notify);
}
}
}
/**
* サービスクラス例
*/
public class NotifyService extends Service {
・・・
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
NotificationCompat.Builder builder = NotifyUtil.createBuilder(
getApplicationContext(),
SettingActivity.class,
NotifyService.class.getName() + ".service.chanel",
NotifyService.class.getSimpleName(),
getResources().getString(R.string.app_name),
getResources().getString(R.string.message_notify),
R.drawable.ic_cat_icon
);
・・・
ServiceUtil.startForeground(this, MyApp.REQUEST_NOTIFY_SERVICE_START, builder.build());
return START_STICKY;
}
}
/**
* サービスの起動/停止例
*/
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent si = new Intent(this, NotifyService.class);
si.putExtra("REQUEST_CODE", "NONE");
ServiceUtil.startService(this, si);
}
// ボタンなどから呼び出す
public void stopService() {
Intent intent = new Intent(getApplication(), NotifyService.class);
intent.putExtra("REQUEST_CODE", "NONE");
ServiceUtil.stopService(getApplicationContext(), intent);
}
}
/**
* BootReceiverからのサービス起動例
*/
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
if (NotifyService.enable(context)) {
Intent si = new Intent(context, NotifyService.class);
si.putExtra("REQUEST_CODE", "NONE");
ServiceUtil.startServiceWithContextCompat(context, si);
}
}
}
}
4.Serviceの永続化について
スマホ端末を再起動した時にServiceを起動する様にしないと、スマホを停止するとサービスが動かなくなりますので、Serviceを実装する場合は、必ずOSの起動時にServiceが起動する様に実装する必要があります。
以下にサービスを永続化する方法を記します。
1.OS再起動時に自動でサービスが起動する様にする。
[build.gradle(Module)]
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.zive.shibayu.pointpassbook">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_cat_icon2"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_cat_icon2_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
・・・
<--↓↓↓追加↓↓↓>
<receiver
android:name=".receiver.BootReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<--↑↑↑追加↑↑↑>
</application>
<--↓↓↓追加↓↓↓>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<--↑↑↑追加↑↑↑>
</manifest>
[BootReceiver]
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
if (NotifyService.enable(context)) {
Intent si = new Intent(context, NotifyService.class);
si.putExtra("REQUEST_CODE", "NONE");
ServiceUtil.startServiceWithContextCompat(context, si);
}
}
}
}
2.サービスクラスのonStartCommandの戻り値をSTART_STICKYに変更する。
public class XXX {
public int onStartCommand(Intent intent, int flags, int startId) {
・・・
return START_STICKY;
}
}
4.Service機能の実装で困ったら
本家のAndroid Developersサイトを見るのが一番ですよー。
リンク貼っときまーす。
https://developer.android.com/guide/components/services?hl=ja
本日は以上です。この記事が少しでもお役に立てば幸いです。