2013年11月22日

[Android] AlertDialogのgetButton()がnullを返す

DialogのOKボタン(Positiveボタン)の長押しを判定したくて、以下のようなコードを書きました。
Builder builder = new Builder(getActivity());
builder.setTitle("title").setMessage("message");
builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dismiss();
}
});

AlertDialog dialog = builder.create();
Button positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
positiveButton.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
return false;
}
});


これを実行すると、NullPointerExceptionが発生してアプリが異常終了しました。
11行目のdialog.getButton()でnullが返却されているためです。
Webを検索してみると以下の情報が見つかりました。

Issue 6360 - android - AlertDialog getButton() return null - Android Open Source Project - Issue Tracker - Google Project Hosting

どうもDialogを表示してからでないとnullになってしまうようです。
ソースコードを読んでみるとDialogのonCreate()を通らないと中のViewが生成されないようですね(たぶん)。
Dialogが表示されたところでOnLongClickListenerをセットすることにしました。


Builder builder = new Builder(getActivity());
// ... 省略 ...

AlertDialog dialog = builder.create();
dialog.setOnShowListener(new OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
Button positiveButton = ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE);
positiveButton.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
return false;
}
});
}
});


多少めんどくさいですが、これなら大丈夫でした。
posted by t2low at 21:00| Android

2013年11月20日

[Android] Toast


アプリの動作をちょっと確認したいときにToastを使うと便利です。
開発中によく↓こんな形のコードを組み込みます。

Toast.makeText(context, "hoge", Toast.LENGTH_SHORT).show();


ただ、Toastはキューイングされているようで、いくつも上記コードを入れてしまうと呼び出した回数分表示されてしまい、なかなか消えてくれなくなります。
そんなときはキャンセルしましょう。

if (toast != null) {
toast.cancel();
}
toast = Toast.makeText(context, "hoge", Toast.LENGTH_SHORT);
toast.show();


ただ、cancel()しても、パッと消えません。
また、キューイングされている未表示のToastをcancel()したとしても、少し時間を消費します。
元々連続して表示するようには作られていないので、大量の情報を表示したければLogクラスや他のクラスを使った方が良いですね。

Toastの使い方はこちら
Toasts | Android Developers

ToastのAPIリファレンスはこちら
Toast | Android Developers


(最近アウトプットが大事だと考えて、とりあえず何か書こうと思ったけど、書くこと思いつかなくてこんな記事を書いた次第)
タグ:android
posted by t2low at 21:00| Android

2013年11月15日

[Android] Fragment内のWebViewで先読みするにはどうすれば良いだろう?

仕事でAndroidアプリ開発をしています。
先日こんなリクエストがありました。

「広告が表示されるまでに時間がかかってるので先読みできませんか?」

DialogFragmentにWebViewを載せて、onCreateView()内でURLを読み込むようにしていましたが、その時点で読み込み始めたのでは遅すぎるようです。


・DialogFragmentのコンストラクタでWebViewを生成して読み込ませるのはどうか
→WebViewが生成できません…。

WebViewを生成するにはContextが必要ですが、contextがありません…。
getActivity()はこの時点ではnullを返します。
遅くともonAttach()まで呼ばれればgetActivity()がactivityを返してくれるようになりますが、onAttach()が呼ばれるのはいつかと考えると、DialogFragment#show()を呼んだ後ですので、先読みになりません。


・DialogFragmentを呼び出すクラスがWebViewを作ってはどうか
→WebViewが渡せません…。

Fragmentの使い方としては引数なしのコンストラクタが必要です。
Fragment利用時に値が必要であれば、setArguments()で渡す必要があります。
setArguments()の引数はBundleで、BundleにはViewは詰められません。
Viewを渡すメソッドを作れば渡せないこともないと思いますが、それはちょっとねぇ。


結局、解決策がわかりませんでした。
DialogFragmentを使うのをやめ、Dialog風に見せかけたレイアウトを作ってお茶をにごしました。
タグ:android
posted by t2low at 22:00| Android

2013年02月01日

[Android] バックグラウンドで動作しているアプリ

Twitterで流れてきたのですが、以下のコマンドでバックグラウンドで動作しているアプリがわかるそうです。

adb shell dumpsys alarm

実行してみると、いろんなアプリが動作していることがわかります。
こういった情報はどこから仕入れてくるんでしょう…。
dumpsysに指定できるのは、dumpsysを無印で実行したとき先頭に表示される一覧のどれかということなんですかね?
タグ:android ADB
posted by t2low at 02:06| Android

2013年01月25日

[Android] DexFileというクラス

DexFileというクラスを見つけました。
http://developer.android.com/reference/dalvik/system/DexFile.html

おもしろそうです。サンプルコードを書いてみました。
apkを読み込んで、そのapkの中にあるクラスファイルを一覧するだけの簡単なものです。
起動するとファイルの一覧が表示されます。「/system/app」のファイルです。
apkがたくさんあって、読み取り権限があるところということで「/system/app」を指定しています。
ファイルをクリックすると、そのapkが使用しているクラスの一覧を表示します。

ソース - DexFileSample.zip
https://www.box.com/s/8odcwuzwlrqzfl9pr4q0

Apk - DexFileSample.apk
https://www.box.com/s/5tbw6opngxmzb6u4vgsa

難読化しているアプリもあれば、そのままのアプリもありますね。
パッケージの分割方法や、命名規則みたいなものが読み取れて面白いかもしれません。

しかし、このクラスは一体どういった用途で使うんでしょうか?
一般的なアプリに組み込んで使う方法が思い浮かびません。
タグ:android
posted by t2low at 02:07| Android

2013年01月12日

[Android] ToneGeneratorで鳴らせる音

Androidでbeep音を鳴らすときはToneGeneratorを使うようですね。

http://developer.android.com/reference/android/media/ToneGenerator.html

