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()メソッドです.

自分でもそのうち検証しようと思います.


© 2024 KMIソフトウェア