タグ「Android」が付けられているもの

  1. Windowメニュー > Preferences を選択
  2. (Preferences画面の)左側のAndroidを選択
  3. SDK LocationにSDKディレクトリを直接入力するか、Browse...をクリックしてディレクトリを選択
  4. Apply、OKをクリック

Android SDKディレクトリは、以下の(Windowsの例の)ようにSDKバージョン毎に分けて置いておくとよいでしょう。
C:\Android\android-sdk-windows-1.0_r1 ・・・ Android 1.0 SDK, Release 1
C:\Android\android-sdk-windows-1.0_r2 ・・・ Android 1.0 SDK, Release 2

[Android] Cursor.close()

Thread内でSQLのquery操作をして、戻り値のCursolを参照するようなコードを書いていた際、

タイミングによっては、

Daemon System Thread [<5> HeapWorker] (Suspended (exception IllegalStateException)) 
 SQLiteCursor.finalize() line: 448 
 NativeStart.run() line: not available [native method]

のようなIllegalStateExceptionが発生しており、少しハマってしまいました。。。

解決方法は、Threadが終了するよりも前、かつ、DataBaseを閉じる前に

Cursol.close()

を挿入するだけでした。

たしかに、考えてみれば当然の流れですね。

リソースからXMLファイルを読み込むには?

android.content.resパッケージ
Resourcesクラス(※1)の
getXml()メンバ関数(※2)を呼び出します。

戻り値は、XmlResourceParserであり、
このクラスは、XmlPullParserインタフェースを実装しているので、
XMLの解析ができます。

※1
Resourcesクラスのインスタンスは、
Activity内であれば、getResources()で取得できます。
※getResources()は、 android.contentパッケージのContextクラスのメンバ関数。

※2
getXml()メンバ関数の第1引数は、リソースIDですので、
プロジェクト内のxmlリソース(/res/xml/hoge.xml)の
リソースID(R.xml.hogeなど)を指定してください。

Tips

REST系のアプリケーションを開発している際に、
デバッグのたびに動的にHTTPでXMLファイルを取得しなければならない場合、
同XMLファイルを、予めブラウザなどでアクセスしてファイル保存し、
上記のように静的にリソースに組み込んで、
XmlPullParserインスタンスが必要な個所を、
getXml()で書き換えてあげれば、(デバッグ用に固定の)XMLファイルを取得できるため、
デバッグ時間を短縮できたり、非ネットワーク環境下でも開発できます。

[Java] For-Eachループ

For-Eachループ 

ArrayList<Integer> array = new ArrayList<Integer>();

のような配列の要素にアクセスする場合、

 

int length = array.size();
for (int i = 0; i < length; i++) {
    value = array.get(i);
}

の書き方で、配列の要素にアクセスすることができますが、

 

Java5(JDK1.5)で追加されたFor-Eachループでは、 

for (Integer value : array) {
}

と書くこともできます。

※Sunのドキュメントは、こちら(http://java.sun.com/j2se/1.5.0/ja/docs/ja/guide/language/foreach.html)

 

後者の方が、読みやすく、安全ということみたいですが、処理時間はかかるみたいです。

実際に、Androidでコードを書いて計測してみると、
後者の方が、2~3倍処理時間がかかりました。

使用する場面に応じて使い分けるなど、留意した方が良さそうです。

Android ニュースリンク集(2007年)

Android ニュースリンク集(2008年)

 

 

[Android ニュースリンク集(2007年)] | [Android ニュースリンク集(2008年)] | [Android ニュースリンク集]

[Android] JSON形式のデータにアクセス

flickrやtwitterなどのRESTの戻り値で、XMLだけでなく、JSONもサポートしている場合、

AndroidでもJSON形式のデータにアクセスできます。

具体的なサンプルソースコードは、以下のとおりです。 

JSONArray jsons = new JSONArray(json);
for (int i = 0; i < jsons.length(); i++) {
    JSONObject jsonObj = jsons.getJSONObject(i);
    id = jsonObj.getInt("id");
    text = jsonObj.getString("text");
    ...
}

まず、RESTで得られたInputStreamインスタンスを、
BufferedReaderやStringBuilderでString(上記ソースでは、json)に変換したら、

org.jsonパッケージのJSONArrayクラスに同文字列を渡してインスタンス化します。

すると、JSONObjectの配列が得られますので、順次アクセスして、目的の要素を取得できます。

org.apache.http.impl.clientパッケージのDefaultHttpClientクラスは、
HTTPクライアントを実装したクラスです。

インスタンス化するには、ThreadSafeClientConnManagerやHttpParamsのインスタンスを渡します。

具体的なサンプルコードは、以下のとおりです。

final HttpClient httpClient = new DefaultHttpClient(
    new ThreadSafeClientConnManager(httpParams, schemeRegistryRegistry),
    httpParams);

 インスタンス作成後、HTTPリクエスト(GETやPUTなど)を発行するには、DefaultHttpClient.execute()を呼び出します。

具体的なサンプルコード(Twitterのpublic_timeline取得)は、以下のとおりです(一部、例外処理を省略して抜粋しています)。

final Uri.Builder uriBuilder = new Uri.Builder();
uriBuilder.path("/statuses/public_timeline.xml");
HttpEntity httpEntity = null;
final HttpResponse httpResponse = httpClient.execute(
    new HttpHost("twitter.com", 80),
    new HttpGet(uriBuilder.build().toString()));
if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
    httpEntity = httpResponse.getEntity();
    final InputStream in = httpEntity.getContent();
    final XmlPullParser parser = Xml.newPullParser();
    try {
        parser.setInput(new InputStreamReader(in));
        // ・・・XMLを解析する処理・・・
    } catch (XmlPullParserException e) {
    }
}