どんな音があるのか気になったので確認するためのサンプルを作ってみました。
tonegenerator_sample.png
↓プロジェクトはこちらです。
https://www.box.com/s/gei8ob2qo6jszuxvlwmg

ToneGeneratorでTONE_から始まる定義をリストアップして、タップでその音を鳴らすようにしています。beep音を確認したい方は是非どうぞ。
タグ:android
posted by t2low at 02:12| Android

2012年11月16日

[android] ネットワークの判別

Android端末がどのネットワークに接続しているか判別する方法を調べました。

ConnectivityManagerのgetActiveNetworkInfo()を使えば良いようです。
ネットワークに繋がっていないときはnullが返りました。

返却されたNetworkInfoのgetType()で接続ネットワークが分かります。
種類はConnectivityManagerにTYPE_XXXとして定義されています。

ISW12HTで試したときは以下のようになりました。

・3G → TYPE_MOBILE
・Wi-Fi → TYPE_WIFI
・WiMAX → TYPE_WIMAX
・機内モード → (null)

ただ、LTEの端末で試してもTypeは変わらず。

・LTE → TYPE_MOBILE

判別には使えないのかとも思いましたが、NetworkInfoにはgetSubtype()というメソッドもありました。
LTE端末で返却される値は13。
合っているかどうかはわかりませんが、おそらくこの値は TelephonyManager#NETWORK_TYPE_LTE だと思います。

サンプル・コードはこちら↓
https://www.box.com/s/bil4ig0a284vhl5dw1oy
タグ:android
posted by t2low at 01:00| Android

2012年08月02日

[Android] トークン取得を同期で

AccountManagerを使ってトークンを取得したいのですが、既存の実装を考えると同期で取得できると組み込みやすい状況でした。
ただし、そのトークンを取得するためにはgetAuthToken()でoptionとしてBundleを渡す必要があったため、blockingGetAuthToken()は利用できません。
ネットを検索してみると、getAuthToken()のコールバックをnullにすると同期でトークン取得ができるらしいという情報があったので試してみました。

コードは↓こちら。
http://dl.dropbox.com/u/50770203/dev/android_samples/BlockingGetAuthTokenSample.zip
このコードはgoogleカレンダーのトークンを取得するためのコードで、Bundleは必要としてませんが、実際に同期で取得できることは確認できました。
posted by t2low at 02:39| Android

2012年07月19日

[Android] ADT r20でAndroidプロジェクトが作れない

おひさしぶりです。

EclipseのJunoが出てたのでインストールしてみました。
ADTもr20をインストールしました。
そしたらAndroidのプロジェクトを新しく作れなくなりました。

同じような症状の人がいないか検索してみました。
やっぱり同じ症状の人がいました。
やることは3つ。

(1) SDK Managerでインストールされているサポートライブラリをアンインストールする
(2) SDK Managerでサポートライブラリを再インストールする
(3) eclipseを再起動する

これで僕のPCでは新しくAndroidプロジェクトを作れるようになりました。

タグ:android Eclipse adt
posted by t2low at 09:27| Android

2012年02月07日

[Android] ACTION_SENDとString

ちょっとしたアプリを作っていて、少しはまったときのメモです。

IntentでACTION_SENDを投げるアプリを作っています。
データとして、EXTRA_SUBJECTとEXTRA_TEXTを持たせています。
自アプリで投げたこのIntentを自アプリで受けると正常に表示できるのですが、
投げるアプリによってはただしく文字が表示されないことがありました。

原因はEXTRA_SUBJECTとEXTRA_TEXTに詰めていたデータの型が問題でした。
どうやら多くのアプリはStringでないと受け付けてくれないようです。
twiccaもそうでしたし、au の EZメールクライアントもそうでした。
IntentにはCharSequenceとしても値を設定できますが、
他のアプリとの連携を考えるとStringを使用するのが無難そうです。
posted by t2low at 02:00| Android

2012年02月04日

[Android] Google Ads for Mobile を始めたときのメモ

サイトに行く。
http://code.google.com/intl/ja/mobile/afma_ads/
英語。よくわからん。

サインアップすれば良さそう。
Sign upってところをクリックする。
このページに飛んだ。
http://www.google.com/ads/mobile/publishers/

アプリ用かWeb用かと聞かれているっぽい。
App developersをクリック。
次のページで[Get started with AdMob]をクリック。

admobのアカウントを作るページに移動した。
Googleアカウントが必要みたい。
--------------------------------
Your current email address → 自分のgmailを入力
Choose a password → admob用のパスワードを設定
Re-enter password → 入力したパスワードをもう一回入力

Location → 日本
BIrthday → 自分の誕生日。「月/日/年」の形式
Word Verification → 下の歪んだ文字を入力
Term of Service → 下のテキストエリアの文章を読む
同意したら「I accept. Create my account.」をクリック
--------------------------------

…。
もうアカウントあるって怒られた…。
サインインしたらいけた…。
確かに以前作ったような…。

気を取り直して、admob登録作業を再開。
サインイン後のページで「+サイト/アプリケーションの追加」をクリック。
…先に支払い情報を登録しろと怒られた…。
--------------------------------
納税情報
国 → 日本
アカウントの種類 → 個人
商号 → 自分の氏名
納税者ID → 空欄のまま

支払い情報
PayPalで支払うにチェック
PayPalのログイン名 → ログインに使うメールアドレス
「送信」をクリック
--------------------------------

ようやくサイト/アプリケーションの追加のページに。
Androidアプリケーションをクリック。
(まだアプリできてないけど…)
--------------------------------
App名 → アプリ名
Android パッケージ URL → アプリのパッケージ名
ジャンル → アプリの属するジャンル
Appの説明 → アプリの説明
CAPTCHA → 2つの読みにくい単語を入力
「次へ」をクリック
--------------------------------

