2012年12月8日土曜日

Android Menu Icon Resources

プロトタイプ作成でよく使うのでまとめておく。

リストの内容は
xml:@android:drawable/ic_menu_***
Javaコード:android.R.drawable.ic_menu_***
で使える41種類。
(SDK内にはこの他にもメニューアイコンリソースがあります)

アイコン画像はSDKのdrawable-hdpi配下のもの。
2.xは72x72px、4.xは48x48pxとなっている。

2012年11月5日月曜日

au 2012 冬モデル ディスプレイパネル まとめ

型番 ペットネーム サイズ 解像度 パネル
HTL21 HTC J butterfly 5" FHD super LCD 3
SOL21 Xperia VL 4.3" HD TFT
SCL21 GALAXY S III Progre 4.8" HD SUPER AMOLED
SHL21 AQUOS PHONE SERIE 4.7" HD S-CGSilicon
FJL21 ARROWS ef 4.3" HD TFT
LGL21 Optimus G 4.7" HD IPS
KYL21 DIGNO S 4.7" HD TFT
PTL21 VEGA 4.3" HD TFT
CAL21 G'zOne TYPE-L 4" WVGA IPS

2012年11月2日金曜日

Macでパラパラと画像をプレビューする方法


  1. 画像の入ったディレクトリをFinderで開く
  2. 画像を選んで[command] + [Y]
  3. 画像が別ウィンドウで開くので、カーソルで画像を選択していくとパラパラとプレビューできる
画像に限らず、テキストファイルなどもプレビューできます。

2012年10月13日土曜日

NFCタグ名刺のつくり方

Nexus 7の国内販売が始まったり、docomoさんの冬モデルでNFC搭載機が5機種発表になったりとNFCが盛り上がって参りました!?
ということで、NFCタグを使った名刺のつくり方について書いてみます。

用意するもの

・NFC搭載Android端末
・名刺
・NFCタグ
・NFCタグライターアプリ

NFC搭載Android端末

今回はNexus S(Jelly Bean)を使用。

NFC搭載端末についてはこちらを参照。
Wikipedia
近距離無線通信

名刺

NFCタグを貼る場所があれば何でも。

NFCタグ

今回の仕入れ先はこちら。
20枚で税込み1,050円也。

RFID/NFC Real Touch Shop
月に1度土曜日営業されています。

NFCタグライターアプリ

今回はこちらのアプリを使用。

NFCタスクランチャー
Android app on Google Play

以前はKDDIさんのこちらのアプリを使用してたんですが、なぜか書き込めませんでした。。
前に使ってたときはNexus SのOSが2.3かICSだった気がします。
因みにNexus 7も書き込みNGでした。

NFCタグリーダー
Android app on Google Play

つくり方

書く

NFCタスクランチャーを起動 -> 新規タグ -> 新規URL -> URLを入力 -> 「URLを入力してタグにつける」をタップ
と操作すると下の画面になります。
複数タグを書き込むにチェックを入れて、NFCタグにかざしていきます。



貼る

地味な作業です...



読む

Nexus Sに名刺をかざすとブラウザが起動してきます。



以上

まとめ

NFCタグの入手性がまだまだですが。。
簡単に作れますので名刺交換の際のネタ作りにも良いんじゃないでしょうか。

2012年10月12日金曜日

いまどきの透明なActivityのつくり方

書籍やWebで透明なActivityについて調べると、「Theme.Translucentを使いましょう」と書いてある所が多いかと思います。しかしながら、いまどきのアプリ開発では4.xを意識してHolo系のThemeを有効にしたい所です。
今回は、Holo系のThemeを使いつつActivityの背景を透明する方法について調べてみました。

コード

いまどきのADTでAndroidプロジェクトを作成すると、以下のようなフォルダ構成で「3.x+ではHolo Themeを有効化、2.xでは従来のThemeを使用」となっているかと思います。そのため、それぞれのstyles.xmlに背景を透過にする設定を追加しています。

/res/values/styles.xml
/res/values-v11/styles.xml
/res/values-v14/styles.xml

まとめ

上記の方法を使うとDark系・Light系テーマの切り替えもできますし、Theme.Translucentを使うよりもレイアウトの自由度が増すと思います。

今回は、こちらのブログを参考にさせていただきました。

ReDo -Refrigerator Door- れいぞうこのドア
透過なActionBar
http://greety.sakura.ne.jp/redo/2011/08/actionbar.html

ActionBarを透過にして、ActionBar領域も含めて背景を描画する手法、どこかで使って見たいと思います。
この記事書かれたの1年以上も前なのですね。。
自分の周回遅れ感が...

2012年9月17日月曜日

Google Cloud Messaging for Android ことはじめ(もっと簡単に動かしてみる編)

今回はアプリケーションサーバの代わりにブラウザを使ってメッセージを送信する方法について書いてみました。



2012年9月6日木曜日

ダブルクリックでジャンプできるようにログを出す方法

LogCatのダブルクリックでコードにジャンプする機能を利用する方法について考えてみたメモ

コード


まとめ

色々試した結果
at クラス名(ファイル名:ライン数)
がログに含まれているとLogCatでダブルクリックした時にコードにジャンプ出来るようです。
上記のコードではログの可読性向上のため、getPadding()でタブ数を計算してジャンプ用ログを整列しています。

こんな感じでログが出ます。


2012年9月1日土曜日

ロックスクリーンを考慮して処理の再開を行う方法