順を追って説明すると、

DefaultHttpClient.execute()の第1引数には、
org.apache.httpパッケージのHttpHostインスタンスを渡す必要があるため、

new HttpHost(ホスト名、ポート名);

でインスタンス化しています。
ここでのホスト名とは、たとえば、Twitterのタイムラインパスである

http://twitter.com/statuses/public_timeline.xml

の場合、twitter.comの部分です。

また、DefaultHttpClient.execute()の第2引数には、
org.apache.http.client.methodsパッケージのHttpGetインスタンスを渡します。

※同パッケージには、他にもHttpPut、HttpPost、HttpDeleteがあります

HttpGetに渡す引数は、uri文字列ですが、
これは、Uri.Builderクラスから作成できます。

ここでのuriとは、先の例で言うと、/statuses/public_timeline.xmlの部分を指します。

※さらに?key1=value1&key2=value2などを渡すには、appendしていけばよいです

リクエストの戻り値は、org.apache.httpパッケージのHttpResponseクラスであり、HttpResponse.getEntity()を呼び出し、

同(org.apache.http)パッケージのHttpEntityを得た後、
HttpEntity.getContent()を呼び出すと、InputStreamインスタンスが得られます。

あとは、XMLをパースするなどしていけばよいです。

org.apache.http.conn.scheme.SchemeパッケージのSchemeRegistryクラスは、
"http"や"https"のようなプロトコルスキームを登録するクラスです。

※このクラスは、DefaultHttpClientクラスを使用する際に必要になります

インスタンス作成後、スキームを登録するには、SchemeRegistry.register()を呼び出します。

具体的なサンプルコードは、以下のとおりです。

final SchemeRegistry schemeRegistryRegistry = new SchemeRegistry();
schemeRegistryRegistry.register(
    new Scheme(HttpHost.DEFAULT_SCHEME_NAME, // "http"
        PlainSocketFactory.getSocketFactory(),
        80));    // ポート番号

 ちなみに、SchemeRegistry.register()の引数には、
同(org.apache.http.conn.scheme.Scheme)パッケージのSchemeインスタンスを渡す必要があるのですが、
上記のような引数を渡せば、インスタンス化できます。

※PlainSocketFactoryも、同(org.apache.http.conn.scheme.Scheme)パッケージのクラスです

org.apache.http.paramsパッケージのBasicHttpParamsクラスは、
HTTPバージョンやキャラクタセットなどのHTTPプロトコルパラメータを保持するクラスです。

※このクラスは、SingleClientConnManager/ThreadSafeClientConnManagerや、DefaultHttpClientクラスを使用する際に必要になります

インスタンス作成後、パラメータを設定するには、
同(org.apache.http.params)パッケージのHttpProtocolParamsクラスを使用します。

具体的なサンプルコードは、以下のとおりです。

final HttpParams httpParams = new BasicHttpParams();
HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);    // HTTP 1.1
HttpProtocolParams.setContentCharset(httpParams, HTTP.UTF_8);        // UTF-8

ちなみに、
HTTPバージョンは、org.apache.httpパッケージのHttpVersionクラスの定数である
HTTP_0_9、HTTP_1_0、HTTP_1_1(通常はコレ)を利用できます。

また、
キャラクタセットには、org.apache.http.protocolパッケージのHTTPクラスの定数である
DEFAULT_CONTENT_CHARSET("ISO-8859-1")や、UTF_8("UTF-8")
などを利用できます。

※RESTサービスの多く(Flickr、Picasa、YouTube、Twitter)は、UTF-8です

お勧めのAndroidサンプルアプリケーションは、apps-for-androidです。

