Android Studioで一応動くアプリを作ってみる2020年03月01日 00:00



Android Studioで簡単な音楽プレイヤーを作ったのでそれについて書く。
ソフト開発は自己責任でやって下さい。

1.Android Studioとは(自己責任でやってね)

その名の通りAndroidのアプリを作る開発システムだ。
パソコンではHSPで簡単なソフトを作る事はあるのだがAndroidのアプリ作成はやった事はなかった。使えるアプリはあるし特に作りたいものが無かったからだ。

そうなのだが最近買ったbluetoothスピーカーがWindows10のパソコンとの相性が悪くまともに再生できない。どうしようか考えていたのだがAndroidではほぼ正常に再生できるのでそいつでアプリを作れないが調べ始めた。HSPのソフトを移植できるというのを試したけど失敗。必要なソフトが古い様で手に入れられなかった。

そこでAndroid StudioでMP3再生位はなんとかならないかと思い作ったのがこれだ。HSPで作成した曲の最初の1分のみ再生するというもの。
なんとかなったけどその程度なので実用性は無い。
しかしスマホ単体でも使えるので個人用としては十分。

Androidアプリ作成を考えている人がお試しでやるのは良いと思う。
VisualBasicの経験がある人ならなんとか使えるレベルだ。

2.Android Studioの環境を整備する(自己責任でやってね)

アプリの開発はAndroid Studio単独で可能だ。導入についてまとめておく。
その辺を親切に書いてあるサイトは結構あるのでそちらを参照するのも良いと思う。

下記のリンクからWindows版64ビットのものがダウンロードできる。
結構重いソフトなので64ビット版のWindows10が走ってないPCだと厳しいかも。
exeファイルを実行するとインストールが始まる。特に面倒な設定は無い。
スタート内にAndroid Studioが追加されているので実行。
右クリックでスタートメニューにピン止めしておくのが良い。

アプリが始まるとプロジェクトの作成が自動的に始まるのでこれもデフォルト設定で進めれば問題無い。MyApplicationという名前でプロジェクトが作成される。
kotlinというC言語的なもので作成される。
右上にAVD Manegerというのがあるので実行用の仮想端末を作成する。
アイコンをクリックして右下にCreateVisualDeviceで作成。
デフォルトでPixel2が選ばれているのでそれで良い。

右上にトンカチのアイコンがあるのでそれをクリックするとビルドされる。
右上にPixel2が表示されているのでその右横の三角ボタンを押すと実行される。
しばらく待つとスマホの画面が表示される。Hello Worldが出ればOK。
右下にBuildとRunがタブが出るので適当にクリックすると状況が表示される。
終わる時は右下横に□ボタンが表示されているのでそれで終了後、スマホ画面も×ボタンで閉じる。

実機で動かす時は右上のSDK Manegerで実機スマホのAndroidのバージョンとGoogle USB Driver をインストールする。Android SDK-SDK Platformとdroid SDK-SDK Toolsのタブで選択。
スマホを開発者モードにする。(システム内で操作してメニューを出す、機種毎に違うのでネットで確認)
USB接続時にUSBデバックがONになっているのを確認する。
最初に警告が出た時はファイルのやり取りをするを選択した方が良さそう。
USBを接続すると警告が出て動き出す。
その後はスマホ上にMyApplicationというアイコンが出来るのでそれを操作して単独で実行できる。



3.簡単な説明(自己責任でやってね)

作成に使用するのは下記の4つのファイルなので左画面でダブルクリックして右側にタブを追加する。
 MainActivity.kt (app-java-com.example~) ソフト記述。
 activity_main.xml (app-res-layout)   画面構成
 strings.xml (app-res-values)      表示コメント登録
 Androidmanifest.xml (app-manifests)  縦横を固定する場合利用

activity_main.xmlでは左下でDesign/Text画面が選べる。
コードを貼り付ける時はText、自分で変更する時はDesignを使う。
strings.xmlでも右上にOpen editorというのがあるが簡単なのでそのまま編集で良い。

