簡単なアプリの製作を体験しましょう。このアプリは、ユーザインタフェースの基本形(テキスト出力とボタン)しか持たないので、これだけでは面白くありませんが、ロボットやゲームのコントロールなどに使えるモーションセンサの他、いろいろな使い道があります。
プロジェクトの作成
- Android Studio を起動し、Welcome 画面で、"Create New Project"を選択
- Select a Project Template 画面で、Empty Activity を選んで、Nextボタンをクリック
- 各種のActivityの雛型が用意されているが、ここでは、Empty Activityという空の画面から作りこむことにする。Activityについては、後で説明。
- Configure Your Prohect 画面で、次の図のように設定して、Finishボタンをクリック
- Name:
- プロジェクト名を設定する。通常は。任意の名前を付けてよいが、ここでは、姓(ローマ字)名列番号(3桁)とする。ローマ字と名列番号の間にスペースを入れないで、続けて書くこと。[例] Kitagawa777
- Package name:
- アプリケーションの公開ID。通常は、自社ドメインを逆順で表記するのが慣習となっている(Javaの名残)。ここでは、仮に jp.merl.プロジェクト名 としておく。
- Save location:
- プロジェクトの保存ディレクトリを指定。ここでは、デスクトップを指定。ただし、Users\の後の kitagawa のところは、各自のユーザ名(ログイン名)を書くこと。
- Language:
- プログラミング言語を指定。ここでは、Java を選択。Googleが推奨している Kotlin を選ぶこともできる(Javaは汎用性がありますが、Androidアプリを本格的に開発するのであれば、Kotlinを選ぶとよいでしょう)。
- Minimum API level:
- APIレベルは、ターゲットとするデバイスに搭載されているAndroidのバージョンに合わせて選択する。APIレベルが高い方が新しい技術に対応しているが、あまり最新のものにすると、少し前のスマートフォンで作成したアプリが実行できなくなる。設定欄の下の行に、目安として何%のデバイスで動作するか表示されるので参考にする。
- しばらく待っていると、MainActivityのViewまたはMainActivityのclass宣言が表示される(初回は、少し時間がかかる)
[参考] アクティビティという言葉がよく出てきますが、Androidのアプリケーションの動作は、アクティビティの状態遷移によって記述されています。アプリの画面を1枚を作るためには、アクティビティクラスを継承したクラス(処理内容や変数のセットと理解しておきましょう)とXMLファイル(画面構成や変数の内容と理解しておきましょう)を用意します。Androidのアプリケーションは、アクティビティの状態遷移(表示、開始、実行、一時停止、再表示など)を繰り返しながら動作しています。そして、各状態に遷移したときの処理と、タップなどのイベント(アプリの操作など)が起こったときの処理を記述するようにプログラムを書いていきます。アクティビティの具体的な状態遷移(またはライフサイクルという)については、WEB等で調べてみてください。後で示すJavaコードの例との対応関係が分かると思います。
ユーザインタフェースの作成
文字出力とコマンドボタンからなるシンプルなユーザインタフェースを作成します。画面要素をWidgets (またはViewオブジェクト)、画面要素を配置するコンテナをLayout (またはViewGroupオブジェクト)と呼びます。
- 左側のProject欄で、app/res/layout/activity_main.xml を探してダブルクリック
- app/res/の下には、画面構成に必要なリソースや文字定数などが保存されます。
- View欄上部のツールバーの青四角アイコンで、表示モードを Design に設定
- View欄の-/+ボタンで、表示サイズを見やすい大きさに設定(View欄の下の方に表示されている場合もある)
- 中央に小さくHello Worldが表示されているので、マウスで選択し、DELキーで削除
- View欄上側のツールバーの目玉アイコンをクリックして、Show Margines と Show System UI にチェックを入れる
- 動作テストに使用する機種の画面サイズとテーマ(配色など)を設定する
- ここでは、機種 = 5.7インチPhone (Nexus6P), テーマ = プロジェクト名(デフォルト) を使用しています。(注:この設定は、Android Studioの表示設定であり、アプリの表示には関係ありません。)
- ウィジェットの作成
- Component Tree欄で、ConstraintLayoutのみが表示されていることを確認
- この状態で、ConstraintLayoutのレイアウトが画面全体に配置されているはず。ConstraintLayout内では、親レイアウトや同じレイアウト内のウィジェット間の相対位置でウィジェット表示場所を定義することができるので、階層的なレイアウト構造を作成せずに簡単に配置ができます。
- Parette欄から TextView を View画面上にドラッグして4個配置
- さらに、Button をView画面上にドラッグして1個配置
- ウィジェットのレイアウト設定
- 配置したTextViewとButtonを、それぞれクリックし、Attributes欄で id, Layout, layout_width を下記の図のように設定する。
- ただし、Buttonは、layout_width = 0dp(match_constraint) を選んでください。各 id は、プログラムから参照する際に使用するので、分かりやすい名称に変更しておきます。id を変更すると、操作確認ダイアログが表示されることがありますが、Refactor を選んでプログラムに反映させて下さい。また、位置の設定のため、水色+マークをクリックして、値を入力します。位置の設定をやり直すときは、グレーの丸の部分をクリックします。テキストやボタンが変な位置に配置されて上手く修正できない場合は、View欄のオブジェクトを一旦削除(DELキー)して、作り直してください。
左上TextView | 右上TextView |
 |  |