入手先は、こちら(http://code.google.com/p/apps-for-android/)。
※Project ownersは、Google先生です。

apps-for-androidには、いくつかのプロジェクトが含まれているのですが、
この中でも超お勧めが、Photostreamという、Android版Flickrクライアントです。

Androidで、Flickr、Picasa、TwitterとかRESTクライアントを作ろうとう方々には、大変よい入門書(ソースコード)になると思います。

ちなみにソースコードは、リンク先のSourceタブのsvnパスを、SVNクライアントでダウンロードできます。
※Windowsの場合、TortoiseSVNがお勧め) 

[Android] ActivityNotFoundException

startActivity()でアクティビティを開始したが、

Suspended exception ActivityNotFoundException

と表示される場合、

AndroidManifest.xmlのApplication Nodesに、

目的のActivityが追加されていない可能性があります。 

対処するには、

  1. Eclipseの[PackageExplorer]から、[AndroidManifest.xml]をダブルクリック
  2. [AndroidManifest.xml]の編集画面下の[Application]タブをクリック
  3. [Add]ボタンをクリック
  4. [Create a new element at the top level, in Application.]で、[Activity]など追加したい要素が選択された状態で、[OK]ボタンをクリック
  5. (画面右下1/4の領域に表示される)Name*の右にある[Browse]ボタンをクリック
  6. [Select class name for element Application]下のリストから目的のクラスをクリック

AndroidManifest.xmlファイルを直接編集する場合、

<application></application>の間に

<activity android:name="クラス名"></activity>

を挿入すればOKです。

[Android] SimpleDateFormat

日時文字列からDateクラスのインスタンスを得るには、DateUtils.parseDate()を使用する方法以外にも、SimpleDateFormat.parse()を使用しても同様のことができます(こちらの方がお勧めかも)。

また、Dateクラスのインスタンスから任意の日時文字列に変換するには、SimpleDateFormat.format()を使用します。

下記に相互変換したサンプルコードを記載しておきます。

String inDate = "Sat, 10 Jan 2009 00:00:00 +0900";
String outDate = null;
SimpleDateFormat inFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
SimpleDateFormat outFormat = new SimpleDateFormat("yyyy/MM/dd");
Date date = null;
try {
    date = inFormat.parse(inDate);
} catch (ParseException e) {
}
outDate = outFormat.format(date); // 結果は、"2009/01/10"

[Android] Java言語の配列の書き方

Java言語の配列の書き方は、以下のとおり。

int[] a = {0, 1, 2};
int[] b = new int[] {0, 1, 2};
int[] c = new int[3];
c[0] = 0;
c[1] = 1;
c[2] = 2;

※色々な言語を行き来していると忘れてしまいます。。。現在、C++、AS3、Javaを並行して作業しているので・・・という言い訳。。。

[Android] DateUtils.parseDate

日時文字列からDateクラスのインスタンスを得るには、DateUtils.parseDate()を使用します。

ソースコードサンプルは、以下のとおりです。

String dateString = "Sat, 10 Jan 2009 00:00:00 +0900";
String pattern[] = {DateUtils.PATTERN_RFC1123};
Date date = null;
try {
    date = DateUtils.parseDate(dateString, pattern);
} catch (DateParseException e) {
}

DateUtilsには、下記の文字列定数がありますので、 変換元のフォーマットが一致する場合には、定数を指定するだけで利用できますが、そうでない場合にも、HHやmmなどで、独自のフォーマット文字列を書けば利用できます。

  • PATTERN_ASCTIME = "EEE MMM d HH:mm:ss yyyy"
  • PATTERN_RFC1036 = "EEEE, dd-MMM-yy HH:mm:ss zzz"
  • PATTERN_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz"

※EEEは、曜日。zzzは、タイムゾーン。

Androidでサポートしている画像フォーマットは、以下のとおり。

  • Bitmap(BMP)
  • JPEG(JPG)
  • PNG
  • GIF

静的にリソースに組み込む場合には、res/drawableに画像を配置して、ImageView.srcにセットすれば表示できる。

※Googleさんの公式ドキュメントは、こちら。
 ここでは、PNGが推奨(preferred)で、それ以外は、非推奨(discouraged)と記載されている。