この動画に「Lock Screen時は音楽再生を止める」というTipsがあったので、試してみたメモ

Google Developers Live
[JP 日本語] Google Play での Android アプリ提供ことはじめ
22分40秒あたり

コード


まとめ

  • アプリが開いている状態でスリープから復帰した場合、ロックスクリーンが表示されていても、onResume()が呼ばれる
  • ロックスクリーンが表示されているかの判定はKeyguardManager#inKeyguardRestrictedInputMode()で可能
  • ロックスクリーンを使用していない場合への考慮も必要
  • ロックスクリーン解除時は、ブロードキャストインテントandroid.intent.action.USER_PRESENTがシステムから通知される

その他

KeyguardManagerですが、API Level 16からisKeyguardLocked()/isKeyguardSecure()が追加されたようです。
isKeyguardLocked()でもロックスクリーン表示の判断が行えました。
isKeyguardSecure()はロックスクリーンにパスワードやパターンなどが設定されている時にtrueを返すようです。
※ API Level 15のIS11LGでも上記のメソッドが使用出来ました。リファレンスの誤記でしょうか?

参考にしたサイト
Yukiの枝折
Android:キーガードはActivityではなくViewであることの影響

2012年8月18日土曜日

LruCacheの使い方

TwitterのツイートをListViewに表示するという処理で、TwitterアイコンのキャッシュにLruCacheを使ってみたメモです。

馴れ初め(ダイジェスト)

TwitteアイコンのキャッシュにSoftReferenceを使っていたのですが、2.2 と 2.3 / 4.xで挙動が違って困っていたところ、以下のツイートに出会う。


ということで、Android Training「Caching Bitmaps」で使われていたLruCacheに辿り着いた次第です。
http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

Twitter と 有益な情報をツイートしてくれる方々に感謝です。

コード


使い方

LruCacheはAPI Level 12からのクラスですが
http://developer.android.com/reference/android/util/LruCache.html
Support Libraryに入っているので
http://developer.android.com/reference/android/support/v4/util/LruCache.html
API Level 4から使えるようになっています。

使い方としては
・KeyとValueの型を指定してインスタンス化する
・LruCache#sizeOf()をオーバーライドしてBitmapのByte数を返してあげる
だけです。

Android TrainingのサンプルコードではBitmap#getByteCount()を使っていますがAPI Level 12からのメソッドなので上記の処理に書き換えています。
上記のコードではキャッシュサイズを1MB固定にしていますが、端末のDalvikVMヒープサイズから動的に決めたい場合は、Android TrainingのサンプルコードのようにすればOKです。

あとは、Twitterアイコン画像URLをKeyにBitmapをキャッシュしておいて、画像使用時にImageCache.getImage(Twitterアイコン画像URL)がnullだったら再取得というような処理にしておけばよいかと思います。

まとめ

2.3以降GCがモア アグレッシブになっているので、SoftReferenceを使用した場合、ListViewの行が画面から消えるとすぐに画像キャッシュがクリアされてしまう。
従って、今後はLruCacheを使いましょう。
といったところでしょうか。

LruCacheを利用することで、SoftReferenceを使用した場合の2.2 と 2.3以上でキャッシュの挙動が違うという問題が解決できました。
公式ドキュメントはちゃんとチェックしておかないとダメですね。。

因に僕は、常にこの構成でデバッグしています。
書いたコードに対してすぐにバージョン間の差異が確認できるので良いかなと思っています。
今のところ誰からも賛同を得られていませんが...

Fragmentationと共に生きる方法
http://neta-abc.blogspot.jp/2012/08/fragmentation.html


2012年8月11日土曜日

エミュレーター・実機に文字列を流し込む方法

最近多用している便利なコマンドのメモです。

adb shell input text <文字列>

エミュレーター・実機でテキスト入力欄を選択して、上記のコマンドを実行すると文字入力ができます。
<文字列>の部分に日本語は使えません。
端末のIME設定が入力に反映されますのでローマ字入力してあげれば日本語の入力も可能です。

adb shell
input text <文字列>
でも使えますが、adbを切断したときにコマンド履歴は消えてしまうので
adb shell input text <文字列>
とやったほうが、コマンド履歴から再利用できて良いと思います。

Facebookのテストアカウントとか使ってるとメールアドレス長くて手入力は辛いですよね。。

MacでInkscapeを使う(画像取り込み編)

Inkscapeに画像ファイルを取り込もうとしてハマったのでメモしておく。

ドラッグ&ドロップ

Windows環境ですと、画像ファイルの取り込みはExplorerからドラッグ&ドロップすればOKですが、Mac環境では、ドラッグ&ドロップは受け付けてくれませんでした。
X上で動いているからでしょうか?

コピー&ペースト

なので、今度はコピー&ペーストを試してみましたがこんな感じに...


インポート

で最後に辿り着いたのがインポートです。
メニューの[ファイル] - [インポート]から開きます。
拡張子のフィルタを[すべてのイメージ]にして、取り込みたい画像ファイルを選択すればOKです。
後は、画像を「リンク」にするか「埋め込み」にするか聞かれますのでお好みで。
・リンクにすると、画像ファイルを移動したときにリンク切れになります。
・埋め込みにすると、SVGファイルに埋め込まれるのでファイルサイズが大きくなります。


これで画像が取り込めるようになりました。
Windows環境と比べると少し面倒ですね。

2012年8月4日土曜日

Fragmentationと共に生きる方法

