Android でセンサーを使う
授業内容 センサーとは何かおさらい MEMS フレームワークとは何か? を理理解する 演習 センサーのフレームワークを理理解する Androidで使 用できるセンサーの種類 センサーを使ってみる
センサーとは?
MEMS
MEMS の採 用例例
Android で使 用可能なセンサー p.27 表 - 2
フレームワークとは? 手続き! 決まった 方法! Android はフレームワークでできている!
Activity はフレームワーク public class MainActivity extends Activity {!! @Override! protected void oncreate(bundle savedinstancestate) {! super.oncreate(savedinstancestate);!! @Override! protected void onpause() {! super.onpause();! extends Activity を書くと oncreate, onpause などの実装が 自動的に呼ばれる
AsyncTask もフレームワーク public class MyAsynctask extends AsyncTask<Void,Void,Void> {!! @Override! protected void onpreexecute(context context) {! // 事前処理理!! @Override! protected void doinbackground(void params) {! // バックグラウンド処理理!
onclick() もフレームワーク public class MyActivity! extends Activity implements OnClickListner {!! @Override! protected void oncreate(bundle savedinstancestate) {! super.oncreate(savedinstancestate);!! @Override! public void onclick(view v) {! // ボタンを押された時の処理理! ボタンが押された時に呼ばれるコールバック関数 extends には 一つだけ : クラス継承 implements には複数 : インターフェース
演習 いつものボタンを作成 public class MainActivity extends Activity {! private Button btn;!! @Override! protected void oncreate(bundle savedinstancestate) {! super.oncreate(savedinstancestate);! setcontentview(r.layout.activity_main);!! btn = (Button) findviewbyid(r.id.btn);!! btn.setonclicklistener(new OnClickListener() {! @Override! public void onclick(view v) {! Log.i( BUTTON, "Pushed");! });!
演習 implements へ書き換える public class MainActivity! extends Activity implements OnClickListener {! private Button btn;!! @Override! protected void oncreate(bundle savedinstancestate) {! super.oncreate(savedinstancestate);! setcontentview(r.layout.activity_main);!! btn = (Button) findviewbyid(r.id.btn);!! btn.setonclicklistener(this);! 自分 自 身を指す!...!
補 足 implements へ書き換える this と書くとエラーになり候補が出てくる implements が 自動的に追加される
解答 implements へ書き換える public class MainActivity! extends Activity implemements OnClickListener {! private Button btn;!! @Override! protected void oncreate(bundle savedinstancestate) {! super.oncreate(savedinstancestate);! setcontentview(r.layout.activity_main);!! btn = (Button) findviewbyid(r.id.btn);!! btn.setonclicklistener(this);!! @Override! public void onclick(view v) {! Log.i(TAG, "Pushed");!
implements を追加 コールバック関数を追加する!
センサーを使うために 利利 用するためのお作法! センサーフレームワークの使 用
センサー情報フレームワーク Sensor! SensorManager! SensorEventListener! SensorEvent SensorManager を取得して 使 用するセンサーを宣 言! SensorEventListener で設定したコールバックで! センサーのイベントが取得できる!
センサーフレームワーク public class MainActivity! extends Activity implemements SensorEventListener {!! @Override! protected void oncreate(bundle savedinstancestate) {! super.oncreate(savedinstancestate);! setcontentview(r.layout.activity_main);!! @Override! public void onsensorchanged(sensorevent event) {! //!! @Override! public void onaccuracychanged(sensor sensor, int accuracy) {! //! センサーに動きがあったら! onsensorchanged コールバックが呼ばれる!
センサーを使うための作法 システムにセンサーを使うという宣 言をする! どのセンサーを使うか宣 言する! アプリ起動時にセンサーを ON( 有効化 ) にする! アプリ終了了時にセンサーを OFF( 無効化 ) にする!
センサーマネージャの取得 private SensorManager msensormanager;!! msensormanager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);! SensorManager をシステムから取得する! システムにセンサーを使うという宣 言
センサー情報の取得と有効化 Sensor accelaration =! msensormanager.getdefaultsensor(sensor.type_accelerometer);! SensorManager から使 用するセンサーを設定する! 取得したいセンサーは Sensor.TYPE_XXXX を変えれば良良い! どのセンサーを使うか宣 言する msensormanager.registaerlistener(this, accelaration, SensorManager.SENSOR_DELAY_NORMAL);! センサーを有効化するためにはレジスト登録する必要がある! アプリ起動時にセンサーを ON( 有効化 ) にする
registerlistener API public boolean registerlistener (SensorEventListener listener, Sensor sensor, int rateus) イベントリスナー 使 用するセンサー センサーの遅延設定 イベントリスナーに this と書くと Activity に implements を! 書いて Activity 内にイベントコールバックを追加する! public class SensorActivity extends Activity implements SensorEventListener {!! :!!
イベントコールバック @Override! public final void onaccuracychanged(sensor sensor, int accuracy) {! // センサーの精度が変化した場合に呼ばれる! @Override! public final void onsensorchanged(sensorevent event) {! // センサーの値が変化した場合に呼ばれる
センサーの有効化と無効化 @Override! protected void onresume() {! super.onresume();! msensormanager.registerlistener(this, acceleration,! SensorManager.SENSOR_DELAY_NORMAL);! @Override! protected void onpause() {! super.onpause();! msensormanager.unregisterlistener(this); 基本的には onresume() でセンサーを有効化して onpause() で無効化する! センサーを有効にしたままだと バッテリーを消費するので注意! アプリ終了了時にセンサーを OFF( 無効化 ) にする
遅延設定 センサーの変化値がイベントコールバックを呼び出す遅延時間を設定!
定数値 Context.SENSOR_SERVICE! Sensor.TYPE_ACCELEROMETER! SensorManager.SENSOR_DELAY_NORMAL class Context {! public static final String SENSOR_SERVICE = sensor ; class Sensor {! public static final int TYPE_ACCELEROMETER = 1;! どこからでも参照できる 定数値 ( 変更更不不可 )
センサー値の取得 @Override! public final void onsensorchanged(sensorevent event) {! // センサーの値が変化した場合に呼ばれる リファレンス SensorEvent event int accuray : 精度度 Sensor sensor : センサーオブジェクト long timestamp : イベントの発 生した時間 float[] values : センサーデータ配列列
演習 教科書 p33 のコードを参照して 実装してみる 注意 SensorActivity となっているがキニシナイ TextView を 3 つ 用意する ( あとで使う )
写経の仕 方 public class MainActivity! extends Activity implemements SensorEventListener {!! @Override! protected void oncreate(bundle savedinstancestate) {! super.oncreate(savedinstancestate);! setcontentview(r.layout.activity_main);!! @Override! public void onsensorchanged(sensorevent event) {! //!! @Override! public void onaccuracychanged(sensor sensor, int accuracy) {! //! @Override implements などのキーワードを探す 自動 生成
加速度度センサー値の取得 // センサーの値が変化した場合に呼ばれる! float[] accell = new float[3]; accell[0] = event.values[0];! accell[1] = event.values[1];! accell[2] = event.values[2];!! Log.i( TAG, "accell[x] " + accell[0]);! Log.i(TAG, "accell[y] " + accell[1]);! Log.i(TAG, "accell[z] " + accell[2]);!! msensor[0].settext(string.valueof(accell[0]));! msensor[1].settext(string.valueof(accell[1]));! msensor[2].settext(string.valueof(accell[2])); values にそれぞれ x, y, z 軸の加速度度が 入っている
演習 加速度度センサーを取得するプログラムを教科書 p.35 を参照しながら完成させてみる 難しいと思う 人は下記からダウンロード して動作を確認してみよう h"p://goo.gl/kgg8hz AxisSensor プロジェクト
Advanced 演習 端末に実装されているセンサーの種類を列列挙してみる 搭載されているセンサーの種類は何種類? ヒント Sensor.TYPE_ ALL SensorManager クラス ArrayList を使う 表 示は Sensor#getType()
センサーのカテゴリ分け
GPS (Global Positioning System)
GPS はセンサーではなく受信機 x, y, z, t の連 立立 方程式を解くことになるので 4 つの衛星を捕捉する必要がある
Google Play Services 位置情報の提供 Googleサービスへの認証 連絡先の同期 怪しいアプリの検出
Google Play Services の導 入 Android SDK Manager から選択
Google Play Services の導 入 Existing Android Code Into Workspace
Google Play Services の導 入 $(ANDORID_SDK)/extras/google/google_play_services Browse から google- play- services_ lib を選択 Copy projects into workspace に
位置情報精度度の設定
位置情報精度度 GPS > WiFi > 基地局 数 m 十数 m ~約 200m 数千 m
位置情報取得の 方法 1 回だけ取得する 連続的に取得する
1 回だけ取得する場合 Google Play Servicesに接続 位置情報問い合わせ 位置情報取得 終了了時にGoogle Play Services を切切断
連続的に取得する場合 Google Play Servicesに接続 位置情報更更新リスナーを設定 更更新をコールバックで受け取る 終了了時にリスナーを破棄 終了了時にGoogle Play Services を切切断
GPS 情報フレームワーク LocationClient! Location! LocationClient を 生成して Play Service へ接続! 位置情報はバックグラウンドで取得され onconnected の! コールバック呼び出し後 位置情報を取得できる!
GPS 情報フレームワーク LocationClient 3.Location 2. 接続 OK 1. 接続要求 Google Play Services バックグラウンドで位置を取得
LocationClient の取得 private LocationClient mlocationclient;!! mlocationclient = new LocationClient(this, this, this);! LocationClient(Context context, GooglePlayServicesClient.ConnectionCallbacks connectioncallbacks, GooglePlayServicesClient.OnConnectionFailedListener connectionfailedlistener) 3 つの引数に this を設定している 後半 2 つはリスナーの設定なので! Activity に implements を追加してコールバック関数が必要! public class MainAcIvity extends AcIvity implements ConnecIonCallbacks, OnConnecIonFailedListener {
イベントコールバック @Override public void onconnecionfailed(connecionresult result) { // Google Play Services の接続に失敗 } @Override public void onconnected(bundle connecionhint) { // Google Play Services に接続した } @Override public void ondisconnected() { // Google Play Services と切断した }
GPS の有効化と無効化 @Override! protected void onresume() {! super.onresume();! // Google Play Services への接続! mlocationclient.connect();!! @Override! protected void onpause(sensorevent event) {! super.onpause();! // Google Play Services との切断! mlocationclient.disconnect(); 基本的には onresume() で接続して onpause() で切切断する! GPS を有効にしたままだと バッテリーを消費するので注意!
位置情報の取得 @Override public void onconnected(bundle connecionhint) { Toast.makeText(this, "Connected", Toast.LENGTH_LONG).show(); } // 位置情報の取得 mloc = mlocaionclient.getlastlocaion(); Log.d("LOCATION", "LAT: " + mloc.getlaitude()); Log.d("LOCATION", "LON: " + mloc.getlongitude()); 位置情報は LocationClient に 入っている! connectionhint には通常 null が 入っている!
AndroidManifest の設定 <uses- sdk android:minsdkversion="19" android:targetsdkversion="19" /> <uses- permission android:name="android.permission.access_fine_location"/> GPSを使うためのパーミッションの設定! <applicaion android:allowbackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/apptheme" > Google Play Serviceを使うための宣 言! <meta- data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
パーミッションの追加 2. Add... をクリック 1. AndroidManifest.xml の Permissions タブ
パーミッションの追加 Uses Permission を選択して OK
パーミッションの追加 android.permission.access_ FINE_ LOCATION を選択
パーミッションの追加 ファイルをセーブすると 反映されることを確認
演習 位置情報取得 ここまでの説明と 教科書 p.54を 参考にして 位置情報を取得して 表 示してみる 表 示はデバッグでもトーストでも テキストでもOK 応 用 :Intent でマップ表 示してみる
Android の 3 大要素 Activity 基本中の基本 Intent 画 面の遷移 Activityの呼び出し Service バッググラウンド動作
Intent で Activity を呼び出し Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse( geo: 35.6575508, 139.69554 ); startacivity(intent); Intent.ACTION_ VIEW : 処理理を他のアプリに委譲 ( 暗黙的 Intent) geo: : スキーマを指定してシステムに丸投げ 他の例例 http: http://www.yahoo.co.jp mailto: mailto:foo@hoge.huga.com tel: tel:08003445xxx
例例えば 35.361069, 138.727867
緯度度経度度 緯度度 赤道からの 角度度 経度度 グリニッジからの 角度度 日本標準時 子午線 日本の経度度緯度度原点! Latitude( 緯度度 ) : 北北緯 35 度度 39 分 29 秒 1527 = 35.65809922! Longitude( 経度度 ): 東経 139 度度 44 分 28 秒 8869 = 139.74135747!
位置情報の更更新 LocationClient! LocationRequest! LocationRequest で更更新リクエストを 生成しておき! LocationClient でリスナーをセットすると! コールバックで更更新された位置情報を取得できる!
onconnected メソッド @Override public void onconnected(bundle connecionhint) { // 位置情報の更新リクエスト LocaIonRequest req = LocaIonRequest.create(); req.setinterval(5000); req.setsmallestdisplacement(1); req.setpriority(locaionrequest.priority_high_accuracy); mlocaionclient.requestlocaionupdates(req, this); } create() で更更新リクエストを 生成! setinterval() で更更新間隔の 目安 (ms)! setsmallestdisplacement() で更更新距離離 (m)! setpriority で更更新のプライオリティをセット! requestlocationupdates() でリスナーをセット! public class MainAcIvity extends AcIvity implements ConnecIonCallbacks, OnConnecIonFailedListener, LocaIonListener {
onlocationchanged メソッド @Override public void onlocaionchanged(locaion loc) { Toast.makeText(this, "Get LocaIon", Toast.LENGTH_SHORT).show(); } mlocaion[0].settext(string.valueof(loc.getlaitude())); mlocaion[1].settext(string.valueof(loc.getlongitude())); LocationUpdate のリスナーは onpause で解除しておく! @Override protected void onpause() { super.onpause(); // LocaIonListener を解除 mlocaionclient.removelocaionupdates(this); // Google Play Services との切断 mlocaionclient.disconnect(); }
サンプルアプリ LocationReq プロジェクト!