まずMP3を再生するためのデータをコピーする。
左画面のresを右クリックしてNew-Directoryでrawというディレクトリを作成する。
(これは良く使われる名前なので合わせておく)
用意したMP3ファイルをコピーしてrawで右クリックしてPasteする。
MP3ファイルは英小文字と数字しか認識してくれない。大文字もダメだった。
(今回はmusic01.mp3~music03.mp3のファイルを用意)

下記のソースをそれぞれのタブに貼り付ける。自動でコードチェックをしてくれる。左上のアイコンでビルド後実行する。

テキストを変更するにはstrings.xmlのtext_messageを変更してから
textView.setText(R.string.text_message) とやった方がうまくいく。
textView.setText("再生中")とやるとエラーが出る事がある。
しかし、正式なのを1つ記述するとその後は正常に処理されることがある。謎だ。

MP3再生は下記のコマンドを追加、使用すると可能。意外と簡単。
曲変更は.release()でメモリ解放してから再度MediaPlayer.createした方が良さそう。

 import android.media.MediaPlayer //MediaPlayer使用
 lateinit var mpp : MediaPlayer //操作をmppに指定
 mpp = MediaPlayer.create (this, R.raw.music01) //曲指定
 mpp.start() //開始
 mpp.pause() //一時停止
 mpp.stop() //終了
 mpp.release() //メモリ解放

うまく行かない時は下記も試して下さい。
MediaPlayer.create(getApplicationContext(), R.raw.music01)

1秒毎にhnd1がrnb1関数を呼ぶようになってます。

変数はval(固定?)かvar(変動?)。配列は変更してもなぜだかval。
;(セミコロン)は複数のコマンドを1行に書く時のみ必要。
関数はfunで指定。
==(等しい)、!=(違う)等は他の言語に似ている。
ボタンを作成したらbutton.setOnClickListener{}(IDがbuttonの場合)のコードを追加するとクリックでの処理が指定できる。

曲数を増やす時はデータをrawにPasteしてから
全曲数anmを増やす、必要ならpnoの配列数も増やす、when内のcreate部分を変更。
R.rawのみの状態でコピーしてから.(ドット)入力でデータの一覧が表示されるのでこれを使うと楽だ。(データは英小文字、数字のみ)

textViewの中の文字を中央寄りに表示するにはGravity-center。
縦横の表示が切り替わると変になるので縦位置に固定しています。
Androidmanifest.xml に android:screenOrientation="portrait" を追加。

どこかのソフト例にありそうな程度のソフトなので自己責任で自由に使ってもらっていいです。
一応、著作権はぷれでたが保持します。(著作権とは良い響きだ)
記事の無断転載は止めて下さい。


4.全体的なまとめ(自己責任でやってね)

苦労したけどなんとか完成。売り物には到底ならないが個人的には使える。
上でも書いたがkotlinというのはC言語的な記述が出来るのでVisualBasic経験者ならなんとかなるレベルだ。C言語も少し知っているとさらに楽。

しかし、javaの情報と混在しているので意外と難しく苦戦した。
rawフォルダ内やSDカード内のファイル名を知りたかったのだがこれが分からず挫折。例はあるんだけど仕様が変わっているという話だ。結局、ベタなアプリとなった。ネット上にはどこかでパクってきた動かないコードを載せている
なんちゃって開発者も多いのも迷惑だったな。探すのも一苦労だ。