ADT20から1クリックで複数の実機・エミュレーターにアプリをDeploy出来るようになっています。

ADT 20 Preview 3 メモ
http://neta-abc.blogspot.jp/2012/06/adt-20-preview-3.html

この機能を利用すれば、デバッグが少し楽になるんじゃないかと思い試してみました。

機材

・MacBook Air (13-inch, Mid 2012)
・USBハブ(U2H-TZS420Sシリーズ)
 http://www2.elecom.co.jp/cable/usb-hub/u2h-tzs420s/index.asp
・Nexus S(4.1)
・IS11LG(2.3)
・IS06(2.2)


今回使用したUSBハブはセルフパワー対応の物を選んでいます。
アダプタの出力が2.0Aなので、4ポートフルに使った場合でも1ポート当たり500mAは供給される計算です。
複数の端末を使って開発しているとバッテリーマネジメントがストレスだったりします。
今回はその辺りの解消も目指します。
※そもそも、バスパワーだと電力不足で4台も繋げない気もします。確認してませんが...

あとは、ポート単位でON/OFFスイッチが付いている所が、このUSBハブを選んだ理由です。
特定の端末を一時的に切り離したい時に、面倒なUSBの抜き差しが不要なので便利かと思います。

動作確認結果

DDMSで見ると、USBハブ経由で3台の端末が認識されています。

プロジェクトの設定は[Run As] - [Run Configurations...]から行います。

この状態でプロジェクトを実行して見ましたが、問題無く3台の端末にアプリをDeployできました。

まとめ

先日からこの構成でデバッグを行っていますが、Androidのバージョン違いで動作が異なる部分に気付いたりして、楽しく(?)開発を進めています。
タイトルのFragmentationとは離れますが、端末間で通信するアプリのデバッグなんかにも良いんじゃないかと思います。

2012年7月15日日曜日

MacでInkscapeを使う(日本語化編)

Inkscapeの言語設定を変えるだけなんですが、ぱっと見でどこから設定を行うのか分からなかったのでメモしておく。


設定方法

1. Inkscape Preferencesを開く([shift] + [control] + [P])
2. Interfaceを選択する
3. LanguageでJapanese (ja) を選択する
4. Inkscapeを再起動する

日本語に切り替えると、こんな感じです。


MacでInkscapeを使う(Altキー編)

デフォルトの設定(X11)ではAltキーが使えないので、Altキーを使えるようにする方法をメモしておく。
設定方法

1. Inkscapeを起動する
2. [command] + [ , ]でX11の環境設定を開く
3. 「OptionキーでAlt_LとAlt_Rを送信」にチェックを入れる
以上の設定で、OptionキーがAltキーの代用になります。

Altキーの用途ですが、重なっている要素の下にあるものを選択するときによく使いますね。
※ アイコンの最下層に配置した影を微調整したい場合など

[alt] + [左クリック]で重なっている要素を上から順に選択できます。


Mac OS X Lion Git導入メモ

はじめに

この手順はXcodeをインストールする前提です。
Xcodeが不要な方は、本家のDownloadページからdmgファイルを落としてインストールするのが王道なんでしょうか?
ちょっと、この辺り確認していないのですみません...

手順

1. App StoreからXcodeをインストールする ※要Apple ID
2. Xcodeを起動
3. [command] + [ , ]でPreferences...を開く
4. Downloadsタブにある「Command Line Tools」をインストールする
以上です。

PATHの設定は不要で、上記の手順のみでターミナルからGitのコマンドが使えるようになります。

2012年7月14日土曜日

実機で解像度を変更してデバッグする方法

am display-size コマンドを使ってみたメモです。

情報源は@yanzmさんのブログから。
Y.A.M の雑記帳
Google I/O 2012 セッションまとめ : So You've Read the Design Guide; Now What?
http://y-anz-m.blogspot.jp/2012/07/google-io-2012-so-youve-read-design.html

注意
アプリの強制終了が発生する場合がありました。
コマンドの実行は自己責任でお願いします。

コマンド

解像度の指定
adb shell am display-size <解像度>

解像度を元に戻す
adb shell am display-size reset

※画面の回転とかアプリ起動とかやると解像度の変更が反映されます。

動作確認

次の3機種で動作確認を行いました。
・Nexus S
・ICONIA TAB A500
・IS11LG

Nexus SとICONIA TAB A500はコマンドが使えることを確認しました。
IS11LGではコマンド無くて使えずです。
3.xからなのかな?
※Nexus S、ICONIA TAB A500両機ともに、コマンド実行時にSecurityExceptionが発生

下記は、ICONIA TAB A500で
adb shell am display-size 1024x600
を実行したスクリーンショットです。(ICONIA TAB A500の本来の解像度は1280x800)
スクリーンショットで黒く表示されている部分までが、本来の表示領域です。

因にDensityの変更は出来ないそうです。
Nexus S(high density)でWQVGA(low density)とかやると画面がむちゃくちゃになるのでご注意を。

Mac OS X Lion キーボードショートカット メモ

スクリーンショット

全画面
[command] + [shift] + [3]
矩形選択
[command] + [shift] + [4]
ウィンドウ
矩形選択モードで[space]

スクリーンショットを撮ったときの、シャッター音の演出が良いですね。

Finder ファイルのカット&ペースト(移動)

[command] + [C] でファイルを選択して
[command] + [option] + [V]

※使えるのはMac OS X Lionからのようです。

Finder 指定したディレクトリに移動