また、URL(http://~)から動的に読み込む場合には、(BufferedInputStream,ByteArrayOutputStream,BufferedOutputStreamなどで)読み込んだbyte配列をBitmapFactory.decodeByteArray()にセットすることでBitmapが得られるので、ImageView.setImageBitmap()にセットすれば表示できる。

※Googleさんの公式ドキュメントでいうと、android.graphicsパッケージ内のBitmap、BitmapFactoryのあたり。

ちなみに駄目元でTIFF(TIF)を試してみたら、やっぱり駄目でした。

Androidエミュレータのプロキシ設定について、
Googleさんの公式ドキュメントは、
こちら(http://code.google.com/intl/ja/android/reference/emulator.html#proxy)にあります。

下記のような症状でお困りの方が対象です。

  • ブラウザを起動しても応答がない
  • 「Web page not available」と表示される
  • 「! The page at 'http://... ERROR [object Object」]と表示される

設定方法の要点だけ言えば、
エミュレータ(emulator)起動時に、以下のような引数を追加して起動すれば良いということです。
(以前(m3-rc22a)は、asb shellからsqliteでsettings.dbを書き換えてた方法の別のやり方です。)

  • プロキシ認証が不要な場合
emulator -http-proxy http://<machineName>:<port>
  • プロキシ認証が必要な場合
emulator -http-proxy http://<username>:<password>@<machineName>:<port>

※<machineName><port>などのカッコ<>は不要です
※上手くいかない場合、machiNameのホスト名(ドメイン名)をIPアドレスを直うちしてみてください
※Android 1.0 SDK, Release 1をお使いの方は、Android 1.0 SDK, Release 2に移行してみてください(当方は何故か、これで解決しました。Release 1のエミュレータヘルプで、-http-proxy(ハイフン)でなく-http_proxy(アンダースコア)と表示されるのと関係あるのかな?)

上手くいけば、デフォルトでインストールされているBrowser(ブラウザ)アプリでWebにアクセスできます。

エミュレータを手動で起動している方は、Windowsとかだと、ショートカットを作成し、リンク先へ引数を追加してあげれば次回以降、ショートカットを呼び出すだけです。

Eclipseをお使いの方は、前述の方法で、先にエミュレータを起動しておく。。。でも可能ですが、Eclipseで設定しておく方法をお勧めします。

Eclipseで設定する方法は、
EclipseのWindowメニューからPreferencesを選択し、
Android > Launch の Default emulator options に
上記引数(-http-proxy~)を追加し、Apply > OKを押してください。

ただし、設定が有効になるのは、これ以降に作成したプロジェクトであるため、
既存のプロジェクトに反映させるには、
EclipseのRunメニューからRun/Debug Configurationsを選択し、
左側のペインで目的のプロジェクトが選択されている状態で、
Targetタブを選択し、
Additional Emulator Command Line Optionsに上記引数(-http-proxy~)を追加してください。
(ここで設定する場合、プロキシ認証が必要な場合でも、認証をつけると上手くいかず、認証の記述を外すと上手くいく場合がありますので、上手くいかない場合には、諦めずにトライしてみてください。)

Android ニュースリンク集

Androidのエミュレータは、トラックボールモードをサポートしています。
操作方法は、以下のとおり。

Android 1.0 SDK, Release 1では、CTRL+Tキーを押している間だけ有効。
Android 1.0 SDK, Release 2では、DELキーをしている間だけ有効、F6キーでモードの有効/無効切り替え。

[Android] cupcake 開発ブランチ

Android Open Source ProjectのWebページに「"cupcake" development brach」という記事が公開されたようです。

以下、変更点の抜粋(直訳)です。

  • アプリケーション(Applications)
    • マルチメディアメッセージングサービス(MMS)・・・添付ファイル保存、不具合修正
    • 電子メール(Email)・・・不具合修正
    • アラーム時計(Alarm Clock)・・・不具合修正
    • パッケージインストーラ(Package Installer)・・・不具合修正
    • 設定(Settings)・・・メニューオプション(動作プロセスリスト)追加
    • 音楽(Music)・・・電話から復帰後の再生フェード、サードパーティ用のメディア検索
    • ブラウザ(Browser)・・・WebKitの更新、SquirrelFish(JS)サポート、コピペサポート、テキスト検索
    • 音声ダイヤル(VoiceDialer)・・・'open app'コマンドサポート
    • カメラ/ギャラリー(Camera/Gallery)・・・ビデオ録画、共有、サムネイル、ローカルファイル再生
  • ダウンロードマネージャー(Download manager)・・・HTTP301,302,303,307,503コードサポート、ダウンロードレジューム、一時停止、リトライ
  • フレームワーク(Framework)・・・新機能(略)、不具合修正
  • Bluetooth・・・A2DP & AVRCPプロファイルサポート
  • システムソフトウェア(System software)・・・Linux2.6.27カーネル、wakelock API改善、Work to transition to the USB Gadget Framework underway、x86サポート
  • ラジオ&電話通信(Radio & Telephony)・・・SIMアプリケーションツールキット1.0、その他新機能、不具合修正
  • 開発ツール(Development tools)・・・アドオンによるAndroid SDKを拡張するサードパーティ用のハンドセット
  • ビルドシステム(Build System)・・・新機能(略)

 

2