2012年12月18日火曜日

[Android]アプリ内課金実装バージョン3リリース

アプリ課金のバージョン3がリリースされました。

In-App Billing Version 3  - Android Developer Blog -
http://android-developers.blogspot.jp/2012/12/in-app-billing-version-3.html

・より簡単に
 実装するのが簡単になりました。

・ローカルキャッシュ
 課金した情報をキャッシュすることができます。
 課金情報を非同期で確認しなくても良くなった。

・製品情報(課金アイテムの情報)
 課金アイテムのタイトルや金額(ロケールされた)を取得できる

・サンプルアプリケーション
 サンプルアプリが更新されました。

・アプリ鍵
 V3からアプリ単位で公開鍵




2012年12月9日日曜日

[Android]HTML5のvideoタグの罠

WebView使ってHTML5のvideoタグを表示した時の動作にはまってしまったので、メモ。

Android 2.x
Videoタグをタップすると、ビデオビューが起動して全画面で再生

Android3.x
Videoタグをタップすると、ビデオビュー起動せず、ブラウザ内でインライン再生
コントロールの全画面押したときだけ、ビデオビュー起動して全画面で再生

もともとAndroid 2.xで動作確認していて、
Android4.0で動かすとぜんぜん動作違っていて困った。



2012年12月7日金曜日

[Android]アプリケーションのキャッシュに保存する

アプリで取得したデータを永続的にキャッシュしておきたい場合には、
アプリケーションのキャッシュに保存しておきましょう。

Context.openFileInput()

http://developer.android.com/reference/android/content/Context.html#openFileInput(java.lang.String)

使い方1:データ読み出し
InputStream in = context.openFileInput("saveData");

使い方2:画像読み出し

FileInputStream is = context.openFileInput(dataName);
Bitmap image = BitmapFactory.decodeStream(is);
is.close();



Context.openFileOutput()

http://developer.android.com/reference/android/content/Context.html#openFileOutput(java.lang.String, int)

使い方1:データ保存
FileOutputStream os = context.openFileOutput("saveData", Context.MODE_PRIVATE);

int DEFAULT_BUFFER_SIZE = 1024 * 4;
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int n = 0;
while (-1 != (n = in.read(buffer))) {
os.write(buffer, 0, n);
}
os.close();


使い方2:画像保存

FileOutputStream os = context.openFileOutput(dataName, Context.MODE_PRIVATE);
ret = image.compress(Bitmap.CompressFormat.PNG, 100, os);

os.cloase();


永続的でなく一時的に保存したい場合は、こちらに保存するのもアリです。
Context.getCacheDir()
http://developer.android.com/reference/android/content/Context.html#getCacheDir()

ファイル容量少なくなると、システムがファイル消してしまうので、その点のみ注意。

2012年12月4日火曜日

[Android]ダイアログ作成コピペ

ダイアログ作成処理をActivityのライフサイクルに乗せる用のコピペ。
自分でダイアログ表示してもいいですが、メモリリークするので、
ライフサイクルに乗せた方がベターです。


==============
Before
==============
// メソッド呼ばれたらその場でダイアログ表示する
    private Dialog createErrorDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(R.string.dialog_title)
            .setMessage(R.string.dialog_message_error)
            .setPositiveButton(R.string.dialog_button_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(which == DialogInterface.BUTTON_POSITIVE) {
dialog.dismiss();
}
}
});
        builder.create().show();
    }
==============


==============
After
==============
final int DIALOG_ERROR_1 = 1;
    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
        case DIALOG_ERROR_1:
            return createErrorDialog();
        default:
            return null;
        }
    }

// メソッド呼ばれたら、Dialog作成
    private Dialog createErrorDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(R.string.dialog_title)
            .setMessage(R.string.dialog_message_error)
            .setPositiveButton(R.string.dialog_button_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(which == DialogInterface.BUTTON_POSITIVE) {
dialog.dismiss();
}
}
});
        return builder.create();
    }


// ボタンクリックされたら、ダイアログ表示
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// ダイアログ表示
showDialog(DIALOG_ERROR_1);
}
});

2012年12月3日月曜日

[Android]着信音ダイアログを表示する


着信オンダイアログを表示する方法
Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
startActivityForResult(intent, REQUEST_CODE_RINGTONE_PICKER);




選択結果はonActivityResultで受け取ります。


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
    if(requestCode == REQUEST_CODE_RINGTONE_PICKER ){
        if(resultCode == RESULT_OK){
            Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
            if(uri != null) {
                ringtone = RingtoneManager.getRingtone(this, uri);
                if(ringtone != null) {
               uri.toString();// 着信音のパス
               ringtone.getTitle(this);// 着信音の名前
                }
            } else {
                // サイレント
            }
        }
    }
}