[command] + [shift] + [G]

Finder 新規フォルダの作成

[command] + [shift] + [N]

アプリケーションの強制終了

[command] + [option] + [esc]

2012年7月9日月曜日

DialogFragmentメモ(2)

前回の結論として、DialogFragmentのonCreateView()よりonCreateDialog()をOverrideした方が良さそうだったのでやってみたメモ。

注意(2012/07/09追記)
ダイアログ表示状態で画面を回転してダイアログのボタンを押すとNullPointerExceptionで落ちることに気付きました...
落ちる場所はDialogButtonClickListenerの65行目からのif文でどちらのダイアログか判別している部分です。
修正してブログ更新する予定。。

DialogFragmentメモ
http://neta-abc.blogspot.jp/2012/06/dialogfragment.html




ただ、DialogFragmentのonCreateDialog()の中で表示内容を設定してしまうとダイアログの数だけDialogFragmentを継承したクラスを作らないといけないので、今回はDialogFragmentを継承したクラスを1つ作り、それを使い回せるようにすることを目標にやってみました。

方針(ざっくり)
(1) DialogFragmentを継承したAlertDialogFragmentクラスを作成する
(2) ダイアログ表示内容の設定はダイアログの呼び出し元で行う
(3) (2)で作成したダイアログ表示内容をsetArguments()でFragmentに設定する
(4) AlertDialogFragmentのonCreateDialog()をOverrideして、(3)で設定したダイアログの表示内容をAlertDialogFragmentに反映する

といったところです。

ただし、setArguments()を使ってFragmentに渡せる引数はBundle型なので、AlertDialog.Builderを継承したクラスを作成してSerializableインターフェースを実装しています。※BundleのputSerializable()を使うためです。

コード
MainActivity.java
package com.example.alertdialogfragment;

import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;

public class MainActivity extends FragmentActivity implements OnClickListener {

    private AlertDialogFragment mDialogFragment1;
    private AlertDialogFragment mDialogFragment2;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.button1).setOnClickListener(this);
        findViewById(R.id.button2).setOnClickListener(this);
    }

    public void onClick(View view) {
        DialogButtonClickListener listener = new DialogButtonClickListener();
        AlertDialogFragment.Builder builder = new AlertDialogFragment.Builder(this);
        Bundle params = new Bundle();

        switch (view.getId()) {
            case R.id.button1:
                builder.setTitle("Title1");
                builder.setMessage("Message1");
                builder.setPositiveButton("POSITIVE", listener);
                builder.setNeutralButton("NEUTRAL", listener);
                builder.setNegativeButton("NEGATIVE", listener);

                params.putSerializable("builder", builder);

                mDialogFragment1 = new AlertDialogFragment();
                mDialogFragment1.setArguments(params);
                mDialogFragment1.setCancelable(false);
                mDialogFragment1.show(getSupportFragmentManager(), "dialog1");
                break;
            case R.id.button2:
                builder.setTitle("Title2");
                builder.setMessage("Message2");
                builder.setPositiveButton("POSITIVE", listener);
                builder.setNeutralButton("NEUTRAL", listener);
                builder.setNegativeButton("NEGATIVE", listener);

                params.putSerializable("builder", builder);

                mDialogFragment2 = new AlertDialogFragment();
                mDialogFragment2.setArguments(params);
                mDialogFragment2.setCancelable(false);
                mDialogFragment2.show(getSupportFragmentManager(), "dialog2");
                break;
        }
    }

    private class DialogButtonClickListener implements DialogInterface.OnClickListener {
        public void onClick(DialogInterface dialog, int which) {
            String dialogName = "";
            if (dialog.equals(mDialogFragment1.getDialog())) {
                dialogName = "ダイアログ1";
            } else if (dialog.equals(mDialogFragment2.getDialog())) {
                dialogName = "ダイアログ2";
            }
            switch (which) {
                case DialogInterface.BUTTON_POSITIVE:
                    Toast.makeText(getApplicationContext(), dialogName + ":POSITIVE",
                            Toast.LENGTH_SHORT).show();
                    break;
                case DialogInterface.BUTTON_NEUTRAL:
                    Toast.makeText(getApplicationContext(), dialogName + ":NEUTRAL",
                            Toast.LENGTH_SHORT).show();
                    break;
                case DialogInterface.BUTTON_NEGATIVE:
                    Toast.makeText(getApplicationContext(), dialogName + ":NEGATIVE",
                            Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    }
}
AlertDialogFragment.java
package com.example.alertdialogfragment;

import java.io.Serializable;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;

public class AlertDialogFragment extends DialogFragment {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Bundle params = getArguments();
        AlertDialog.Builder builder = (AlertDialog.Builder) params.getSerializable("builder");
        return builder.create();
    }

    public static class Builder extends AlertDialog.Builder implements Serializable {

        private static final long serialVersionUID = 1L;

        public Builder(Context context) {
            super(context);
        }

        public Builder(Context context, int theme) {
            super(context, theme);
        }

    }

}

Cancelableの設定はAlertDialog.Bulderではなく、DialogFragmentのsetCancelabre()を使うので注意です。ちょっとはまりました...
DialogFragmentを使うと画面を回転したときにダイアログを再表示してくれるので良いですね。

FragmentのsetArguments()については、ここを参考にしました。
Y.A.M の 雑記帳
Fragment で setArguments() してるサンプルが多いのはなぜ?
http://y-anz-m.blogspot.jp/2012/04/androidfragment-setarguments.html

2012年7月1日日曜日

PagerTabStripの使い方

Support Package rev.9で追加されたPagerTabStripを使ってみたのでメモしておく。


PagerTabStripはViewPagerにタブの表示を追加するものです。
スクリーンショット上部のPage1~3の部分がPagerTabStripです。
後述しますが下部に配置することもできます。
類似のものにPagerTitleStripがありますが、相違点はPagerTabStripではタブの部分をタップしてページ切り替えが可能なところです。

使い方
・ViewPagerの子要素としてPagerTabStripを配置
・layout_gravity="top"で上、"bottom"で下に表示
・PagerTabStrip#setDrawFullUnderline(true)で下線を表示
・PagerTabStrip#setTabIndicatorColor()でインディケーターと下線の色を指定

コード
activity_main.xml
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >
    <android.support.v4.view.PagerTabStrip
        android:id="@+id/pager_tab_strip"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:background="#33B5E5"
        android:textColor="#FFFFFF"
        android:paddingTop="10dp"
        android:paddingBottom="10dp" />
</android.support.v4.view.ViewPager>
MainActivity.java
package com.example.pagertabstripsample;

import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.PagerTabStrip;
import android.support.v4.view.ViewPager;

public class MainActivity extends FragmentActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
        PagerTabStrip pagerTabStrip = (PagerTabStrip) findViewById(R.id.pager_tab_strip);
        FragmentPagerAdapter fragmentPagerAdapter = new MyFragmentPagerAdapter(
                getSupportFragmentManager());

        viewPager.setAdapter(fragmentPagerAdapter);
        pagerTabStrip.setDrawFullUnderline(true);
        pagerTabStrip.setTabIndicatorColor(Color.DKGRAY);
    }

}
MyFragmentPagerAdapter.java
package com.example.pagertabstripsample;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