ここでSDKをダウンロードするよう促された。
「AdMob Android SDK のダウンロード」をクリック。
アプリにSDKを組み込むことにする。

たぶん組み込むのはここを読めばできる。英語…。
http://code.google.com/intl/ja/mobile/ads/docs/android/fundamentals.html

1.SDK JARをプロジェクトに追加する。
2.AndroidManifest.xmlにcom.google.ads.AdActivityを定義する。
3.admobが必要とするネットワーク系のパーミッションを追加する。

とりあえず、ここまででビルドエラーが出ないことを確認。おけ。
次にいこうと思ったけど、なんか直接AdViewを作るやり方っぽいので、XMLでのサンプルが載ったページへ。
http://code.google.com/intl/ja/mobile/ads/docs/android/banner_xml.html
こっち。

レイアウトのルート要素に以下を追加。
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
続いて、xmlのcom.google.ads.AdViewの部分を自分のプロジェクトにコピペ。

以下を書き換える
--------------------------------
MY_AD_UNIT_ID → 自分のAdMob パブリッシャー ID(admobのサイトに書いてあるとこがある)
TEST_DEVICE_ID → テストしたい端末のDeviceId(IMEI?)、ちょっとよくわからん。
--------------------------------

とりあえず、エミュレータで実行してみる。
広告出なーい。なんかだめ?
と思ったら、出ることも…。
単純に表示する広告がないだけ?よーわからん。
でも、実装はこれで良さそう。簡単。
タグ:android AdMob
posted by t2low at 23:41| Android

2012年01月20日

[Android] ACTION_DATE_CHANGED について

ACTION_DATE_CHANGED は、日付が変わったときにブロードキャストされるIntentです。
Manifestにブロードキャストレシーバーを書き、<intent-filter>のactionとして"android.intent.action.DATE_CHANGED"を設定すれば受信出来ます。

これを受信するアプリの動作確認をするとき、どうするでしょうか。
おそらく端末の時間をいじって、23:59に設定する人が多いと思います(勘です)。
1分待てば受信できますからね。
ただ、このIntent、何故か端末の時間をいじると送信されないことがあるようです。
何故そうなるのかよくわかりません。

そのとき作っていたアプリもいくら日付をいじっても全然受信しませんでした。
もしや?と思い、"昼の11:59"に設定してみました。
1分待ってみると、Intentを受信しました。昼の12:00です。ACTION_DATE_CHANGEDでした。
どういことでしょうか。時間をいじり過ぎておかしくなってしまったのでしょうか。
僕がこの動作を確認したのはhtc Desire(海外モデル)とIS01です。他の端末でも起こるかもしれません。
頻繁に時間をいじっていたので、00:00に発行されるはずのIntentが遅れてたまたま12:00ちょうどに発行されたのでしょうか?
よくわかりません。
でも、今はちゃんと00:00に受信しています(少なくともDesireは)。
よくわかりません。

「わからない」ばかり書いたので、最後に少しは役に立つ(と思う)ことを。
このIntentは基本的に1日1回来るので、いろいろと便利に使えると思います。
ただ、これを契機に通信をするのは避けた方が良いです。
僕はそのときの想像が出来ていなかったので、ひどいことになりました。
アプリを使っている人たちが一斉にアクセスしてくるのです。恐ろしいですね…。
通信するにしても、Intent受信後すぐに通信するのではなく、ユーザーからのアクセスがバラけるように工夫すると良いと思います。
タグ:android
posted by t2low at 12:42| Android

2012年01月19日

[Android] jarsigner のバグ

仕事でPCを新しくして、Android開発環境も作り直しました。
数日して、apkを未署名で出力する機会があったのですが、そのときjarsignerを使った署名がまったくうまくいかず、しばらくハマっていました。

どうやらJDK7のjarsignerでは署名できないようです。
http://groups.google.com/group/android-developers/browse_thread/thread/38f3210c28324b93

うん、確かにJDK5かJDK6を使えと書いてあります。
http://developer.android.com/sdk/requirements.html

僕は職場の人に聞いてわかりましたが、知っている人がいなかったらもうしばらくハマっていたかもしれません。
ということで、備忘録的にメモ。
タグ:android
posted by t2low at 12:57| Android

2011年12月31日

[Android][翻訳] XmlPullParser.nextText()に気をつけて

Android Developers Blogの翻訳です。
英語に慣れるために翻訳しています。
誤訳が多々あると思うので、指摘いただけたら幸いです。


元の記事
http://android-developers.blogspot.com/2011/12/watch-out-for-xmlpullparsernexttext.html

--------------------------------

19 DECEMBER 2011
Tim Bray at 10:55 AM

Watch out for XmlPullParser.nextText()

XmlPullParser.nextText()に気をつけて

[This post is by Jesse Wilson from the Dalvik team. −Tim Bray]

Using XmlPullParser is an efficient and maintainable way to parse XML on Android. Historically Android has had two implementations of this interface:

AndroidでXMLをパースするのにXmlPullParserを使うことは、効率的で保守が容易です。これまでのAndroidは継承された2つのインターフェイスを持っていました。

KXmlParser, via XmlPullParserFactory.newPullParser ().

XmlPullParserFactory.newPullParser ()を使ったKXmlParser。

ExpatPullParser, via Xml.newPullParser().

Xml.newPullParser()を使ったExpatPullParser。

The implementation from Xml.newPullParser() had a bug where calls to nextText() didn’t always advance to the END_TAG as the documentation promised it would. As a consequence, some apps may be working around the bug with extra calls to next() or nextTag():

Xml.newPullParser()を使った実装は、nextText()を呼んだ時に常にEND_TAGまで進むことが保証されていないというバグがあります。
結果として、いくつかのアプリは別途next()やnextTag()を呼んで、このバグについて対処するかも知れません。