左中TextView | 右中TextView |
 |  |
下段Button | |
 | |
- ウィジェットの属性設定
- 配置したTextViewなどの5つのWidgetsに対して、Attributes欄のCommon AttributesまたはAll Attributesの値を、それぞれ次のように設定する(リストがたたまれている場合は、行頭記号の三角形の部分をクリックして展開)
- (注)onClick は、ボタンをクリックしたときに実行されるメソッド名を指定しています。ただし、Attributes欄でonClickを設定すると、プログラムのコードが読みにくくなるので、コード中で、onClickに対するイベントハンドラーを設定するのが普通です。
- 最終的に、各オブジェクト(画面上の部品)の位置がおかしいときは、手動で修正しましょう。
| 左上TextView | 右上TextView | 左中TextView | 右中TextView | 下段Button |
id | textPeak | textPAccel | textCurrent | textCAccel | Reset |
text | Peak Acceleration (m/s2) X:\nY:\nZ: | 0.0\n0.0\n0.0 | Current Acceleration (m/s2) X:\nY:\nZ: | 0.0\n0.0\n0.0 | RESET |
textSize | 18sp | 18sp | 18sp | 18sp | 18sp |
textStyle | 変更なし | Bold | 変更なし | Bold | 変更なし |
onClick | 変更なし | 変更なし | 変更なし | 変更なし | peakReset |
gravity | right | right | right | right | 変更なし |
textColor | #ff000000 | #ff00ffff | #ff000000 | #ff00ffff | 変更なし |
background | 変更なし | #ff000000 | 変更なし | #ff000000 | 変更なし |
- 編集画面の右上の方にある、3個並んだアイコン(Code, Split, Design)のうち、Codeアイコンをクリックすると、View画面に対応するXML(Extensible Markup Language)のコードが表示される。XMLに慣れている人は、こちらのほうが編集しやすいかもしれない。ViewのProperties設定により、View画面上に表示されなくなったボタンやテキストも、XMLのほうで編集することができる。元に戻すには、編集画面の右上の3個並んだアイコンから、Designを選ぶ。
コードの記述
JavaやKotlinの書き方は、プログラミングの演習科目で学ぶことにして、とりあえず下記の内容をコピペして作成しましょう。基本的には、アクティビティの変化、ユーザの操作、デバイスの状態変化といったイベントごとに、実行させる処理内容(メソッド)を記述していきます。
- 左側のProject欄で、app/java/jp.merl.accel/MainActiviry をダブルクリックすると、ソースコードが表示される
- 表示されたJavaのコードを全て消して、下記のリストをコピペする。
- [注意] package の宣言は、自分のパッケージ名に合わせて修正が必要です。また、使用するAPIのバージョンによっては、一部の import 文にも修正が必要な場合があります。
package jp.merl.kitagawa777;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
// import android.support.v7.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
import java.text.DecimalFormat;
import java.util.List;
public class MainActivity extends AppCompatActivity implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mAccelerometer;
private final float[] cValues = new float[3];
private final float[] pValues = new float[3];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
List list = mSensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
if (list.size()>0) {
mAccelerometer = (Sensor) list.get(0);
}
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
@Override
public void onResume() {
super.onResume();
if (mAccelerometer != null) {
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
}
public void onStop() {
super.onStop();
mSensorManager.unregisterListener(this);
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) {
return;
}
cValues[0] = event.values[0];
cValues[1] = event.values[1];
cValues[2] = event.values[2];
for (int i=0; i<3; i++) {
if(pValues[i] < cValues[i]) {
pValues[i] = cValues[i];
}
}
DecimalFormat df = new DecimalFormat("###.####");
TextView textCAccel = findViewById(R.id.textCAccel);
TextView textPAccel = findViewById(R.id.textPAccel);
StringBuffer cBuf;
StringBuffer pBuf;
cBuf = new StringBuffer();
pBuf = new StringBuffer();
cBuf.append(df.format(cValues[0])).append("\n").append(df.format(cValues[1])).append("\n").append(df.format(cValues[2]));
pBuf.append(df.format(pValues[0])).append("\n").append(df.format(pValues[1])).append("\n").append(df.format(pValues[2]));
textCAccel.setText(cBuf.toString());
textPAccel.setText(pBuf.toString());
}
public void peakReset(View view) {
TextView textPAccel;
textPAccel = findViewById(R.id.textCAccel);
textPAccel.setText("0.0\n0.0\n0.0");
pValues[0] = 0;
pValues[1] = 0;
pValues[2] = 0;
}
}
以下に、上記Javaコードの内容を、おおまかに解説しておきますので、プログラムの流れと雰囲気を掴んでください。
- class
- 機能を実現するために必要な一連の処理(メソッド)や変数などをまとめたものです。
- package
- 複数のクラスをまとめて名前を付けたものです。同じ名前のクラスがあっても、パッケージ名が異なっていれば、別のクラスと解釈されます。
- import
- ライブラリに含まれているクラスを自分のプログラムに読み込むために、これから使用するクラスを宣言します。
- onCreate, onResume, onStopなど
- アクティビティの状態(起動時、表示、非表示など)が変化したときに実行する内容を示します。
- mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE); List list = mSensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
- 加速度センサを取得する(アプリに対する入出力ポートを用意する)ための処理です。
- onAccuracyChanged, onSensorChanged
- クラスにセンサ機能を追加した場合、これらのメソッドを用意しておく必要があります。onAccuracyChangedはセンサの精度更新、onSensorChangedはセンサ値の更新時に呼び出されるメソッドです。
- cValues[], pValues[]
- cValuesは、加速度センサの値を読み込むための配列変数、pValuesは、加速度センサの最大値を保持するための配列変数です。加速度センサの出力は、X, Y, Zの3次元であるため、その値を読み込むために3次元の配列を使用しています。
- TextView textPAccel = findViewById(R.id.textPAccel);
- 画面に配置したTextViewのid (textPAccel) を指定して、このTextViewにアクセスできるようにしています。これは、画面上のリソースにアクセスするための常套手段です。メソッドの中でローカルに宣言したため、他のメソッドでは、再度、実行する必要があります。具体的には、R.id.textPAccel(即ち textPAccel というidを持つスマホ上のリソース)を探して、textPAccelというTextView型の変数に割り当てるという処理を行っています。
- textCAccel, textPAccel
- textCAccelは、画面上右下側に配置したTextView、textPAccelは、画面上右上側に配置したTextViewに対応する変数です。それぞれ、加速度センサの現在値とピーク値を文字列に変換して代入することにより、画面表示させます。
- peakReset
- 画面上に配置したRESETボタンをタップした時に呼び出され、センサのピーク値(数値)と画面の表示(文字)をリセットしています。
ここでは、全部コピペをしましたが、自分でコードを編集する際に便利な補完機能を紹介します。
- CTRL + SPACEキーによりコードの補完ができる
- 文法エラーがあると、エディタの右端に褐色の短いラインが表示される
- エラーとなっている行の赤文字ににカーソルを置き、ALT + Enterキーを押すと、必要なクラスがインポートされエラーが消えることが多い
- クラスの機能を使用するためには、パッケージ(クラスのカテゴリ)とクラス名を指定する必要がありますが、いちいち調べて書くのは面倒なので、使用するパッケージとクラスの名前を最初に import 文で指定しておきます。import文の左に表示されている+マークをクリックして展開して、現在何がインポートされているか確認できます。今回は、全部まとめてコピペしてしまいました。
ADB(Android Debug Bridge)による動作確認とデバッグ
PCにテスト用のスマートフォン実機をUSB接続します。実機を持っていない場合は、エミュ(Emulator = PC上でスマホの動作を模擬する機能)を使用することもできますが、センサや無線通信が使えないので、実機の使用をお勧めします。まず、実機を使ってデバッグを行うために、実機の開発者向けオプション設定を行います。
[注意] Androidの実機を持っていない人は、後述のAVD(Android Virtual Device)による動作確認に飛んで下さい。
- Androidの設定メニューから、 [端末情報] - [ソフトウエア情報] (または、[システム])を選び、「ビルド番号」を7回タップすると(必要ない場合もある)、[開発者向けオプション]というメニューが、設定画面に追加される
- Androidのバージョンによっては、最初から[開発者向けオプション]がメニューに出ているので、上記の操作は必要ない。
- Androidによっては、「ビルド番号」が表示される階層が異なることがある。
- 設定画面から、[開発者向けオプション]に入り、USBデバッグ = ON に設定する
- 設定画面から、[セキュリティ]に入り、提供元不明のアプリ = ON に設定する(項目がない場合は、設定の必要はない)
- USBケーブルでPCに接続するとPCにUSBドライバがインストールされる
- 実機端末が、USBデバッグを許可するか聞いてきた場合はOKする。
- ドライバがインストールされると、PCのデバイスマネージャーに、AndroidデバイスまたはADB Interfaceが表示される。「不明なデバイス」となった場合は、Android Studioユーザガイドなどで適切なドライバーを検索して、インストールを行う。
Android Studioで作成したアプリケーションを走らせ、実機上で動作確認を行います。
- ツールバーの Run 'app' ボタン(下図のStart)をクリック
- Select Development Targetウインドウが表示されるので、使用するAndroid端末を選んでを選んで、OKボタンをクリック
- アプリにエラーがなければ、実機にアプリケーションが転送され、実機上でアプリケーションが起動するので、動作が正しいか確認する
- うまく動作した場合は、実機端末に転送されたアプリケーションを、アプリ一覧から直接起動できる。
- うまく動作しない場合は、activity_main.xmlとMainActivity.java に文法エラーがないかよく確認する
- エラーが見つからない場合は、Android Studioの一番下の方にある Logcat タブをクリックして実行時ログを調べる
- ログ(変数値などの観察)やブレークポイント(プログラムの一旦停止)の設定方法は、3年生の自主課題研究などを参考にしてください。
スマホへのインストール
実は、ADBを実行する際に、アプリがスマホにインストールされています。アプリ一覧画面でプロジェクト名のアプリを探してみてください。まだ、アイコンを設定していないので、デフォルトのBugdroid(ドロイド君)アイコンになっているはずです。

写真は、Nexus7による動作確認の様子。強く振ると、Peak Accelerationの値が大きくなりますが、あまり強く振って、スマホが飛んでいったりしないよう注意。
AVD(Android Virtual Device)による動作確認
実機がPCに接続されていない場合は、Android Studioの Run 'app' ボタン(緑三角アイコン)をクリックすると、AVD(Android Virtual Device)というエミュレータが起動します。起動する機種は、Run 'app' ボタンの左側のドロップダウンリストで選択できます。デフォルトでは、NexusとPixelしか用意されていませんが、ドロップダウンリストで、AVD Manager を選択し、+ Create Virtual Device...ボランをクリックすると、他の機種やバージョンの異なるAndroidをインストールすることができます。エミュレータを使えば、多くの種類の実機やAndroidのバージョンを用意しなくても、動作テストができるので便利です。

環境設定[1/2]
お問い合わせはこちらまで: kitagawa@is.t.kanazawa-u.ac.jp
© Kanazawa Univ., 2013-