public class MyFragmentPagerAdapter extends FragmentPagerAdapter {

    private String[] pageTitle = {
            "Page1", "Page2", "Page3"
    };

    public MyFragmentPagerAdapter(FragmentManager fragmentManager) {
        super(fragmentManager);
    }

    @Override
    public Fragment getItem(int position) {
        Fragment fragment = new PageFragment();
        Bundle arguments = new Bundle();
        arguments.putString("pageIndex", Integer.toString(position + 1));
        fragment.setArguments(arguments);
        return fragment;
    }

    @Override
    public int getCount() {
        return pageTitle.length;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return pageTitle[position];
    }

}
PagerFragment.java
package com.example.pagertabstripsample;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class PageFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = getActivity().getLayoutInflater().inflate(R.layout.fragment_page, null);
        TextView textView = (TextView) view.findViewById(R.id.textview);
        textView.setText(getArguments().getString("pageIndex"));
        return view;
    }

}

レイアウトファイル(fragment_page.xml)のコードは割愛。
これまではViewPagerIndicatorというライブラリを使っていましたが、今後はPagerTabStripを使ってみようかなと思ってます。

ViewPagerIndicator
http://viewpagerindicator.com/

2012年6月25日月曜日

DialogFragmentメモ

Android Developersブログの記事「Using DialogFragments」を読んだのでメモ。
http://android-developers.blogspot.jp/2012/05/using-dialogfragments.html

先日、リファレンスを見ていてActivityのshowDialog()/dismissDialog()はdeprecatedなので、代わりに「DialogFragmentを使いましょう」と書いてあった。
気になっていたので、読んでみました。

このサンプル、v4 support libraryを使ってます。
1.6~2.3でもフラグメント使えるようになるアレです。
Eclipseでプロジェクトのルートフォルダを右クリックして
[Android Tools] - [Add Support Library...]
とやればOKです。
自動で
・libsフォルダの作成
・android-support-v4.jarの配置
・ビルドパスの設定
が行われます。

使い方(ざっくり)
・DialogFragmentを継承したクラスをつくる
・レイアウトはonCreateView()の中でinflate
・表示したい時は、上記のクラスをインスタンス化してshow()メソッドを呼ぶ

注意
このサンプルプログラム、IMEが「Google日本語入力Beta」だと動きませんでした...
onEditorAction()でアクションIDがIME_ACTION_DONEだったら入力内容をToastに表示してダイアログを閉じる作りですが、ログを仕込んで確認したところIME_ACTION_DONEが発生していないのが原因。
「Google日本語入力Beta」ではEnterキーをタップした時のアクションIDがIME_ACTION_UNSPECIFIEDでした。
他のIMEに切り替えたところ、問題なく動作。

感想
ブログ記事のスクリーンショットにもあるように4.xでTheme.Holoが効いているとそれなりの見栄えで表示されますが、2.xで表示するとこんな感じに...

ちゃんとレイアウトしないとダメですね。
ちょっとしたダイアログ出すのは、これまで通りAlertDialog.Builderでやろうかなぁというのが正直なところ。
とか、思ってたらこんな記事を発見!
Y.A.Mの雑記帳
「Android DialogFragment」を使うときの注意点。」
こうやって使うんですね。。
こんな有用な情報を発信できる存在でありたい...

参考
サンプルコードの閲覧・ダウンロードは下記から
dialogfragmentdemo


2012年6月24日日曜日

実機デバッグでプリファレンスの内容を確認する方法

エミュレーターはroot権限なので/data/data/パッケージ名/以下のファイルが見られますが、実機では権限が無いため見られません。
「実機でも見られたらデバッグ捗るのになぁ」というお話。