public void parseXml(Reader reader) throws XmlPullParserException, IOException {
    XmlPullParser parser = Xml.newPullParser();
    parser.setInput(reader);
    parser.nextTag();
    parser.require(XmlPullParser.START_TAG, null, "menu");
    while (parser.nextTag() == XmlPullParser.START_TAG) {
        parser.require(XmlPullParser.START_TAG, null, "item");
        String itemText = parser.nextText();
        parser.nextTag(); // this call shouldn’t be necessary!
        parser.require(XmlPullParser.END_TAG, null, "item");
        System.out.println("menu option : " + itemText);
    }
    parser.require(XmlPullParser.END_TAG, null, "menu");
}

public static void main(String[] args) throws Exception {
    new Menu().parseXml(new StringReade r(
                "<?xml version='1.0'?>" +
                "<menu>" +
                "<item>Waffles</item>" +
                "<item>Coffee</item>" +
                "</menu>"));
}

In Ice Cream Sandwich we changed Xml.newPullParser() to return a KxmlParser and deleted our ExpatPullParser class. This fixes the nextTag() bug. Unfortunately, apps that currently work around the bug may crash under Ice Cream Sandwich:

Ice Cream Sandwichでは、Xml.newPullParser()がKxmlParserを返すよう変更し、ExpatPullParserを削除しました。これによりnextTag()のバグが修正されます。残念ながら、バグを回避するアプリは、Ice Cream Sandwichより前のバージョンではクラッシュする可能性があります。

org.xmlpull.v1.XmlPullParserException: expe cted: END_TAG {null}item (position:START_TAG <item>@1:37 in java.io.StringReader@40442 fa8) at org.kxml2.io.KXmlParser.require(KXm lParser.java:2046) at com.publicobject.waffles.Menu.parse Xml(Menu.java:25) at com.publicobject.waffles.Menu.main(Menu .java:32)

The fix is to call nextTag() after a call to nextText() only if the current position is not an END_TAG:

この修正は、現在のポジションがEND_TAG以外のときだけ、nextText()の後にnextTag()を呼ぶようにするものです。

while (parser.nextTag() == XmlPullParser. START_TAG) {
    parser.require(XmlPullParser.START_TAG, null, "item");
    String itemText = parser.nextText();
    if (parser.getEventType() != XmlPullP arser.END_TAG) {
        parser.nextTag();
    }
    parser.require(XmlPullParser.END_TAG, null, "item");
    System.out.println("menu option: " + itemText);
}

The code above will parse XML correctly on all releases. If your application uses nextText() extensively, use this helper method in place of calls to nextText():

上記のコードはすべてのリリースでXMLを正しくパースするでしょう。もし、あなたのアプリケーションで広範囲にnextText()を使用していた場合、nextText()を呼んでいる箇所でこのヘルパーメソッドを使ってください。


private String safeNextText(XmlPullParser parser) throws XmlPullParserException, IO Exception {
    String result = parser.nextText();
    if (parser.getEventType() != XmlPullP arser.END_TAG) {
        parser.nextTag();
    }
    return result;
}

Moving to a single XmlPullParser simplifies maintenance and allows us to spend more energy on improving system performance.

単独のXmlPullParserに変更することはメンテナンスを容易にし、システムパフォーマンスの改善に多くのエネルギーを割けるようになります。。
タグ:翻訳 android
posted by t2low at 08:48| Android

2011年12月15日

[Android][翻訳] よく見ると100億ダウンロードに

Android Developers Blogの翻訳です。
短い記事があったので、途中の未訳の記事はすっ飛ばして訳してみました。
こんなに短い記事でも最後の1文の訳なんかはどう訳したら良いのかさっぱりです…。
英語に慣れるのはまだまだ遠そうです…。

元の記事
http://android-developers.blogspot.com/2011/12/closer-look-at-10-billion-downloads.html

--------------------------------

08 DECEMBER 2011

Dirk Dougherty at 10:46 AM

A Closer Look at 10 Billion Downloads

よく見ると100億ダウンロードに

[This post is by Eric Chu, Android Developer Ecosystem. −Dirk Dougherty]

On Tuesday, we announced that Android Market passed 10 Billion app downloads. We wanted to look a little deeper at that huge number. First question: which app was lucky number 10 billion? Photobucket Mobile. They’ll be getting a great prize package, including tickets to next year’s Google I/O developer conference.

