#blog2navi()
*NativeScriptでServiceを実装する [#s51b7dce]
~NativeScriptでAndroidのサービスを実装する方法は概ねマニュアル通りなのですが、若干はまったのでメモです。
~NativeScript+Serviceで検索すると[[このへん:https://www.nativescript.org/blog/using-android-background-services-in-nativescript]]とかが出てくるのですが、なんだか分かりづらいです。~
私が参考にしたのは[[こちら:https://github.com/NativeScript/nativescript-geolocation/blob/master/demo/app/background-service.ts]]でした。シンプルです。~
以下、手順です。
+ サービスの初期化~
app/app.jsに以下のように書きます。
#code(php){{{
const utils = require("tns-core-modules/utils/utils");
const application = require("tns-core-modules/application");
const Platform = require("tns-core-modules/platform");
const jobId = 1;
function stopBackgroundJob() {
if (application.android) {
let context = utils.ad.getApplicationContext();
const jobScheduler = context.getSystemService(android.content.Context.JOB_SCHEDULER_SERVICE);
if (jobScheduler.getPendingJob(jobId) !== null) {
jobScheduler.cancel(jobId);
console.log(`initservice: Job Canceled: ${jobId}`);
}
}
}
// アプリを閉じたらサービスも止める
// application.on(application.exitEvent, stopBackgroundJob);
function startBackground() {
console.log('startBackground sdkver='+Platform.device.sdkVersion);
if (application.android) {
let context = utils.ad.getApplicationContext();
if (Platform.device.sdkVersion < "26") {
let intent = new android.content.Intent(context, jp.inxray.scop.BackgroundService.class);
context.startService(intent);
} else {
const jobScheduler = context.getSystemService(android.content.Context.JOB_SCHEDULER_SERVICE);
const component = new android.content.ComponentName(context, jp.inxray.scop.BackgroundService26.class);
const builder = new (android.app).job.JobInfo.Builder(jobId, component);
builder.setOverrideDeadline(0);
return jobScheduler.schedule(builder.build());
}
}
}
function stopBackgroundTap() {
if (application.android) {
if (Platform.device.sdkVersion < "26") {
let context = utils.ad.getApplicationContext();
let intent = new android.content.Intent(context, jp.inxray.scop.BackgroundService.class);
context.stopService(intent);
} else {
stopBackgroundJob();
}
}
}
// 開始
startBackground();
}}}
~
+ サービス本体です~
app/service/background.js
#code(php){{{
const application = require("tns-core-modules/application");
const Timer = require("tns-core-modules/timer");
const Platform = require("tns-core-modules/platform");
let timerid = null;
if (application.android) {
if (Platform.device.sdkVersion < "26") {
(android.app.Service).extend("jp.inxray.scop.BackgroundService", {
onStartCommand: function (intent, flags, startId) {
this.super.onStartCommand(intent, flags, startId);
return android.app.Service.START_STICKY;
},
onCreate: function () {
startTimer(30);
console.log("background: start Service");
},
onBind: function (intent) {
console.log("background: on Bind Services");
},
onUnbind: function (intent) {
console.log('background: UnBind Service');
},
onDestroy: function () {
console.log('background: service onDestroy');
stopTimer();
}
});
} else {
(android.app).job.JobService.extend("jp.inxray.scop.BackgroundService26", {
onStartJob() {
startTimer(30);
console.log('background: service onStartJob');
return true;
},
onStopJob(jobParameters) {
console.log('background: service onStopJob');
this.jobFinished(jobParameters, false);
stopTimer();
return false;
},
});
}
}
/**
* 定期実行設定
* @param {number} interval 時間間隔(sec)
*/
function startTimer(interval) {
if(interval>0 && timerid==null){
timerid = Timer.setInterval(() => {
const randNumber = Math.random();
console.log(randNumber);
}, interval*1000);
console.log('worker: set timer to interval '+ interval*1000 + 'ms.');
}
}
/**
* 定期実行停止
*/
function stopTimer() {
if(timerid!=null){
Timer.clearInterval(timerid);
timerid = null;
console.log('background: stop timer.');
}
}
}}}
~
+ manifestにサービスを記述します~
app/App_Resources/Android/src/main/AndroidManifest.xml
#code(xml){{{
<application
:
<service android:name="jp.inxray.scop.BackgroundService" android:exported="false"></service>
<service android:name="jp.inxray.scop.BackgroundService26" android:permission="android.permission.BIND_JOB_SERVICE" android:enabled="true" android:exported="false"></service>
</application>
}}}
~
+ webpack.configの設定~
webpack(--bundle)を使わない場合はここまでで動くのですが、NativeScript6からwebpack必須になりました。~
webpackに対応するには以下の設定が必要です。~
~webpack.config.js
#code(php){{{
const appComponents = [
"tns-core-modules/ui/frame",
"tns-core-modules/ui/frame/activity",
resolve(__dirname, "app/service/background.js"),
];
}}}
4行目にサービスの実行ファイルを追記しています。
~以上で、&inlinecode{tns run android --bundle};すると、アプリを閉じてもタスクリストから終了しても、30秒ごとにランダムな数字がコンソールにログ出力されます。
~以上です。
#htmlinsert(twitterbutton.html)
RIGHT:Category: [[[NativeScript>日記/Category/NativeScript]]] - 14:15:52
----
#htmlinsert(20191130_service.html)
----
RIGHT:&blog2trackback();
#comment(above)
#blog2navi()