前提条件
AndroidManifest.xmlの
android:debuggableが"true"であること。
※明示的にdebuggableを指定していない場合はデバッグビルド / リリースビルドでtrue / falseを勝手に切り替えてくれる

手順
adb shell
run-as パッケージ名

ran-asコマンドにより、指定したアプリ(パッケージ名)のユーザーに切り替わるので/data/data/パッケージ名/以下が見られるようになる。
あとは、/data/data/パッケージ名/shared_prefs/以下にあるプリファレンスのxmlファイルをcatコマンドで表示すれば内容が確認できます。

注意事項
便利なrun-asコマンドですが、すべての実機で使えるわけではないようです。
以下、動作確認結果です。

[OK] Nexus S
[OK] ICONIA TAB A500
[NG] IS11LG *コマンド実行権限はあるが...
[NG] IS06 *コマンド実行権限なし
[NG] IS01 *コマンド実行権限なし

データベースも!と思ったのですが、sqlite3コマンドの実行権限が無かったり、そもそもsqlite3コマンドが無かったりでだめでした。。

2012年6月5日火曜日

GitHub for WindowsでAndroidプロジェクトをGitHubにアップする方法

1. EclipseでAndroidプロジェクトを作成
2. 作成したプロジェクトのルートディレクトリに.gitignoreファイルを配置
   ※.gitignoreファイルは下記からDLした
3. Git Shellを起動
4. 作成したプロジェクトのルートディレクトリに移動してコマンド”git init”を実行
5. GitHub for Windowsを起動
6. GitHub for Windowsのウィンドウに、作成したプロジェクトのディレクトリをドラッグ&ドロップ
7. GitHub for Windowsのlocal repositoriesを開く
8. 追加したプロジェクトを開く
9. COMMIT MESSAGEを記入して[COMMIT]ボタンを押下
10. ウィンドウ上部中央の[push to github]を押下
11. DESCRIPTIONを記入して(任意)[PUSH]ボタンを押下

12. ウィンドウ上部中央の[publish]を押下
13. ウィンドウ上部中央に”in sync”と表示されたら完了


2012年6月4日月曜日

ADT 20 Preview 3 メモ

インストール方法、リリースノートは以下から。
http://tools.android.com/download/adt-20-preview

気になった変更点
・layout editorでLint先生がグラフィカルに叱ってくれる。
・LogCatの文字色が変更可能に
設定は [Window] - [Preferences] - [Android] - [LogCat] - [Colors]
・複数デバイスに同時Deployできる。
設定はプロジェクトの
[Run As] - [Run Configurations...] - [Target]タブ - [Launch on all compatible devices/AVD's]
※実機3台繋いで試したら動いた
・今後、SDK ManagerからPreview版のSDK ToolsがDLできるようになる?
SDK Managerの [Tools] - [Options...] - [Others] - [Enable Preview Tools]

2011/05/04追記
Emulatorが起動しなくなってしまったのでATD 18に戻しました。
※症状は起動画面で固まる...
環境はEclipse3.7/Windows 7 64bitです。
Mac環境ですが、こんなIssueが上がってますね。
Issue 32577: Emulator crashes when loading with ADT 20 Preview 3
http://code.google.com/p/android/issues/detail?id=32577

2012年6月3日日曜日

スプラッシュ画面を表示する方法

Androidアプリでスプラッシュ画面を表示する方法のメモ

アプリを起動するとスプラッシュ画面(SplashActivity)を表示。
3秒後にメイン画面(MainActivity)に遷移する。
スプラッシュ画面の表示時間は
Handler#sendEmptyMessageDelayed()の第2引数で調整。
単位はミリ秒。
※LayoutのXMLとAndroidManifest.xmlの設定は割愛。

2012年5月20日日曜日

Google Play ストアの言語を切り替える方法

アプリ紹介文多言語対応確認用メモ。

https://play.google.com/store/apps/details?id=<パッケージ名>&hl=<言語コード?>

<言語コード?>の部分にアルファベット2文字のコードを入れると言語が切り替わる
例えば
ja(日本語)
en(英語)
fr(フランス語)

ただそれだけですが、忘れっぽいのでメモる...

2012年5月3日木曜日

デバッグビルドとリリースビルドで処理を変える方法(2)

デバッグビルドとリリースビルドで処理を変える方法その2です。
以前に書いた方法は以下から。

デバッグビルドとリリースビルドで処理を変える方法
http://neta-abc.blogspot.jp/2012/02/blog-post.html

ADT 17(らしい)から/genの下にBuildConfig.javaが自動生成されるようになっています。

BuildConfig.java
/** Automatically generated file. DO NOT MODIFY */
package com.example.builconfigtest;

public final class BuildConfig {
    public final static boolean DEBUG = true;
}

このBuildConfig.DEBUGはリリースビルド時(Export Signed Application Package...)に自動でfalseになってくれる仕組みだそうです。

なので、これを利用してデバッグビルドとリリースビルドで処理を切り替えることが出来ます。

BuildConfigTestActivity.java
public class BuildConfigTestActivity extends Activity {

    private final String TAG = getClass().getSimpleName();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        if (BuildConfig.DEBUG) {
            Log.e(TAG, "BuildConfig.DEBUG = true");
        } else {
            Log.e(TAG, "BuildConfig.DEBUG = false");
        }
    }
}

