Androidでセンサーを使う
センサーとGPS
渡辺知男
授業内容
•
センサーとは何かおさらい
–
MEMS
•
フレームワークとは何か?を理理解する
–
演習
•
センサーのフレームワークを理理解する
•
Androidで使⽤用できるセンサーの種類
•
センサーを使ってみる
Androidで使⽤用可能なセンサー
フレームワークとは?
・⼿手続き!
・決まった⽅方法!
Activityはフレームワーク
public class MainActivity extends Activity {! !
@Override!
protected void onCreate(Bundle savedInstanceState) {! super.onCreate(savedInstanceState);!
}! !
@Override!
protected void onPause() {! super.onPause();!
}! }!
extends Activityを書くと、
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へ書き換える
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) {! //!
}! }!
センサーに動きがあったら、!
センサーを使うための作法
・システムにセンサーを使うという宣⾔言をする!
・どのセンサーを使うか宣⾔言する!
・アプリ起動時にセンサーを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
イベントリスナーに”this”と書くと、Activityに”implements”を!
書いて、Activity内にイベントコールバックを追加する!
public boolean registerListener (SensorEventListener listener, Sensor sensor, int rateUs) 使⽤用するセンサー センサーの遅延設定 イベントリスナー
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(無効化)にする
遅延設定
定数値
class Context {!
public static final String SENSOR_SERVICE = “sensor”; !
}!
Context.SENSOR_SERVICE!
Sensor.TYPE_ACCELEROMETER!
SensorManager.SENSOR_DELAY_NORMAL
class Sensor {!
public static final int TYPE_ACCELEROMETER = 1; !
}!
センサー値の取得
• int accuray : 精度度
• Sensor sensor : センサーオブジェクト
• long timestamp : イベントの発⽣生した時間
• float[] values : センサーデータ配列列
リファレンス SensorEvent event @Override!public final void onSensorChanged(SensorEvent event) { ! // センサーの値が変化した場合に呼ばれる
演習
教科書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) {! //!
}! }!
加速度度センサー値の取得
valuesにそれぞれx, y, z軸の加速度度が⼊入っている
// センサーの値が変化した場合に呼ばれる! 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]));
演習
加速度度センサーを取得するプログラムを教科書
p.35を参照しながら完成させてみる
難しいと思う⼈人は下記からダウンロード
して動作を確認してみよう
h"p://goo.gl/kGG8hz
AxisSensorプロジェクト
Advanced演習
端末に実装されているセンサーの種類を列列挙してみる
搭載されているセンサーの種類は何種類?
ヒント
・Sensor.TYPE_̲ALL
・
SensorManager
クラス
・ArrayListを使う
・表⽰示はSensor#getType()
GPS
GPSはセンサーではなく受信機
Google Play Services
•
位置情報の提供
•
Googleサービスへの認証
•
連絡先の同期
Google Play Servicesの導⼊入
Google Play Servicesの導⼊入
Google Play Servicesの導⼊入
Copy projects into workspaceに☑
Browseからgoogle-‐‑‒play-‐‑‒services_̲libを選択 $(ANDORID_SDK)/extras/google/google_play_services
位置情報精度度
GPS > WiFi > 基地局
位置情報取得の⽅方法
・1回だけ取得する
・連続的に取得する
1回だけ取得する場合
・Google Play Servicesに接続
・位置情報問い合わせ
・位置情報取得
・終了了時にGoogle Play Services
を切切断
連続的に取得する場合
・Google Play Servicesに接続
・位置情報更更新リスナーを設定
・更更新をコールバックで受け取る
・終了了時にリスナーを破棄
・終了了時にGoogle Play Services
を切切断
GPS情報フレームワーク
・LocationClient!
・Location!
LocationClient
を⽣生成して、Play Serviceへ接続!
位置情報はバックグラウンドで取得され、onConnectedの!
GPS情報フレームワーク
Google Play Services
LocationClient
3.Location
1.接続要求
バックグラウンドで位置を取得
2.接続OK
LocationClientの取得
private LocationClient mLocationClient;! …!
mLocationClient = new LocationClient(this, this, this); !
3
つの引数に”this”を設定している。後半2つはリスナーの設定なので、!
Activity
に“implements”を追加してコールバック関数が必要!
LocationClient(Context context,
GooglePlayServicesClient.ConnectionCallbacks connectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener connectionFailedListener)
public class MainAcIvity extends AcIvity implements
イベントコールバック
@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()で切切断する!
位置情報の取得
@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"/> <applicaIon android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <meta-‐data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" /> GPSを使うためのパーミッションの設定!パーミッションの追加
1. AndroidManifest.xmlの「Permissions」タブ 2. 「Add...」をクリック
パーミッションの追加
パーミッションの追加
パーミッションの追加
【演習】位置情報取得
ここまでの説明と、教科書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”
例例えば
緯度度経度度
緯度度 ⾚赤道からの⾓角度度 経度度 グリニッジからの⾓角度度 ⽇日本標準時⼦子午線⽇日本の経度度緯度度原点!
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
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())); }
@Override
protected void onPause() { super.onPause();
// LocaIonListenerを解除
mLocaIonClient.removeLocaIonUpdates(this); // Google Play Servicesとの切断
mLocaIonClient.disconnect(); }