火曜日、私たちはAndroid Marketのアプリのダウンロード数が100億件を超えたことを発表しました。私たちはその大きな数字について少し掘り下げたいと思います。
最初の質問:ラッキーな100億番目はどのアプリか?
Photobucket Mobile(https://market.android.com/details?id=com.photobucket.android)です。彼らは来年のGoogle I/O developer conferenceのチケットが入ったすてきな賞品を手に入れるでしょう。

Remember we still have 8 days left to celebrate 10 billion downloads with 10-cent apps on Android Market. You can follow which apps are promoted each day on +Android, our Google+ page.

100億ダウンロードを記念した10セント(日本では100円)アプリはまだ8日間残っていることを覚えていて下さい。あなたは毎日どのアプリがセールの対象になるのかGoogle+の+Android(https://plus.google.com/104629412415657030658/posts)で追いかけることが出来ます。

Here’s a graphical deep dive into 10 billion downloads...

ここに100億ダウンロードへの深いダイブの図を用意しました。

(図は元のサイトを見てください)
posted by t2low at 07:34| Android

2011年12月13日

[Android][翻訳] Android SDK Tools r14でのライブラリプロジェクトへの変更点

2度目の翻訳です。
英語の勉強のつもりで訳し始めましたが、これは1ヶ月半もかかってしまいました。
(大半は3DSでマリオを遊んでいたせいですが)
英語の初級者にこの分量は無理があるような気がしてきました。
すでに未訳の記事が10件ほど…。
全部訳すのか、それとも記事を選択して訳すのか、考えたいと思います。


元の記事
http://android-developers.blogspot.com/2011/10/changes-to-library-projects-in-android.html

--------------------------------

25 OCTOBER 2011

Posted by Xavier Ducrohet, Android SDK Tech Lead at 11:30 AM

Changes to Library Projects in Android SDK Tools, r14

Android SDK Tools r14でのライブラリプロジェクトへの変更点


Last week, we released the SDK for Android 4.0 and a new set of developer tools, now in revision 14. The updated tools include a lot of build changes, many that improve build performance. Also included is an under-the-hood change in how libraries are used by main projects − a first step in improving library support and code reusability. While the change should have little impact on existing projects, some developers have had issues when migrating to the updated tools. Please read below for more information about the change to library projects and how to solve migration issues.


先週、私たちはAndroid 4.0 SDKと新しい開発者ツール一式をリリースしました。リビジョンはもう14になります。
このアップデートされたツールには多くの変更点が含まれます。その多くはパフォーマンスの改善が行われています。
メインのプロジェクトから利用されるライブラリの使い方のような内部的な変更も含まれます。
ライブラリのサポートとコードの再利用性を改善することはその第一歩です。
その変更は既存プロジェクトに少し影響を与えます。いくらかの開発者たちはアップデートされたツールに移行するときに問題を抱えます。
ライブラリプロジェクトの変更点と移行の際の問題の解決方法についての詳細は以下をお読みください。


Previously, library projects were handled as extra resource and source code folders to be used when compiling the resources and the application’s source respectively. While this worked fine for most cases, there were two issues.

これまで、ライブラリプロジェクトはリソースやアプリケーションのソースをそれぞれコンパイルする際に使用される別のリソースやソースコードフォルダとして処理されていました。
多くの場合問題なく動作しますが、2つの問題がありました。

1. Developers asked us for the ability to distribute a library as a single jar file that included both compiled code and resources. The nature of Android resources, with their compiled IDs prevented this.

1. 開発者たちは、コンパイルされたコードとリソースを含む単一のjarファイル形式のライブラリに分割してできることを私たちに訪ねます。
Androidのリソースの性質上、コンパイルされたIDがそれを阻みます。

2. The implementation of the library projects was extremely fragile in Eclipse. Adding extra source folders outside of the project folders is non-trivial when it needs to be handled automatically, in a way that doesn’t expose a user’s local installation path (which is required for people working in teams through a source control system such as SVN or git).

2. ライブラリプロジェクトの導入はEclipseの中でとても不安定です。プロジェクトフォルダの外側に自動的に処理される必要のある別のソースフォルダの追加することは簡単ではありません。ユーザーのローカルなインストールパスを見る方法がありません(それにはSVNやgitのようなソース管理システムを通して同じチームで作業している必要があります)。

For r14, we decided to fix both issues at once, by moving to a compiled-code based library mechanism. This solves the implementation fragility in Eclipse and will allow us to, later, enable distribution of libraries as a single jar file.

r14では、コンパイルされたコードを基本としたライブラリ構造に変更することで、私たちはこの2つの問題を一度に修正することにしました。この修正はEclipseにプロジェクトを導入する際の不安定さを解決しました。そして、後には単一のjarファイルでのライブラリの配布ができるようになるでしょう。

As you might have seen in the release notes, moving to this new mechanism can affect existing projects in some cases, but there are simple fixes.

あなたはこの新しいライブラリ構造への移行はいくつかの既存プロジェクトに影響を与えること、しかし、簡単な修正で済むことをリリースノートで確認する必要があるでしょう。

The first impact of this change is that the new library project requires the resource IDs generated by libraries to be non final. This prevents the Java compiler from inlining the values in the library code, and therefore prevents usage of the switch statement in the library code. To address such occurrences in your code, Eclipse provides a refactoring action to convert fromswitch statements toif/else (see here).

この変更による最初の影響は、新しいライブラリプロジェクトが要求するライブラリによって生成されたリソースIDがfinalではなくなることです。これによってJavaコンパイラがライブラリ内で値をインライン化できなくなります。また、このことによってライブラリ内ではswitch文にリソースIDを使うことができなくなります。あなたのコードでそのようなことが起こったときの対処法としては、Eclipseの提供するリファクタリング機能によって、switch文からif/else文に変換することができます。
(こちらを確認してください)

Second, some projects may not have been properly migrated to the new
mechanism, resulting in projects that fail to compile, with errors such as duplicated classes being added in the dex build step. ADT 14 should have migrated older projects to the new mechanism but the fragility of the old mechanism may have prevented it from happening. This makes projects reference the libraries twice, using both the old and new mechanisms, which then triggers the libraries classes being packaged twice. If you see this in your projects, look in the Package Explorer for extraneous source folders named with the pattern_src. The screenshot to the right shows an example of this.

2つ目に、いくつかのプロジェクトでは新しい構造にプロパティを移せないかもしれません。結果として、そのプロジェクトはコンパイルに失敗します。例えば重複したクラスが、dexを作成する段に追加されるなどのエラーが起こります。
ADT14では、古いプロジェクトを新しい構造へ移行すべきでしたが、古い構造の不安定さのためにそれはできないかもしれません。
これは作成するプロジェクトが、新旧両方の構造を使用するために、ライブラリを2度参照します。そして、ライブラリのクラスは2度パッケージされてしまいます。
これについてあなたがプロジェクトを確認するのなら、パッケージエクスプローラで_srcという形式で名付けられた外部ソースフォルダを見てください。右のスクリーンショットはその例です。

(画像は元のサイトを見て下さい)

To fix the project, you must remove the extraneous source folders with the following steps:

プロジェクトを修正するには、以下の手順で外部ソースフォルダを削除する必要があります。

Right click source folder and choose Build Path > Remove from Build path A dialog will pop up. In it, make sure to check “Also unlink the folder from the project” to completely remove the folder.

ソースフォルダを右クリックして、Build Path > Remove from Build pathを選択するとダイアログが表示されます。その中で、“Also unlink the folder from the project”がチェックされていることを確認してください。それでフォルダの削除は完了です。

With this change to library projects, we pave the way to better support for reusable components. We will continue working to make components easier to create, work with, and manage. Our goal is to make it easy for developers to create apps with great user experiences that easily adapt to all form factors.

これによってライブラリプロジェクトが変更され、私たちはコンポーネントの再利用のためのより良いサポートができるようになります。
私たちは継続して、作成や作業、管理が簡単になるようなコンポーネントを作成していきます。
私たちの目標は開発者がすべての要因に簡単に適応できる素晴らしいユーザ体験をもたらすアプリを作るのを容易にすることです。

Some developers have also told us that they only use library projects internally, that they don’t need to distribute binary versions and would prefer to continue with a source-based mechanism. We are investigating how we could support this alongside the new mechanism.

一部のの開発者は、内部でのみ使っているライブラリプロジェクトについてバイナリーバージョンで区分する必要がないこと、そしてソースベースの構造を継続できる方を好むだろうということも私たちに話してくれました。
私たちは新しい構造ついてと並行してどのようなサポートができるのかを研究しています。

Finally, I wanted to point out that we are tracking a few known issues (and workaround for them) in the current r14 tools at this page: http://tools.android.com/knownissues.

最終的には、このページ(http://tools.android.com/knownissues)で、現行のr14ツールのいくつかのの既知の問題を追いかけていること(それと、その回避方法)を見てもらいたいと思っています。

We are working on a tools update that will include fixes for most of these. We are hoping to have it out shortly.

私たちはツールのアップデートに取り組んでいます。そのほとんどが修正の取り込みです。私たちは近いうちに決着をつけられることを望んでいます。
タグ:翻訳 android
posted by t2low at 22:58| Android

2011年11月07日

[Android][翻訳] ICSで新しく公開されたAPI

英語の勉強にもなるし、と思い、Android Developers Blogを読んでみることにしました。
ただ、中学・高校レベルの英語力しかないので、うまいこと訳すことができません。
時間もかかりました。
いずれ英語力がついたときに過去の訳を読んで恥ずかしくなるために、ここに晒します。
添削していただける奇特な方がいらっしゃいましたら、コメントいただけると幸いです。

元の記事
http://android-developers.blogspot.com/2011/10/ics-and-non-public-apis.html

--------------------------------

20 OCTOBER 2011

Posted by Tim Bray at 10:20 AM

New Public APIs in ICS

ICSで新しく公開されたAPI

Since Android is open-source, anyone can look at the code and see how it works inside. If you do this, you’ll notice that most but not all of the APIs are publicly documented.

Androidはオープンソースなので、誰でもコードを見ることができるし、内部でどんな処理が行われているか知ることができます。
もし、それを行うのなら、すべてではないけれど、ほとんどのAPIが文書化され公開されていることに気づくでしょう。

If they’re publicly documented, they’re part of what we consider the Android Application Framework. This means their tests appear in the Compatibility Test Suite (CTS) so that our hardware partners have to prove that the APIs work, and that we promise to try very hard not to change them and thus break your code.

文書が公開されているなら、それらは私たちがAndroid Application Frameworkと考えるものの一部です。
これが意味するのは、これらのテストがCompatibility Test Suite(CTS)にあるということです。
私たちのハードウェアパートナーはAPIが動作することを証明する必要があります。
さらに、あなたのコードを壊してしまわないよう、動作を変えない努力を精一杯行うことを約束します。

In almost every case, there’s only one reason for leaving APIs undocumented: We’re not sure that what we have now is the best solution, and we think we might have to improve it, and we’re not prepared to make those commitments to testing and preservation.

ほとんどすべての場合で、文書化されていないAPIを残す唯一の理由があります。
何が最良の解決法なのか確信が持てないとき、私たちはそれを改良する必要があるかもしれないと考えます。それらのテストや維持に責任を果たす準備が出来ていない場合に文書化されていないAPIを残します。

We’re not claiming that they’re “Private” or “Secret” − How could they be, when anyone in the world can discover them? We’re also not claiming they’re forbidden: If you use them, your code will compile and probably run. And in fact we know of quite a few apps out there whose developers have used undocumented APIs, often to good effect. It’s hard to get too upset about this in cases where there’s a useful API that we haven’t gotten around to stabilizing.

私たちはそれらが"Private"であるとか"Secret"であるとは主張していません。
-誰もがそれを見つけることができるようにするにはどうしたら良いのでしょう?
私たちはそれらを禁止しているとも主張していません。あなたがそれらを使っても、コードはコンパイルされ、おそらく動くでしょう。
そして、実際にかなりの数の文書化されていないAPIを活用したアプリが出回っていることを知っています。
私たちにこの便利なAPIを安定化させる余裕がないような状況では、腹を立てるわけにはいきません。

But the developers who use those APIs have to be prepared to deal with the situation that arises when we move them from the undocumented outside into the Android Application Framework. Fortunately, this is reasonably straightforward. Also we take a close look at Android Market, using our in-house analytics tools, to get a feel for the impact when we know one of these changes is coming.

しかし、これらのAPIを利用する開発者は、私たちが Android Application Frameworkに文書化されていないAPIを移した際に起こる問題に対処できるよう備えておく必要があります。
幸いなことに、これはまあまあ簡単なことです。
私たちはこれらの一つの変更が行われるときの影響を感じられるように、社内分析ツールを使ってAndroid Marketを注視しています。

There are a few such changes coming up in the Android 4.0 “Ice Cream Sandwich” (ICS) release of Android. We wanted to take the opportunity to combine these words on undocumented APIs with some specifics about the changes.

Android 4.0 ”アイスクリームサンドイッチ” (ICS) のリリースで、そのような変更が少し出てきます。
私たちは文書化されていないAPIといくつかの変更のあった仕様をまとめる機会を得たいと考えていました。

Calendars

カレンダー

Let’s start with the good news: As of ICS, the Android Framework will include a fully-worked-out set of APIs for accessing Calendar data. You can guess the bad news: Quite a few developers have built apps (including many good ones) using the undocumented Calendar APIs, some using fairly low-level access to the calendar database. Unfortunately, these integrations were unsupported, and prone to breakage by platform updates or OEM customization of calendar features.

良いニュースから始めましょう:ICSではAndroid Frameworkにカレンダーにアクセスするための十分に練り上げられたAPIを含むようになります。
悪いニュースは想像できるでしょう:
かなりの数の開発者たちは非公開のカレンダーAPIを利用したり、中にはカレンダーデータベースにかなり低レベルなアクセスをしてアプリ(多くの素晴らしいもを含む)を作り上げてきました。
不幸にもこれらの統合はサポートされない上に、プラットフォームのアップデートや、カレンダーのOEMカスタマイズによって壊れやすくなっています。

We want to see lots of good calendar apps and extensions that work reliably across Android devices, and aren't broken by platform updates. So we decided to create a clean API, including a comprehensive set of Intents, to manage calendar data in ICS. Now anyone can code against these new APIs and know that Android is committed to supporting them, and that partners have to support these APIs as part of CTS.

様々なAndroid端末で確実に動き、プラットフォームのアップデートがあっても壊れない、そのような多くの素晴らしいカレンダーアプリと拡張機能を見てみたいと思っています。
私たちは、Intentの総合的なセットを含む、ICSでカレンダーのデータを管理するためのきれいなAPIを作ることにしました。
今すぐ誰でもこれらの新しいAPIでコーディンクすることができ、Androidがこれらのサポートを約束していることを知り、パートナー会社はCTSの一部として、これらのAPIをサポートする必要があります。

Once the new APIs arrive, you’re going to have to update your apps before they’ll run correctly on ICS while still working on older releases. There are a variety of techniques for doing that, many of which have been featured on this blog, including reflection and lazy loading. Recently, we introduced Multiple-APK support, which could also be used to help with this sort of transition.

新しいAPIが出てきたら、あなたのアプリがまだ旧APIで動いている間はICSでも正しく動くでしょうけれど、アップデートをしなければならなくなるでしょう。
それを行うには様々な技術があり、リフレクションや遅延読み込みを含む多くの記事がこのブログで取り上げられています。
最近、私たちはある程度移行の手助けとしても使える複数APKのサポートを紹介しました。

Text To Speech

テキストから音声への変換

Android has never really had a text-to-speech API at the Framework level, but there was unofficial access at the C++ level. With ICS, we will have a fully-thought-through application-level API running on Dalvik, so you can access it with ordinary Java-language application code.

AndroidにはFrameworkレベルのテキストから音声に変換するAPIがありませんでしたが、C++レベルの非公式のものはありました。
ICSでは、完全に考え抜かれたアプリケーションレベルのAPIがDalvik上で動作するようになります。そして、それは通常のJavaのコードでアクセスできます。

The old C++ API will no longer be supported, but we’ll have a compatibility layer that you can use to bridge from it to the new API. We think it should be easy to update for ICS with very little work.

古いC++のAPIはもはやサポートされなくなりますが、互換レイヤーが用意されるのでそれを使って新しいAPIに接続することはできます。
ほんの少しの作業で簡単にICSへアップデートできると考えています。

Doing the Right Thing

正しい対応を行う

We recognize that this means some work for developers affected by these changes, but we’re confident that Android programs in general, and both Calendar and TTS apps in particular, will come out ahead. And we also think that most developers know that when they use undocumented APIs, they’re making a commitment to doing the right thing when those APIs change.

私たちはこれらの変更で影響を受ける開発者たちに作業が発生することを認識しています。
しかし、私たちは一般的なAndroidアプリや、特にカレンダーアプリやTTSアプリの両方が得をすると自信を持っています。
そして、私たちはまた、多くの開発者たちが文書化されていないAPIを利用するときにそのことを理解している、彼らはそのAPIが変更されるときには正しい対応を行う責任を持っている、とも考えています。
タグ:翻訳 android
posted by t2low at 02:15| Android

2011年10月04日

[Android] 充電の検知

端末の充電を検知するサンプルコードを書いてみました。

端末の充電開始と終了はBroadcastで飛んできます。
BroadcastReceiverとManfest.xmlに適切に設定すれば受信できるようです。
BroadcastReceiverのIntentFilterはこんな感じ。

<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
</intent-filter>

サンプルコードを置いておくので必要な方は見てください。
PowerConnectSample.zip
posted by t2low at 22:33| Android

2011年09月18日

[Android] アカウント管理を行う(アカウントの追加)

前回の続きです。

前回はAndroid側にアカウントの定義をわかってもらうところまでやりました。
今回はとりあえずアカウントを作成できるようにしたいと思います。
サンプルなのであんまりめんどくさいことはやりません。
「アカウントと同期」→「アカウントの追加」→「Sampleアカウント」と選ばれたら、即アカウント作成とします。
ただ、重複はNGにします。アカウントは1個しか作りません。

さて、前回のプロジェクトで空実装だったAuthenticatorを実装していきましょう。
アカウントを作成できるようにするには、addAccount()を実装します。

@Override
public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options) throws NetworkErrorException {
return null;
}

前回はこんなコードでした。nullを返しているだけです。
ここに処理を追加し、アカウントを作ります。
アカウントはAccountクラスです。
インスタンスの作り方は↓こう。

Account account = new Account("アカウント名", "アカウントタイプ");

"アカウント名"は通常ユーザに入力してもらうものかと思いますけど、今回は固定値で"Sample"としておきます。
"アカウントタイプ"はaddAccountの引数accountTypeをそのまま使いましょう。

そして、アカウントを作るには↓こう。

AccountManager am = AccountManager.get(mContext);
am.addAccountExplicitly(account, "Password", null);

AccountManagerのaddAccountExplicitly()で作ることができます。
"Password"はパスワードです。これも固定値にしちゃってます。
アカウントを作るのであれば、これだけです。簡単です。
上で言っていた重複判定なんかは、いつものようにサンプルコードを置いておくので、そちらを見てくださいまし。

なお、addAccount()の戻り値はBundleです。
いろいろと自由に値を詰めることができます。
一応、AccountManagerにはすでにキーの定義がいくつかあります。
エラーコードやエラーメッセージを返す必要があるときは、AccountManagerで定義されたものを使うと良いでしょう。

また、今回のサンプルコードを実行するために以下の2つのパーミッションが必要です。

android.permission.GET_ACCOUNT
android.permission.AUTHENTICATE_ACCOUNTS

忘れずにManifestに書いておいてください。
実際にアカウントを追加してみるとこんな感じです。
device-2011-09-18-173754.png device-2011-09-18-173828.png
アカウントの追加は以上です。
また、サンプルコードを置いておくので、よろしかったら見てください。
AccountSample.addAccount.zip
タグ:android
posted by t2low at 17:53| Android

2011年09月12日

[Android] アカウント管理を行う

最近、仕事でアカウントを使うコードを書きました。
後々使えそうなところなので、忘れないうちにサンプルコードでも書いて、メモっとこうと思ってこの記事を書いています。
ちなみにアカウントと言っているのは、Android端末の「設定」→「アカウントと同期」のとこに出てくる「アカウント」のことです。

Eclipseを起動します。
プロジェクトを作ります。Androidのやつです。
とりあえず、Activityは要りません。

アカウントの情報を定義しているのはxmlです。たぶん。
resフォルダにxmlフォルダを作りましょう。
その中にxmlを作ります。
Android SDKに付属のサンプル(SampleSyncAdapter)に倣って、authenticator.xmlという名前にしました。

編集します。
<account-authenticator>というタグとその属性を書きます。
↓こんな感じ。

<account-authenticator
xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="com.tappli.android.sample.account"
android:icon="@drawable/icon"
android:smallIcon="@drawable/icon"
android:label="@string/account_label" />

ちなみにコレ↑、ほぼSampleSyncAdapterのコピペです。
<account-authenticator>ってタグの説明が見つけられなくて困ってます。
どなたかリファレンスのどこを見たら載っているのか教えてくだしあ。

android:accountTypeってのは自分で何か指定してください。
パッケージ名じゃなくて良いと思います。
このアカウントを作ったり、このアカウントからトークン取得するときとかに必要になります。
android:labelは「アカウントと同期」からアカウントを追加するときに表示される名前ですね。
res/values/string.xmlに「Sampleアカウント」と定義しました。


さて、このアカウントの定義をAndroidにわかってもらうために、Manifestに書いとく必要があります。
SampleSyncAdapterを見ると<service>タグの中の<meta-data>としてauthenticator.xmlが指定されています。
同じようにするためにServiceを準備しましょう。
一旦Manifestは置いときます。

SampleSyncAdapterを参考にすると、Serviceの中でAuthenticatorというものが必要なようです。
Serviceも置いといて、先にAuthenticatorを片付けましょう。
AuthenticatorはAbstractAccountAuthenticatorというクラスを継承すれば良いようです。
とりあえずとして、まずは空のAuthenticatorを作りましょう。
コンストラクタと以下のメソッドをoverrideします。
・addAccount
・confirmCredentials
・editProperties
・getAuthToken
・getAuthTokenLabel
・hasFeatures
・updateCredentials
とりあえずなのでメソッドの中身はすべて「return null;」のみです。
これでAuthenticatorができました。

んで、Serviceに戻ります。
Serviceは普通のServiceを継承すれば良いようです。
onCreate()でAuthenticatorのインスタンスを作って、onBind()でIBinderを返却するだけ。
これもSampleSyncAdapterのほぼコピペでいけますね。

最後にManifestを編集します。
これもSampleSyncAdapterをコピペして、クラス名とandroid:resourceの部分を自分の環境に合わせれば十分そう。
こんな感じになります。

<service
android:name=".AuthenticationService"
android:exported="true"
>
<intent-filter>
<action
android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/authenticator" />
</service>

これでたぶん最低限の準備は整いました。
サンプルを起動してみましょう。サンプルをエミュレータでも実機でも良いので転送してみてください。
Activityがないのでアプリとしては起動しないです。
Android端末の「設定」→「アカウントと同期」を開いてください。
「アカウントを追加」というボタンがあるのでタップします。
最初にauthenticator.xmlで指定したラベル名が表示されていたら成功です。
device-2011-09-10-194934.png
ただ、Authenticatorの中身が空なので、タップしても何も起きません。
次はこの中身を作っていこうと思います。

もしかしたら一部の人でこのサンプルを動かすと端末がリセットするようなことがあるかも知れません。
これはアプリのバグというよりはAndroidのバグっぽいです。
Android2.1のソースを見たら、nullチェックをせずにfor文にリストを突っ込んでいるところがあって、そこでヌルポが発生していました。
一応、回避方法はあって、「アカウントと同期」の「同期」の方も実装すると大丈夫っぽいです。
AbstractThreadedSyncAdapterを実装して使えるようにしろってことになります。
この辺はまだ全然理解できていないので、おいおいやっていこうと思います。
実機で動かないって人はとりあえずエミュレータ使っといてください。

このサンプルコードはこちら↓
AccountSample.zip

9/18 続きを書きました。
タグ:android
posted by t2low at 00:33| Android