上記のコードでデバッグビルド/リリースビルド時にログが切り替わることを確認しています。

因みにWindows環境(のみ?)ではBuildConfig.DEBUGがリリースビルド時にfalseにならないバグがあるようです。
私の環境(Windows 7 64bit/Indigo/ADT 18)でも発生しています。
>Eclipseの[Project] -> [Build Automatically]を外すと回避できました。

Issue 27940: BuildConfig.DEBUG is "true" for exported application package
http://code.google.com/p/android/issues/detail?id=27940

2012年4月29日日曜日

Android 2.1以上でGridLayoutを使う

準備
1. Support Packageをアップデートする。(2012/4/29現在の最新は revision 8)
2. <android-sdk install path>\extras\android\support\v7\にあるライブラリプロジェクト”gridlayout”をワークスペースにインポートする。
3. GridLayoutを使いたいプロジェクトに上記のライブラリを追加する。
   [プロジェクトを右クリック] - [Properties] - [Android] - [Library] - [Add]

使用方法
<GridLayout>の代わりに<android.support.v7.widget.GridLayout>と記述する。
因みに、<Space>も使えるようになる。
<Space>の代わりに<android.support.v7.widget.Space>と記述する。
使い方の詳細は
<android-sdk install path>\extras\android\support\v7\gridlayout\README.txt
を参照。

2012年4月21日土曜日

ボタンにアイコンを表示する

レイアウトファイルで指定する方法
drawableLeft
drawableRight
drawableTop
drawableBottom
でアイコンの位置と画像を指定。

drawablePadding
でアイコンと文字の間隔を指定。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    android:orientation="vertical" >
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:drawableLeft="@drawable/ic_launcher"
        android:drawablePadding="10dp"
        android:text="drawableLeft" />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:drawableRight="@drawable/ic_launcher"
        android:drawablePadding="10dp"
        android:text="drawableRight" />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:drawableTop="@drawable/ic_launcher"
        android:drawablePadding="10dp"
        android:text="drawableTop" />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:drawableBottom="@drawable/ic_launcher"
        android:drawablePadding="10dp"
        android:text="drawableBottom" />
</LinearLayout>
コードから指定する方法
setCompoundDrawablesWithIntrinsicBounds()
でアイコンの位置と画像を指定。
引数はリソースID または Drawableで指定。

setCompoundDrawablePadding()
でアイコンと文字の間隔を指定。
単位はpx。たぶん。。
        Button button = (Button) findViewById(R.id.Button);

        int left = R.drawable.ic_launcher;
        int top = 0;
        int right = 0;
        int bottom = 0;

        // Drawable left = getResources().getDrawable(R.drawable.ic_launcher);
        // Drawable top = null;
        // Drawable right = null;
        // Drawable bottom = null;

        button.setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom);
        button.setCompoundDrawablePadding(10);

2012年3月24日土曜日

Android開発環境(再)構築メモ for Windows 7(64bit)

Android SDK r17とADT 17が公開されたので導入したら
下記のExceptionが出るようになる
「Exception while initializing java tooling」

Eclipse再インストール ※ついでなので3.6(32bit)->3.7(64bit)にバージョンアップ

3.7(64bit)起動せず ※Eclipse 64bit動かすにはJDK 64bitが必要?
「Failed to load the JNI shared library "C:\Program Files(x86)\Java\jdk1.6.0_24\jre\bin\client\jvm.dll"」

諦めて3.7(32bit)に

起動するも症状変わらず...
「Exception while initializing java tooling」

調べてみたところworkspaceが壊れてる?模様
http://www.myeclipseide.com/PNphpBB2-viewtopic-t-21638.html
既存のworkspaceをリネームしてバックアップした後
新しくworkspaceを作り直したところ復旧

バックアップしたworkspaceからプロジェクトをインポート

@Overrideアノテーションでエラー出る

調べる

解決
Window->Preferences->Java->Compiler->JDK Compliance->Compiler compliance level
1.5->1.6に変更
※参考にしたページ

Java関連の日記 - Firespeed
「@Overrideのエラーを解決してみた」


次回の再構築時にもハマりそうなので、忘れないようにメモる。