初心者のハードルとしてはやや高いのでこれが参考になれば良いです。
(kotlinとは南ことりの事か? (^^;; )


5.ソースリスト(自己責任でやってね)

下記にありますそれぞれのタブに貼り付けて下さい。

(MainActivity.kt)

package com.example.myapplication

import android.app.Activity
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

import kotlinx.android.synthetic.main.activity_main.*
import android.media.MediaPlayer //曲再生
import android.os.Handler //タイマー用
import java.util.Random //乱数用

class MainActivity : AppCompatActivity() {
lateinit var mpp : MediaPlayer

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

var tim1 = 0 //タイマー
var num1 = 1 //曲順
val anm = 3 //全曲数
var sw = 0 //演奏/停止
val pno = Array<Int>(anm+2,{0}) //再生曲番号

fun chg_mus() : Unit { //曲変更
if(num1>1) {mpp.stop(); mpp.release() } //2曲目から停止とリリースをする
var mn = R.raw.music01 //曲名データ設定

when(pno[num1]){ //曲セット
1 -> { mn = R.raw.music01 }
2 -> { mn = R.raw.music02 }
3 -> { mn = R.raw.music03 }
}

if(num1>=1 && num1<=anm) { //再生
mpp = MediaPlayer.create(this,mn) //曲設定
val p = num1.toString() + " : 再生中" //番号設定
button.setText(p) //ボタン表示
textView.setText(mn) //テキストに曲名表示
mpp.start() //再生開始
}
else { //終了
textView.setText(R.string.text_message2) //テキスト表示
button.setText(R.string.text_message3) //ボタン表示
num1 = 1 //最初に戻る
sw = 0 //再生停止
tim1 = 0 //タイマー
}
}

fun rndno() : Int { //乱数発生
val n = Random()
val m = n.nextInt(anm) + 1 //全曲内の乱数
return m
}

fun setpno() : Unit { //曲順決定
var n = 1
while (n<=anm) { //全曲の順番を決定
val x = rndno() //乱数
var y = 1
while(y<=n) { //曲の重複が無いのを確認
if(x==pno[y]) { break }
y++
}
if(y>n) { pno[n] = x; n++ } //重複が無いなら次へ
}
}

val hnd1 = Handler() //タイマー用ハンドル
val rnb1 = object : Runnable{ //タイマー処理
override fun run() { //
if(sw==1){ tim1++ } //タイマー加算
if(tim1>=60){ //一定時間で曲変更
tim1 = 0 //タイマーリセット
num1++ //曲順+1
chg_mus() //曲変更
}
hnd1.postDelayed(this,1000) //1秒後呼び出し
}
}

setpno() //曲順決定
button.setText(R.string.text_message3) //ボタン表示
hnd1.post(rnb1) //タイマースタート

button.setOnClickListener{ //ボタンON処理
if(sw==0) { //再生開始
sw = 1 //再生中
if(num1==1 && tim1<2) { //開始
chg_mus() //曲変更
}
else{ //中断中
val p = num1.toString() + " : 再生中"
button.setText(p) //ボタン表示
mpp.start() //再生
}
}
else { //一時停止
sw = 0 //停止中
button.setText(R.string.text_message3) //ボタン表示
mpp.pause() //一時停止
}
}

button2.setOnClickListener { //ボタン2ON処理
button.setText(R.string.text_message) //ボタン表示
mpp.stop() //終了
mpp.release() //メモリ解放
moveTaskToBack(true) //アプリ終了
}

} //onCreate
} //MainActivity

(activity_main.xml)

xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="50dp"
android:text="終了"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent" />

<TextView
android:id="@+id/textView"
android:layout_width="300dp"
android:layout_height="70dp"
android:layout_marginTop="50dp"
android:layout_marginBottom="50dp"
android:gravity="center"
android:text="曲名"
android:textSize="24sp"
app:layout_constraintBottom_toTopOf="@+id/button2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button" />

<Button
android:id="@+id/button"
android:layout_width="120dp"
android:layout_height="50dp"
android:layout_marginTop="50dp"
android:text="Button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

(strings.xml)

<resources>
<string name="app_name">My Application</string>
<string name="text_message">終了中</string>
<string name="text_message2">再生終了</string>
<string name="text_message3">停止中</string>
</resources>

(Androidmanifest.xml)

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication" >

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
<activity android:name=".MainActivity" android:screenOrientation="portrait">

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</activity>
</application>

</manifest>