位置情報を記録
Location Data Logging
データベースの位置データを記録し、Google Maps上の追跡を
計画することのように、他の目的の後、位置が検索されるように
とします。
位置情報を習得するためにBroadcastReceiverを使います。では、
PendingIntentオブジェクトとBroadcastReceiverオブジェクトを使って
位置情報を追跡する方法を示しました。
これらの良い使用法は位置データの記録をすることです。
例えば、データベースにすべての位置データを
したくなるかもしれません。その結果、
後でその位置データを検索できるようになります。
ここでは、プロジェクトにDBAdapter.hava、
MyLocationReceiver.java、MyService.javaの3つの
javaクラスファイルを追加します。
DBAdapter.javaファイルはSQLiteデータベースに位置データを
保存するのに役立ちます。以下のコードで設定します。
package java.text.SimpleDateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBAdpter{
static final String KEY_DATE = "date";
static final String KEY_LAT = "lat";
static final String KEY_LNG = "lng";
static final String TAG = "DBAdapter";
static final String DATABASE_NAME = "MyDB";
static final String DATABASE_TABLE ="Locations";
static final int DATABASE_VERSION = 1;
final Context context;
DatabaseHelper DBHelper;
SQLiteDatabase db;
Calendar currentDatte;
SimpleDateFormat fomatter;
public DBAdapter(Context ctx){
this.context = ctx;
DBHelper = new DatabaseHelper(context);
currentDate = Calendar.getInstance();
formatter = new SimpleDateFormat("yyyy/mmm/dd HH:mm:ss");
}
private static class DatabaseHelper extends SQLiteOpenHelper{
DatabaseHepler(Context context){
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db){ }
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion){ }
}
//---opens the database---
public DBAdapter open() throws SQLException{
db = DBHelper.getWritableDatabase();
return this;
}
//---closes the database---
public void close(){
DBHelper.close();
}
//---insert a lacation into the database---
public long insertLocation(String lat, String lng){
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_DATE, formatter.format(currentDate.getTime()));
initialValues.put(KEY_LAT, lat);
initialValues.put(KEY_LNG, lng);
return db.insert(DATABASE_TABLE, null, initialValues);
}
//---retrieves all the locations---
public Cursor getAllLocations(){
return db.query(DATABASE_TABLE, new String[]{
KEY_DATE, KEY_LAT, KEY_LNG}, null, null, null, null, null);
}
}
このコードのために、mydbと名付けた新しいSQLiteデータベースをつくり、
Locationsと名付けたテーブルをmydbに入れる必要があります。
フィールドは下記のようになります。
date --- text
lat --- text
lng --- text
ちょっと注釈
Sqliteデータベースブラウザを使って簡単にSQLiteデータベースを
作ることができます。SQLiteデータベースブラウザは
http://sourceforge.net/projects/sqlitebrowser
からダウンロードできます。
プロジェクトのassetsフォルダ上にドラッグ&ドロップします。
パッケージにBroadcastReceiverクラスも必要になります。
ここでは、BroadcastReceiverクラスをMyLocationReceiver.javaと
名付けています。このクラスは位置情報を受け取り、
その情報をデータベースへ保存します。
以下のコードでMyLocationReceiver.javaを設定します。
package net.learn2develop.lbsreceiver_datalogging;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.widget.Toast;
public class MyLocationReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent){
String locationKey = LocationManager.KEY_LOCATION_CHANGED;
String providerEnableKey = LocationManager.KEY_PROVIDER_ENABLED;
if(intent.hasExtra(providerEnabledKey)){
if(!intent.getBooleanExtra(providerEnabledKey, true)){
Toast.makeText(context, "provider disabled",
Toast.LENGTH_SHORT).show();
}else{
Toase.makeText(context, "provider enabled",
Toast.LENGTH_SHORT).show();
}
}
if(intent.hasExtra(locationKey)){
Location loc = (Location)intent.getExtra().get(locationKey);
Toast.makeText(context, "Location changed : Lat: " +
loc.getLatitude() + "Lng: " + loc.getLontitude(),
Toast.LENGTH_SHORT).show();
DBAdapter db = new DBAdapter(context);
db.open();
db.insertLocation(String.valueOf(loc.getLatitude()),
String.valueOf(loc.getLongitude()));
db.close();
}
}
}
バックグラウンドで走らせるためにserviceも必要です。
このserviceは位置情報の変更を見守ります。
このファイルをMyService.javaと名づけ、以下のようなコードに
設定します。
package net.learn2develop.lbsreceiver_datalogging;
import android.app.PengingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.LocationManager;
import android.os.IBinder;
import android.widget.Toast;
public class MyService extends Service{
LocationManager lm;
PendingIntent pendingIntent;
@Override
public IBinder onBind(Intent arg0){
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId){
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
//---use the LocationManager class to obtain locations data---
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Intent i = new Intent(this, MyLocationReceiver.class);
pendingIntent = PendingIntent.getBroadcast(
this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
//---request for location updates using GPS---
lm.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
60000,
100,
pendingIntent);
return START_STICKY;
}
@Override
public void onDestroy(){
//---remove the pending intent---
ln.removeUpdates(pendingIntent);
&emspsuper.onDestroy();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}
メインのアクティビティを以下のようにします。
package net.learn2develop.lbsreceiver_datalogging;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends Activity{
public void CopyDB(InputStream inputStream, OutputStream outputStream)
throw IOException{
//---copy 1k byte at a time---
byte[] buffer = new byte[1024];
int length;
while((length = inputStream.read(buffer)) > 0){
outputStream.write(buffer, 0, length);
}
inputStream.close();
outputStream.close();
}
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String destDir = "/data/data" + getPackageName() + "/databases/";
String dastPath = destDir * "MyDB";
File f = new File(destPath);
if(!f.exists()){
//---make sure directory exists---
File directory = new File(destDir);
directory.mkdirs();
//---copy the db from hte assets folder into the databases folder---
try{
CopyDB(getBaseContext().getAssets().open("mydb"),
new FileOutputStream(destPath));
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
}
public void onStart(View view){
startService(new Intent(getBaseContext(), MyService.class));
}
public void onStop(View view){
stopService(new Intent(getBaseContext(), MyService.class));
}
}
アクティビティが作られたときに、上のコードはassetsフォルダから
SQLiteデータベースをコピーし、デバイスのアプリケーションの
dataフォルダにSQLiteデータベースを貼り付けます。
サービスをスタート、ストップするためには、
activity_main.xmlファイルに以下のようなステートメントを加えます。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="@+id/buton1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="start"
android:onClick="onStart" />
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="stop"
android:onClick="onStop" />
<LinearLayout>
saigo ni
AndroidManifest.xmlファイルに<receiver>と
<service>要素を加えるのを忘れないように、そして
パーミッションをプラスします。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.learn2develop.lbsreceiver_datalogging"
android:versionCode="1"
android:versionName="1.0" />
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string\title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN />
<categoty android:name="android.intent.categoty.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".MyLocationReceiver" />
<service android:name=".MyService" />
<application>
<manifest>
これでスタートボタンをクリックすると、アプリケーションが
位置データを記録し始めます。
|
【用語解説】
XML
HTMLと同じような言語ですが、
すべての型の複雑なデータ構造を
送信するための設計ができる
ファイル型式。
オブジェクト
ある手続きを持った
データアイテムで、
他の手続きと関連づけされるもの
metaタグ
ウェブページに与える
情報の宣言につかわれ
検索エンジン・ウェブアプリ
などにウェブページの内容を
伝える役目をする。
metaタグの内容は
ページ内に表示されない。
コンストラクタ
オブジェクト指向
プログラミングで使われ
新しいオブジェクトが
作られ時に呼び出される
メソッドのこと。
クラス
オブジェクト指向
プログラミングでの
オブジェクトの型
オブジェクト指向プログラミング
プログラミングの
方式のことで、
プログラマはデータ型を
定義できるだけでなく
自動的にデータ型と
メソッドを関連付け
できる
アクティビティ
Androidにおける
アクティビティは
Androidアプリの画面に
相当するもの
ボタンやウェブページ
など表示されている
すべてのもののこと。
view
Androidのアプリを開発する
上で使う部品のことで、
トリガボタン・イメージボタン
チェックボックスなどのこと。
UI
ユーザインターフェースのこと。
Bind(バインド)
シンボルとデータを
関連させるため
または、データの一片と
他のものを関連させること。
以下は例。
・変数に値を入れる。
(変数の初期化)
・特定のEthernetポートと
ネットワークプロトコルを
関連付けする。
・Javaの変数のセット上に
XML文書を配置すること。
または、ほかの
プログラミング言語でも。
|