用 NativeScript-Vue 建立一個倒數計時器APP

Ding
9 min readFeb 21, 2019

--

分享一下怎麼樣用 {N}-Vue 做出一個簡單的健身倒數計時器,安裝2個套件,讀取手機內部聲音檔案,倒數計時完後播放聲音。

環境

  • nativescript 5.2.0
  • Sidekick
  • MacOS

Step 1.建立專案

使用 sidekick 建立 Vue 專案

image

看到以下表示專案建立完成:

image

Step 2.安裝相關套件

tns plugin add nativescript-mediafilepicker
tns plugin add nativescript-audio

提醒: nativescript-audionativescript-audio-player 是不同的,別搞混

若安裝成功可以在 package.json 裡看到

image

安裝完 plugin 後,記得下指令 rm -rf platforms

編輯 app/components/Home.vue

看官網文件得知 import 的方式:

<script>
const { Mediafilepicker } = require("nativescript-mediafilepicker");
import { TNSPlayer } from "nativescript-audio";
</script>

Step 3.版面

<template>
<Page class="page">
<ActionBar class="action-bar">
<Label class="action-bar-title" text="Workout rest timer"></Label>
</ActionBar>
<StackLayout>
<FlexboxLayout class="center">
<Button @tap="pickFile" text="Select audio"></Button>
<Button @tap="count_down(3)" text="3 sec"></Button>
<Button @tap="count_down(60)" text="1 min"></Button>
<Button @tap="reset" text="reset"></Button>
</FlexboxLayout>
<Label :text="display_num" class="display"></Label>
<Label :text="'play:' + audioPath"></Label>
<Button v-if="showStopbtn" @tap="clickStop" text="暫停"></Button>
</StackLayout>
</Page>
</template>
layout

style:

<style scoped lang="scss">
.display {
font-size: 85;
text-align: center;
}
.center {
justify-content: center;
align-items: center;
}
</style>

Step 4. 商業邏輯

Step 4.0 解釋data

data() {
return {
display_num: 0,
c_id: null,
audioPath: null,
player: null,
showStopbtn: false
};
},

display_num 為螢幕上顯示倒數的數字
audioPath:存儲使用者選擇的音樂檔
showStopbtn:判斷是否顯示「暫停」按鈕的 flag

函數結構:

methods: {
pickFile() {
// Put it later
},
count_down(num) {
// Put it later
},
play() {
// Put it later
},
clickStop() {
// Put it later
},
reset() {
// Put it later
}
}

Step 4.1 pickFile

按下 Select Audio 按鈕後,使用 nativescript-mediafilepicker plugin,挑選手機內部聲音檔

根據 nativescript-mediafilepicker 的文件

pickFile() {
let options = {
android: {
maxNumberFiles: 1, // 只接受挑選一個檔案
extensions: ["mp3"] //只接受 *.mp3
}
};
let mpicker = new Mediafilepicker();
mpicker.openFilePicker(options);
mpicker.on("getFiles", res => {
let results = res.object.get("results");
// 選到的檔案路徑為 results[0].file,設定到 `this.audioPath` 裡
this.audioPath = results[0].file;
console.log("Set path: ", this.audioPath);
});
mpicker.on("error", res => {
let msg = res.object.get("msg");
console.log(msg);
});
mpicker.on("cancel", res => {
let msg = res.object.get("msg");
console.log(msg);
});
},

Step 4.2 count_down

當按下 3 sec 的按鈕時,執行count_down(3),如果還有其他的計時器正在倒數,先停止其他計器器。再開始新的倒數。倒數結束時,呼叫 this.play() 播放音樂。

count_down(num) {
if (this.c_id) clearInterval(this.c_id);
this.display_num = num;
this.showStopbtn = true //顯示「Stop」按鈕
this.c_id = setInterval(() => {
this.display_num = this.display_num - 1;
if (this.display_num === 0) {
this.display_num = `Time's up`;
this.play(); //播放音樂
clearInterval(this.c_id); //把計時器清空
}
}, 1000);
}

Step 4.3 play

當倒數結束時,執行 this.play() 來播放音樂

根據 nativescript-audio 的文件,學習使用方式。
把要播放的檔案路徑,設定到 audioFile 中。

play() {
if (!this.audioPath) return;
this.player = new TNSPlayer();
const playerOptions = {
// 把 4.1 選到的 audioPath 指定給 audioFile 參數
audioFile: this.audioPath,
loop: false,
completeCallback: function() {
console.log("finished playing");
},
errorCallback: function(errorObject) {
console.log(JSON.stringify(errorObject));
},
infoCallback: function(args) {
console.log(JSON.stringify(args));
}
};
this.player
.playFromUrl(playerOptions)
.then(res => {
console.log(res);
})
.catch(err => {
console.log("something went wrong...", err);
});
}, // end play

Step 4.4 clickStop

當下按 暫停 按鈕時,呼叫 clickStop

clickStop() {
if (this.c_id) clearInterval(this.c_id);
if (this.player) this.player.pause();
this.showStopbtn = false;
this.display_num = 0;
},

Step 4.5 reset

當按下 Reset 的按鈕時,執行reset()

reset() {
if (this.c_id) clearInterval(this.c_id);
this.display_num = 0;
this.audioPath = null;
if (this.player) this.player.pause();
this.showStopbtn = false;
},

Step 5. 打開模擬器

tns run android --bundle

Step 6. 在模擬器裡新增檔案

把聲音檔用拖拉的方式拉到 emulator 裡,他會存在 /sdcard/download
這時候請長按模擬器的電源,重新開機,如此程式才能正常讀取到檔案。

https://stackoverflow.com/questions/2808632/manually-put-files-to-android-emulator-sd-card

Step 7. Demo

demo

The demo code

https://github.com/advancedor96/my_timer

--

--

Responses (1)