因みにEclipseの設定は下記の通り。
・Android開発向けEclipse設定メモ
http://neta-abc.blogspot.jp/2011/09/eclipse.html
・Eclipse Java ; { の入力
http://neta-abc.blogspot.jp/2011/10/eclipse-java.html

2012年2月25日土曜日

ADT 17 Preview メモ

ADT 17 Previewをインストールしてみた。
ダウンロードと変更点の詳細は↓から。

以下、気になった変更点。
Network Statistics

使い方
DDMSパースペクティブを開く
[Window]-[Show View]-[Other]を開き[Android]-[Network Statistics]を選択
Devicesから測定したいパッケージ名を選択してNetwork Statisticsの[Start]ボタンを押下

Totalは灰色、タグを設定した処理の通信量は色分けして表示される。
タグの設定方法は下記。
TrafficStats.setThreadStatsTag(0xF00D);
try {
// make network request using HttpClient.execute()
} finally {
TrafficStats.clearThreadStatsTag();
}

Proguard
設定ファイル名が変わった?
proguard.cfg → proguard-project.txt
設定ファイルが分割された?
<android-sdk-path>\tools\proguard\proguard-android.txt
Proguardの設定ファイルを読みこなせないので詳しいことはわかりません...

Lint
いろいろ変わったらしい...

Export Screenshot from the Layout Editor
Layout Editorから右クリック-[Export Screenshot...]でLayout Editor上画面レイアウトのスクリーンショットが保存できる。

Androidアプリのデフォルトアイコン
ic_launcher.pngが↓に変わった。

/res/drawable-xhdpi
新規Androidプロジェクトの作成時に生成されるようになった。

以上。

2012年2月8日水曜日

デバッグビルドとリリースビルドで処理を変える方法

2012/05/15追記
↓その2書きました。こちらの方がシンプルです。
デバッグビルドとリリースビルドで処理を変える方法(2)
http://neta-abc.blogspot.jp/2012/05/2.html

コード
MainActivity.java
public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        if (DebugUtil.isDebuggable(getApplicationContext())) {
            Log.e(getClass().getSimpleName(), "Debug Build");
        } else {
            Log.e(getClass().getSimpleName(), "Release Build");
        }
    }
}
DebugUtil.java
public class DebugUtil {
    public static boolean isDebuggable(Context context) {
        PackageManager manager = context.getPackageManager();
        ApplicationInfo info = null;
        try {
            info = manager.getApplicationInfo(context.getPackageName(), 0);
        } catch (NameNotFoundException e) {
            return false;
        }
        if ((info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == ApplicationInfo.FLAG_DEBUGGABLE) {
            return true;
        }
        return false;
    }
}

AndroidManifest.xmlのapplicationタグ内でandroid:debuggableをtrue/falseしてデバッグビルドとリリースビルドを切り替えると思っていましたが、Eclipseから実行した場合は自動でandroid:debuggable="true"となるようです。

上記コードで以下を確認しました。
・Eclipseから実行した場合
  Debug Buildのログが表示される。
・Export Signed Application Packageで作成したAPKファイルをインストールして実行した場合
  Release Buildのログが表示される。

参考にしたサイト
Tech Racho
「Androidでリリース時にデバッグログをオフにする方法」
http://techracho.bpsinc.jp/bps/2010_06_28/1946
Y.A.Mの雑記帳
「Android SDK Tools, Reviison 8」
General notes: "true debug build をサポート。..."の部分
http://y-anz-m.blogspot.com/2010/12/androidsdk-tools-reviison-8.html

2012年1月22日日曜日

Intent経由でGoogleカレンダーに予定を追加する方法

コード
Intent intent = new Intent(Intent.ACTION_EDIT);  
intent.setType("vnd.android.cursor.item/event");
intent.putExtra("title", "予定のタイトル");
intent.putExtra("description", "予定の内容");
intent.putExtra("beginTime", eventStartInMillis); //開始日時
intent.putExtra("endTime", eventEndInMillis); //終了日時
startActivity(intent);

メモ
今回の方法では
1. IntentでGoogleカレンダーの新規予定作成画面を起動
2. Intentに設定したタイトル等の情報が新規作成画面に反映される
3. ユーザー操作で登録先カレンダー変更・通知設定等を行い、予定の追加完了
という流れになります。

Intentを使わない方法と比較すると若干ユーザー操作が増えるというデメリットがありますが、下記のメリットもあるかと思います。
・予定追加の際、更にユーザーが内容を追記できる
・自分のアプリにカレンダー読み書きのパーミッションを付加しなくてもよい

開始日時/終了日時はエポックタイムで指定します。
私はCalendarクラスのgetTimeInMillis()メソッドを使用して指定しました。

因みに、「ジョルテ」がインストールされていると、Intentに「ジョルテ」も反応しますが設定した予定の情報を渡すことは出来ませんでした。
データの渡し方が分かれば「ジョルテ」にも対応できるんじゃないかと思います。

上記コードは2.2(Froyo)、4.0(ICS)で動作確認を行っています。

参考にしたサイト
自転車で通勤しましょ♪ブログ
「ANDROID:カレンダーにINTENTを発行する」
http://319ring.net/blog/archives/1596
Stack Overflow
「How to launch Android Calendar application using Intent(Froyo)」
http://stackoverflow.com/questions/4373074/how-to-launch-android-calendar-application-using-intent-froyo

2012年1月15日日曜日

AdMob 4.3.1 メモ

ライブラリ追加
プロジェクトフォルダ直下に/libsディレクトリを作成
GoogleAdMobAdsSdk-4.3.1.jarを/libsディレクトリへコピー
Java Build PathのAdd JARs...から上記ライブラリを追加

AndroidManifest.xml
パーミッションの追加
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Activityの追加
<activity
android:name="com.google.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" />
↑Project Build Targetを3.x以上?にしないと使えないパラメータが入っているので必要に応じてTarget SDK Versionを上げる

layoutファイル
    <com.google.ads.AdView
        android:id="@+id/adview"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        ads:adSize="BANNER"
        ads:adUnitId="パブリッシャーID" />

コード
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mAdView = (AdView) findViewById(R.id.adview);
        AdRequest adRequest = new AdRequest();
        adRequest.addTestDevice(AdRequest.TEST_EMULATOR); //テスト用バナーを表示する
        mAdView.loadAd(adRequest);
    }

    @Override
    protected void onDestroy() {
        mAdView.destroy();
        super.onDestroy();
    }
上記コードを実行するとLogCatに I/Ads(32576): To get test ads on this device, call adRequest.addTestDevice("*****..."); なログが出るので#addTestDeviceのAdRequest.TEST_EMULATORを*****...に置き換える これにより、開発者向けテスト用のバナーが表示されるようになる