AndroidアプリからFusion TablesのAPIを利用する方法.マイマップから移行しろということなので試してみました
AndroidからFusionTablesを使う例
Fusion Tables
についての説明は省略しますが,
マイマップのAPIが2011年1月31日で
廃止される にあたって
Google様はこのFusion Tablesとやらにデータを移行しろと言ってますので,試してみました.ちなみにFusion Tablesでの地図表示は,こんな感じです.
API廃止の話題については,フォーラムのこのスレが割と熱いです.APIは廃止されても,Googleマップからマイマップを使うのは大丈夫なようです.
Fusion TablesのAPIはHTTPですので,アクセスする方法は色々あると思いますが,今回は
Google API Client Library for Java を使いました.
実体は google-api-client-1.2.1-alpha.jar ですが,
これ自体は191KBしかありませんので,最終的なapkもそれほど大きくならずに済みました.
ソース
MainAct.java
package
com.kamoland.ftsample;
import
com.google.api.client.googleapis.GoogleTransport;
import
com.google.api.client.googleapis.auth.clientlogin.ClientLogin;
import
com.google.api.client.http.HttpRequest;
import
com.google.api.client.http.HttpTransport;
import
android.app.Activity;
import
android.os.Bundle;
import
android.util.Log;
import
java.io.IOException;
import
java.io.UnsupportedEncodingException;
import
java.net.URLEncoder;
import
java.util.StringTokenizer;
/**
* Fusion Tablesにアクセスするサンプル
*/
public
class
MainAct extends
Activity {
@Override
public
void
onCreate(Bundle icicle) {
super
.onCreate(icicle);
try
{
HttpTransport transport = GoogleTransport.create();
ClientLogin authenticator = new
ClientLogin();
authenticator.authTokenType = "fusiontables"
;
authenticator.username = "XXXXX"
; // Googleアカウント名
authenticator.password = "YYYYY"
; // パスワード
authenticator.authenticate().setAuthorizationHeader(transport);
HttpRequest request = transport.buildGetRequest();
String selectQuery = "SHOW TABLES"
;
//【2011/2/13 修正】
request.setUrl("http://www.google.com/fusiontables/api/query?sql="
+ URLEncoder.encode(selectQuery, "UTF-8"
));
String response = request.execute().parseAsString();
StringTokenizer st = new
StringTokenizer(response, "\n"
);
while
(st.hasMoreTokens()) {
String line = st.nextToken();
log(line);
}
} catch
(UnsupportedEncodingException ex) {
throw
new
RuntimeException(ex);
} catch
(IOException ex) {
throw
new
RuntimeException(ex);
}
}
private
static
void
log(String mes) {
Log.d("**sample MainAct"
, mes);
}
}
AndroidManifest.xml
<?xml version="1.0"
encoding="utf-8"
?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package
="com.kamoland.ftsample"
android:versionCode="100"
android:versionName="1.0"
>
<application android:icon="@drawable/icon"
android:label="@string/app_name"
>
<activity android:name=".MainAct"
android:label="@string/app_name"
>
<intent-filter>
<action android:name="android.intent.action.MAIN"
/>
<category android:name="android.intent.category.LAUNCHER"
/>
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET"
/>
<uses-sdk android:minSdkVersion="3"
/>
</manifest>
参照ライブラリー
- google-api-client-1.2.1-alpha.jar
- Android 1.6
解説
SHOW TABLES というコマンドを発行しています.
これは認証されたユーザが所有するテーブル一覧を取得するというものです.
DDMSのLogCatの関係で日本語が文字化けしてしまいますが,出力はこんな感じです.
テーブルIDとテーブル名が出力されています.
12-23 21:58:42.046: DEBUG/**sample MainAct(9075): table id,name
12-23 21:58:42.046: DEBUG/**sample MainAct(9075): 363535,a±±a??a?-a?¬a??a?Ra??a?¢i??Androida?¢a??
12-23 21:58:42.046: DEBUG/**sample MainAct(9075): 363347,Cycle konami (map id=0004908b607d9a4fb589c)
認証方式について
Androidアプリの場合,Googleアカウントを扱う時はIDとパスワードではなく
- OSが1.6以下の場合: GoogleLoginServiceHelper
- OSが2.1以上の場合: AccountManager
を使ってその端末に紐付いているアカウント情報を元にauthTokenを取得して,それをGoogleのサービスに渡して認証するのがスマートだと思います.
しかし今回のFusion Tablesサービスについては,うまくいきませんでした.
GoogleLoginServiceHelperを使った場合(OS 1.6)は,service="fusiontables" にするとauthToken取得時に発生するパーミッションエラー
caller pid 4829 uid 10081 lacks com.google.android.googleapps.permission.GOOGLE_AUTH.fusiontables
java.lang.SecurityException: caller pid 4829 uid 10081 lacks com.google.android.googleapps.permission.GOOGLE_AUTH.fusiontables
を回避できませんでしたし,
AccountManagerを使った場合(OS 2.2)は,パーミッションエラーは発生しなかったのですが,取得できたauthTokenがnullにしかなりませんでした.
このような状況のため,IDは一応これらの方法でも取得できるのですが,パスワードはユーザにアプリへ入力してもらう必要があるので,不便なところです.
【2011/2/8 追記】
...と思っていたのですが,MyTracksのソース SendToFusionTables.java によると,AuthManagerとgoogle-api-clientを組み合わせてちゃんと実装されているみたいです.最後のrunUpdate()メソッドです.
自分でもそのうち検証しようと思います.