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 {
                // サイレント
            }
        }
    }
}

2012年11月28日水曜日

[Android]ImageViewの後始末

ImageViewは画像を表示するのに使いますが、
終了時にちゃんとメモリ解放処理いれてあげないと、
大きい画像を扱ったりすると、すぐにメモリ不足おきてしまいます。

使うとき

imageView.setImageResource(resId);
imageView.setImageBitmap(bitmap);
imageView.setImageDrawable(drawable);


使い終わったとき
void cleanup(ImageView view) {
    d = view.getImageDrawable()
    d = null;

    if(bitmap != null) {
        if(!bitmap.isRecycle()) {
            bitmap.recycle();
        }
        bitmap = null;
    }

    imageView.setImageDrawable(null);

    view.setOnClickListener(null);
}



2012年11月26日月曜日

[Android]metaio SDK 3.0 → 4.0にバージョンアップ

metaio Mobile SDK のバージョン4がリリースされました。

というわけで、
SDKを入れ替えましたが、大幅に変わっているので、注意点をいくつか。

1.metaio Mobile SDK がない!?

Download Center に行くと、
metaio Mobile SDK 4.0 が見当たりません。

metaio SDK v4.0.2に統合されたようです。
こちらをダウンロードしましょう。


2.jarの名前が変わっている

jar の名前がmetaiomobilesdk.jar からmetaiosdk.jar になっています。
metaiomobilesdk.jar をビルドパスから外しましょう。
それから、metaiosdk.jar をビルドパスに追加しましょう。


3.クラス名が大幅に変わっている

ARViewActivity.java で使用していた様々なクラス名が変更されています。
一つずつ置き換えていきましょう。


4.シグネチャの変更が必要。

metaio Developer Console でシグネチャ登録しましたが、
4.0 に変更した場合、再度シグネチャを取得する必要があります。


5.トラッキングデータの変更


今までのも使えますが、ここも名前が変わっています。

2012年11月25日日曜日

[Android]トレーニング

Android公式でトレーニングなる項目を見つけた。
いろんなサンプルコードを解説してくれてます。
http://developer.android.com/intl/ja/training/index.html

2012年11月22日木曜日

[Android]SQLiteOpenHelperでDBバージョンを上げる時に、列を追加する方法


SQLiteOpenHelperでDBバージョンを上げる時に、列を追加する方法です。

onUpgrade()で古いバージョン、新しいバージョンが分かるので、
古いバージョンのときに処理を行うようにします。
(今回の場合は、1 -> 2にバージョン上げたと仮定します)

db.execSQLで、
列追加のSQLコマンドを実行すればOK。

ALTER TABLE テーブル名 add 追加する列名 型名


@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
try {
if(oldVersion == 1) {
db.execSQL( "ALTER TABLE " + DB_TABLE_NAME + " add " + ADD_COLUM_NAME + " TEXT;");
}
} catch (Exception e) {
e.printStackTrace();
}
}



2012年11月21日水曜日

[Android]WebView の背景を透過する方法

WebViewの背景を透過する方法です。

HTMLで以下のように指定しても、透過されません。
<body style="background-color:transparent;">


WebView に以下のようにセットしましょう。
webView.setBackgroundColor(0);


2012年11月20日火曜日

[Android]TextView に使用できるHTMLタグ一覧

TextView にHTMLタグありの文字列をセットすると、
リンクや文字色などを設定することができたりします。

String html_source;
textView.setText(Html.fromHtml(html_source);

しかし、
すべてのHTMLタグが使える訳ではないです。

使用できるタグはここ参照。
http://commonsware.com/blog/Android/2010/05/26/html-tags-supported-by-textview.html


<a href="...">
<b>
<big>
<blockquote>
<br>
<cite>
<dfn>
<div align="...">
<em>
<font size="..." color="..." face="...">
<h1>
<h2>
<h3>
<h4>
<h5>
<h6>
<i>
<img src="...">
<p>
<small>
<strike>
<strong>
<sub>
<sup>
<tt>
<u>




<a>タグでリンク張り、ブラウザ起動させたい場合は、以下の設定も必要です。

MovementMethod movementmethod = LinkMovementMethod.getInstance();
textView.setMovementMethod(movementmethod);



2012年11月19日月曜日

[Android]WebViewのloadDataで文字化け

ここが参考になりました。
http://d.hatena.ne.jp/paraches/20120819



loadDataWithBaseURL(null, html, "text/html", "utf-8", null)
loadData(html, "text/html; charset=utf-8", "utf-8")

2012年11月17日土曜日

[Android]AES復号化処理でBadPaddingException

サーバで暗号化した文字列を
アプリで復号化しようとした際にはまったので、メモ。



SecretKey key = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] encrpytText = cipher.doFinal(encryptCode);


最後のdoFinal()で
BadPaddingException: pad block corrupted.

が発生します。


そんなあなたに、

暗号化キーと復号化キーは同じですか?


http://stackoverflow.com/questions/12110459/android-des-decrypt-badpaddingexception-pad-block-corrupted

2012年11月16日金曜日

[Android]selectorをJavaで書く

selector使うと、
ボタン押したときの画像を変更できたりします。
とても、便利。


今回は、
XMLで定義しないで、プログラム上でselectorを行う方法です。


使うのは、StateListDrawableクラス。

http://developer.android.com/intl/ja/reference/android/graphics/drawable/StateListDrawable.html


使い方

        Drawable iconOn = /* Drawble 作成する */;
        Drawable iconOff = /* Drawble 作成する */;
        
        // StateListDrawable に状態と表示するDrawable をセット
        StateListDrawable d = new StateListDrawable();
        d.addState( new int[]{ android.R.attr.state_selected }, iconOn );
        d.addState( new int[]{ -android.R.attr.state_selected }, iconOff );


状態は、
new int[] { android.R.attr_state_xxxxx}
という形で指定します。

状態が無効のときは、マイナスを付ける
new int[] { -android.R.attr_state_xxxxx}

あとは、Viewにセットするだけです。


2012年11月14日水曜日

[Android]画面解像度の違い

ldpi、hdpi、mdpi、xdpi などありますが、
それぞれいったい画面サイズはいくつなのさ?


という訳で公式サイトにありました。
http://developer.android.com/intl/ja/guide/practices/screens_support.html#testing


2012年11月13日火曜日

[Android]APIレベル一覧

APIレベルが分からなくなってしまうので、Android公式ページで探してきた。

http://developer.android.com/intl/ja/guide/topics/manifest/uses-sdk-element.html#ApiLevels




ついでに現在のOSシェア、画面解像度の割合とかもあった。
グラフでみやすい。
http://developer.android.com/intl/ja/about/dashboards/index.html


2012年11月12日月曜日

[Android]Android開発グッズ(リール式USBケーブル)

Android開発で役立つアイテムを紹介します。




リール式USBケーブル。

端末付属のUSBケーブルでもよいですが、
100均で売られているリール式USBケーブルをおすすめします。

お勧めポイント
・安い
・ケーブルが細い
・リール式なので机の上がすっきり。



リール部分は壊れやすいのが難点ですが、
壊れたらリール部分をはずしておくとかさばらなくてよいです。


ぜひ。

2012年11月10日土曜日

Androidアプリ開発用に所有している端末リスト(2012)

Androidアプリの開発していると気づいたら、端末増えてきたのでまとめてみます。



1.au ISW11HT (HTC)

http://www.au.kddi.com/seihin/archive/kishu_archive.html?id=isw11ht


初めて購入したAndroid。私物です。
au初の WiMax + Wifiテザリング が魅力。
どこでもルータ代わりになって便利。
OSは購入時は、2.2。 今は、 2.3 にバージョンアップしてます。


2.docomo Galaxy Nexus SC-04D (SamSung)




4.0が普及し始めて、2.xのみでは動作確認が厳しくなってきたので、Amazonで購入。

docomo GALAXY NEXUS SC-04D チタンシルバー SAMSUNG Android4.0搭載 スマートフォン 白ロム 携帯電話本体標準セット

・Google標準機なので、基本こちらで動作確認。
・HTCと解像度異なるので、レイアウトの調整にも使ってます。
・NFCが付いてるので、それ使った開発もそのうち。



3. SIMフリー Xperia Play (SonyEricsson)

http://www.sonymobile.co.jp/product/docomo/so-01d/
楽天かAmazonで購入。

ギャラリー周りの動作確認で、ソニエリ端末が欲しかった。
Playにしたのは、形状変わっているのが理由。
OSは、2.3。
解像度は、HTCと同じなので、
HTCをルータと使ってる間の代替端末。

ゲームもできるよw


4. docomo Galaxy Tab 10.1 LTE SC-01D (SamSung)



Amazonで購入。ケース付けてくれた。ラッキー。
docomo GALAXY Tab 10.1 LTE SC-01D

初のタブレット。OSは3.2。
ソニタブとは迷った。Galaxyにしたのは、Google公認なのと値段。

レイアウト確認がメイン。
解像度違うと、レイアウトが崩れる崩れる。。

4.0にバージョンアップできるけど、現状維持。


5. au IS05 (Sharp)

http://www.sharp.co.jp/products/is05/

即日発送!新品 IS05 グリーン×ブラック 携帯電話 白ロム au

とあるアプリで不具合報告あって、
手持ちの端末で発生しなくて、オークションで5000円くらい購入。

結局再現できなかったですけど。

OSは2.2。
スペックが貧弱なので、メモリ不足の動作確認で。
あと、Felica搭載端末なのが魅力です。


6. au SIRIUS α IS06 (PANTECH)

http://jp.pantech.com/products/siriusis06.html


au IS06  チャコールブラック


家族が機種変したので、貰った。
OSは2.2。
2.3にバージョンアップ出来るけど、現状維持。

電池が膨らんでて、危険。。


7. au iPhone4S (Apple)

http://www.apple.com/jp/iphone/iphone-4s/specs.html

新品 iPhone 4S 16GB ホワイト au 白ロム MD240J/A

iPhoneアプリからAndroidへの移植案件が重なって、
画面イメージだけだと詳細まで確認できないため、購入。
オークションで。

iPhoneはiPhoneの
AndroidはAndroidの良さがそれぞれあるなと実感。



------------
という訳で現在は、iPhone含めて7台所有。

メインは、Galaxy Nexus と Xperia Play。
ルータとして、ISW11HT。


OS内訳
1.6 ・・・ なし
2.1 ・・・ なし
2.2 ・・・ 2台(IS05、IS06)
2.3 ・・・ 2台(PLAY、ISW11HT)
3.2 ・・・ 1台(SC-01D)
4.0 ・・・ 1台(SC-04D)
4.1 ・・・ なし
4.2 ・・・ なし


今すぐ、買うつもりはないけど、
次は、
4.xのタブレット端末
4.1のスマートフォン
かな。

メーカーは、悩みどころです。
ARROWS、MEDIASは一台は持っておきたいところ。

NEXUS 7が欲しい。

iPhone 5も欲しい。

Windows Phone 8も欲しい。

我慢、我慢。

2012年9月25日火曜日

[Android]startActivityForResultでカメラ起動後、アプリに戻ると変数の値がnullになってる現象

タイトル長くて分かりにくいですが、、

startActivityForResult でカメラ起動する
変数に値を保持。



カメラ撮影



onActivityResult でアプリに戻ってくる
変数の値がnullになっている



のような現象が発生しました。

スマートフォンで発生せず、タブレットで発生。
・スマートフォン(SC-04D、ISW11HT)
・タブレット(SC-01D)



ソース1:カメラ起動する


ContentValues values = new ContentValues();
   values.put(MediaStore.Images.Media.TITLE, filename);
   values.put(MediaStore.Images.Media.MIME_TYPE, Const.MIMETYPE_PNG);
   mImageUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
 
   // カメラ起動
Intent intent = new Intent();
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
startActivityForResult(intent, Const.REQUEST_CODE_CAMERA);

mImageUriにカメラ撮影したデータを保存するもらう。


ソース2:カメラからの戻り処理

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

if(resultCode == RESULT_OK) {
Intent intent;
// カメラからの戻り処理
if(requestCode == Const.REQUEST_CODE_CAMERA){
Log.d(tag, mImageUri);
}
}
}
カメラから戻ったら、mImageUriをログ出力。




[原因]

タブレットを傾けていたのが、よろしくなかった模様。

カメラ起動元の画面はマニフェストで縦固定の指定をしていた。
android:screenOrientation="portrait"

カメラ起動後、縦⇔横回転が行われていたようで、
アプリに戻ってきたときに横 → 縦の処理が行われ、画面の再作成した。(と思う)
ここで変数が初期化されてしまった。


[対策]
マニフェストに以下を記述。
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|fontScale"

端末回転しても画面破棄しないようにする。
(orientationだけでいいんだけど、全部指定してみた)



2012年9月19日水曜日

[Android]動くジョジョ風ランチャーウィジェット2をリリースしました

動くジョジョ風ランチャーウィジェット2をリリースしました。
1とは別アプリとして動作します。

1ではなかったユーザーさんが好きな文字を入力できる機能を実装。

こんな風に文字入力できます。



ウィジェットとして設定するとこんな感じです。


お試しあれ。

https://play.google.com/store/apps/details?id=com.gettingsignals.android.JoJoLauncher2

2012年9月12日水曜日

[Android]アプリ内課金の銀行口座にデポジットされない問題→解決

Androidでアプリ内課金機能を実装する場合、
売り上げを入金してもらうための銀行口座が必要になります。

Google checkout から「設定」-「財務情報」から銀行口座を入力するわけですが、
https://checkout.google.com/sell/

Googleさんからテストデポジットがされなかったときの対処方法です。


私の使ったのは楽天銀行さんです。

銀行口座に以下の情報を入力します。
タイプ:Futsuu
銀行名:Rakuten Bank
口座名義:半角カタカナ(姓名の間スペース、小文字は大文字に)。※ローマ字ではない
銀行コード:0036
口座番号:xxxxxxx
支店番号:zzz


初めに登録したとき、
1ヶ月経ってもデポジットされず、デポジット失敗のメールも来なかったので、
サポートセンターから問い合わせしました。(英語のみ)

http://support.google.com/checkout/sell/bin/request.py?contact_type=payouts&from=vba

フォーム入力して、Submit押すと数日後にメール来ます。
※Submit押しても受付完了メールとか来なくて、何回もしてしまった。。


口座名義のところをローマ字で入力してしまってたので、修正したい旨を連絡。
銀行名も間違ってた。Rakuten KC にしてたorz
※カード見ながら入力するとこうなる


正しく入力し直して、1週間経過。

以前、Adsenseのデポジットされていたので、試しに入力するもNG。
3回やってアカウントロック。しまった!

もう一度問い合わせ。
・一週間経ってもデポジットされない。
・アカウントロックされちゃった。

Google「今日デポジットしたよー」

翌日にデポジット確認。



勉強になったこと。
・Adsenseのデポジットとは別。
・入力するときはここも参照。
http://support.google.com/adsense/bin/answer.py?hl=ja&answer=1316748#n4
・デポジットは1週間は待ってみること。
・デポジット失敗してもメールは来ない?
・なんでデポジットされなかったのかの原因は不明。


Adsense と違って、checkoutは銀行口座が認証されないと変更できないので注意

2012年9月7日金曜日

[Android]広告(adstir)をFragment化してみた

nendさんに続いて、お次はAdStirさんです。
http://ja.ad-stir.com/

AdStirさんは複数の広告ネットワークを自動で配分してくれます。


Android 2.xでも使えるように、Android Support Package v4使ってます。

libsフォルダadstir.jar を追加し、ビルドバスに追加


AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
 ・・・・>
   <meta-data android:name="ADSTIR_APP_ID" android:value="MEDIA-xxxxxxx" />
</application>



main.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<fragment
  android:id="@+id/fragmentAd"
   android:name="com.package.Sample.AdstirFragment"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:layout_alignParentBottom="true"
   />
</RelativeLayout>



AdstirFragment.java
public class AdstirFragment extends Fragment {  
AdstirView adView;
public AdstirFragment() {
}
    
    @Override  
    public View onCreateView(LayoutInflater inflater,  
            ViewGroup container, Bundle savedInstanceState) {  
        
    adView = new AdstirView(getActivity(), 1);
return adView;
    }
    
    @Override
    public void onResume() {
   super.onResume();
   adView.start();
}
 
@Override
public void onPause() {
   super.onPause();
   adView.stop();
}


    @Override
    public void onDestroy() {
        super.onDestroy();
        new AdstirTerminate(getActivity());
    }
}

onResume() / onPause() でstart / stop の処理が必要。
これでいいのかな、Fragment使いこなすにはもう少しかかりそう。

[Android]広告(nend)をFragment化してみた

とあるアプリをタブレット対応したので、ついでに広告処理もFragment実装してみました。

使用したアドネットワークは、nendさん。
https://www.nend.net/


libsフォルダにnendSDK-1.2.1.jarを格納し、ビルドパスに追加

AndroidManifest.xml

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
追記。


main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" >
<fragment
  android:id="@+id/fragmentAd"
   android:name="com.sample.package.NendFragment"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   />
</RelativeLayout>



NendFragment.java
public class NendFragment extends Fragment implements NendAdListener {  
private static final int SPOT_ID = ****** 発行されたSPOT ID ******;
private static final String API_KEY = "******** 発行されたAPI KEY *********";
public NendFragment() {
}
    
    @Override  
    public View onCreateView(LayoutInflater inflater,  
            ViewGroup container, Bundle savedInstanceState) {  
        
    NendAdView adView = new NendAdView(getActivity().getApplicationContext(), SPOT_ID, API_KEY);
    adView.setListener(this);
return adView;
    }

@Override
public void onFailedToReceiveAd(NendAdView arg0) {
}

@Override
public void onReceiveAd(NendAdView arg0) {
}
}


Fragment化しておけば、レイアウトファイルに追加するだけでいいから便利ですねー。

2012年8月29日水曜日

[Android]FaceDetectorを使う


画像から顔を検出する方法です。

FaceDetectorは、Android4.0から使用可能。


final int MAX_FACES = 4;

// Config.RGB_565で画像作成
Bitmap temp = Bitmap.createBitmap(width, height, Config.RGB_565);
Canvas canvas = new Canvas(temp);
canvas.drawColor(0x00000000);
canvas.drawBitmap(bmp, 0, 0, new Paint());
canvas.save();


Face[] faces = new Face[MAX_FACES];
FaceDetector detector = new FaceDetector(temp.getWidth(), temp.getHeight(), MAX_FACES);
int numFaces = detector.findFaces(temp, faces);

if(numFaces > 0) {
    // 認識した数だけ処理
    for (int i = 0 ; i < numFaces ; i++) {
        Face face = faces[i];
       
        // 顔認識結果を取得
        face.getMidPoint(midPoint);        // 中心座標を取得
        eyesDistance = face.eyesDistance();    // 目の間隔を取得
    }
}


画像は、Config.RGB_565 にしないと、
顔検出時にエラーになります。

取得できる特徴点が少ない。。

2012年8月28日火曜日

[Android]AES暗号化と復号化

Android側で暗号化したデータをサーバに送信し、
サーバ側(php)でデータを復号を行ったときのメモ。


Androidアプリ


String encodeKey = "YOUR_ENCODE_KEY";
String value = "ENCODE_VALUE";

// キー生成
SecretKey key = new SecretKeySpec(encodeKey.getBytes(), "AES");
// 初期化
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
// エンコード処理
byte[] encryptBin = cipher.doFinal(value.getBytes());
// BASE64に変換
String encodedValue = new String(Base64.encode(encryptBin, Base64.DEFAULT));




サーバ(PHP)



function mc_decrypt($decrypt) {
$mc_key = 'YOUR_ENCODE_KEY';
$decoded = base64_decode($decrypt);
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB), MCRYPT_RAND);
$decrypted = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $mc_key, trim($decoded), MCRYPT_MODE_ECB, $iv));
    return rtrim( pkcs5_unpad($decrypted) ); } function pkcs5_unpad($text) { $pad = ord($text{strlen($text)-1}); if ($pad > strlen($text)) return false; if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false; return substr($text, 0, -1 * $pad); }



2012年8月7日火曜日

[Android]metaio Mobile SDKのアプリ登録方法

metaio Mobile SDKのサンプルから自分用のアプリを作成するために、
パッケージ名を変更すると、以下のようなログが出力されてしまいます。


Could not verify the application name <package name>. Please check docs.metaio.com for more details.
License check failed
License was not valid
Error createing unifeye mobile: null


ライセンスエラー、認証エラーですね。。

この認証チェックですが、どこを見ているのかというと、
Configuration.java のsignatureという値を見ているようです。

public static final String signature = "Ig1hNdxRO52rNP9Qn1NPz13pGkIoXjHxgclAV26cEFI=";

このシグネチャーをどうやって取得すればいいかというと、
metaio Developer Portal から取得できました。
https://mobiledeveloperportal.ar-live.de/index.php?


ログインすると、
・Application Name
・Application ID
を入力すると、signatureを生成してくれるので、
Configuration.java のsignatureを書き換えると認証OKとなります。
※Application IDはパッケージ名を入力


参照
http://docs.metaio.com/bin/view/Main/ApplicationSignature

2012年8月6日月曜日

[Android]マーカーレスARライブラリ比較

マーカーレスARを実現するために必要なライブラリをまとめてみました。


・SATCH SDK

 http://satch.jp/jp/
 ・・・KDDIが運営しているARライブラリ。
   開発ガイド、APIリファレンス、サンプルなど資料が豊富。
   アプリ作成には開発者登録、アプリ登録が必要。
   資料はすべて日本語。


・metaio Mobile SDK


 http://www.metaio.com/software/mobile-sdk/
 ・・・英語。
   JARを追加するだけで利用可能。
   トラック画像(認識するための画像)もプロジェクト内に登録するだけで可能。
   無料版ではカメラビューに透かし画像が表示される。

・Vuforia

 http://www.qualcomm.com/solutions/augmented-reality
 ・・・Qualcommの提供するARライブラリ。英語
   ビルドにはAndroid NDKが必要。
   トラックデータはウェブサイトにて登録・取得。
   単純なトラック画像では認識率が悪い(登録時に確認可能)


・OpenCV

 http://opencv.jp/
 ・・・オープンソースライブラリ。
   画像認識・変換などが行える。
   認識率はmetaio や Vuforiaより劣る。
   Android NDKが必要。




SATCHは日本語が充実していて、開発ツールも用意されているので、初めての人でもとっつきやすそう。
(あまりさわったことないので、詳細不明。)


metaio Mobile SDKは、
JARファイルを追加するだけの簡単設計。
Android NDKが不要な点が利点。
無料版はスプラッシュ画像、カメラビューに透かしが表示される。
トラックデータや、3Dモデルもxmlに追加するだけ。
フォーラムありますが、情報が英語しかないので、ちょっとつらい。
日本語の情報も少なめ。


Vuforiaは、
Android NDKが必要な点がハードル高め。
トラック画像を選ぶのが難点。(画像によっては認識率悪い。サイト側で登録できない。。)
トラックデータはサイトから取得しないと行けない。


OpenCVは、
画像認識部分を利用。
簡単にトラック画像を登録できますが、認識速度、認識率が悪い。
Android NDKが必要な点がハードル高め。
3Dオブジェクトの表示部分は自分で実装必要??

[Android]ARライブラリ「vuforia」のサンプル実行

QualcommさんのARライブラリの名称がいつの間にか「QCAR」から「Vuforia」に変わっていたので、
改めてサンプル実行してみました。
追加された2つのみ。

Vuforiaの環境設定などは以前の記事を参照のこと。
Getting Signals: Android NDK環境構築
Getting Signals: Qualcom「QCAR」のサンプル実行
Getting Signals: Qualcomm「QCAR」のImageTargetsの認識画像を ...
Getting Signals: Qualcomm「QCAR」のImageTargetsの表示画像を ...



BackgroundTextureAccess
背景がグレースケールで表示される。
タッチすると背景が歪む。


・OcclusionManagement
6面体を認識


組み立てて認識すると...もっと分かり易くなるはず。

2012年8月3日金曜日

[Android]OpenCVの環境構築とndk-build


Android NDK関連の記事はMacやLinuxベース名ことが多いので、
Windows環境では少々困ることがあるので、備忘メモ。

@ITさんの「オープンソースの「OpenCV」で画像認識しよう」を参考に。
http://www.atmarkit.co.jp/fsmart/articles/armobile06/01.html

環境構築は↓を参考に。
http://www.kosaic.jp/wordpress/2011/08/opencv4android-2-3-1beta2-%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E6%89%8B%E9%A0%86%EF%BC%88%E7%94%BB%E5%83%8F%E4%BB%98%E3%81%8D%EF%BC%89/
Cygwin
c:\Cygwin

OpenCV
OpenCV-2.3.1-android-bin.tar.bz2
SDKと同じ場所に解凍
i:\Development\に解凍
同じ階層に
i:\Development\android-sdk-windows
i:\Development\OpenCV-2.3.1
i:\Development\samples


Android NDK r8b
android-ndk-r8b-windows.zip


c:\r8bに解凍



PC環境
Wndows Vista 32bit Ultimate


環境変数に設定
c:\Cygwin\home\[ユーザー名]\.bashrcの末尾に


export ANDROID_NDK_ROOT=/cygdrive/c/r8b
export PATH=$ANDROID_NDK_ROOT:$PATH


を追記

sampleをndk-buildする

i:\Development\samples\tutorial-3-native
をeclipseにインポート

cygwinから
cd cygdrive/c/Development/samples/tutorial-3-native

ndk-build

プロジェクトをリフレッシュして、実行


@ITのサンプル(detect_image_sample)をndk-buildする

detect_image_sample.zipを↓に解凍
i:\Development\samples\detect_image_sample

eclipseにインポート

OPENCV_MK_PATHの設定を変更
Android.mk内の

include $(OPENCV_MK_PATH)



include ../includeOpenCV.mk
ifeq ("$(wildcard $(OPENCV_MK_PATH))","")
#try to load OpenCV.mk from default install location
include $(TOOLCHAIN_PREBUILT_ROOT)/user/share/OpenCV/OpenCV.mk
else
include $(OPENCV_MK_PATH)
endif

に変更。




cygwinから
cd cygdrive/c/Development/samples/detect_image_sample


ndk-build


プロジェクトをリフレッシュして、実行


2012年7月31日火曜日

[Android]動くジョジョ風ランチャーウィジェットをリリースしました

ジョジョスマフォ(L-06D JOJO)の発売を記念して、
ジョジョ風ランチャーウィジェットをリリースしました!


動くジョジョ風ランチャーウィジェット
https://play.google.com/store/apps/details?id=com.gettingsignals.android.JoJoLauncher







2012年7月23日月曜日

[Android];Dcloudを組み込む(挫折)

;Dcloudとは、
デコメ素材を提供するプラットフォームです。
http://dcloud.jpn.com/?lang=ja



SDKも提供されていて(開発者登録必要)、
ちょっと使ってみようと思ったのだけど。。。

[挫折1]
開発者登録。
作成したアプリのURLを記述する欄が存在する。(入力必須)
→まだ作成していないんだけど;


[挫折2]
以下のアプリをインストールしたのだけど、
https://play.google.com/store/apps/details?id=com.jpn.dcloud.baseapp

EmojiUtil.isInstalledDcloudApp() で falseが返ってくる

→インストールするアプリを間違えているのか??
 インストールしないといけないアプリへの導線を作って欲しい。


[挫折3]
ベースアプリのチェックを無視して、
EmojiUtil.startDcloud()を呼び出そうとしたんだけど、
パラメータのAPP_IDが何をさしているのか分からない。
開発者登録時に発行されたIDみたいなんだけど、”application ID”なるものが分からない。

→ユーザーIDか??

 ドキュメントに記述して欲しい。



[挫折4]
ひとまず絵文字パレットを表示させようと思ったのだけど、
EmojiPaletteViewのコンストラクタのパラメータの int titlePositionに設定する値が分からない。
→サンプルコードはあるんだけど、レイアウトから作成するものしかなくて、
 しかもそちらのパラメータにtitlePositionの指定はない。
 intだけでは何の値を指定すればいいのか分からない。
 サンプルコードを増やして欲しい。 or ドキュメントに詳しく


私にはハードルが高かったのか。。

[Android]旅宿アプリを「@アプリ」様にレビュー頂きました。

ソフトバンクモバイル様運営のAndroidアプリレビューサイト「@アプリ」にて、
旅宿アプリをレビュー頂きました!

http://app.ent-ext.mb.softbank.jp/promotion/appli/indivisual/appli_2549/
SBスマフォからでないと見れないのが、残念ですが。




取り上げていただけるのは、嬉しいですね。

2012年7月20日金曜日

[Android]GestureLockerアプリをリリースしました

GestureLocker(ジェスチャーロッカー)は、
ジェスチャー操作で端末のロックを解除することができるロックアプリです。



ロック中の画面。
画面下部に設定中のジェスチャーと対応するアプリが交互に表示されます。
解除方法は画面に指でタッチして特定のジェスチャーを描くだけ。

対応するアプリが表示されているところ。


ジェスチャーが表示されているところ。  

 交互に表示されます。


設定画面からジェスチャーとアプリの組み合わせを変更できます。


Google Playからダウンロードできます。
https://play.google.com/store/apps/details?id=com.gettingsignals.android.GestureLocker

[Android]アプリ内課金の売り上げ情報を確認する

GestureLockerというアプリでアプリ内課金を実装したので、
売り上げ情報を確認しようとしたときに困ったのでメモ。

有料アプリの場合だと、購入から15分はユーザーがキャンセルすることができますが、
アプリ内課金は即時決済となっています。

ユーザーはキャンセルする場合は、デベロッパーにキャンセルリクエストを行うことができますが、
デベロッパーが承認・キャンセル処理を行わないと返金はされません。

分からなかったのは、
デベロッパーにキャンセルリクエストが届いたときに、
”承認・キャンセル処理”の実行の方法です。

Google checkoutからできるらしいというのは分かったのですが、
自分の購入情報しか表示されず・・・。


ヘルプをよーく見てみると、
「Google checkoutの販売者アカウントで・・・」と記載があります。

販売者アカウントにアクセスしないといけないのです。

というわけで、
https://checkout.google.com/sell/
にアクセスすると売り上げ情報が見れました。

Androidレビューサイトまとめ(2012/07/20)

Androidアプリをリリースしたときのレビュー依頼するためのメモ。


アンドロイダー
http://androider.jp/
専用フォームから→https://secure.androider.jp/mailform/review_index.html

Androreview(アンドロレビュー)
http://androreview.com/
メール


オクトバ
http://octoba.net/
専用フォームから→http://octoba.net/contact

オクトバタウン
http://octoba.net/town/
専用フォームから

アンドロイドール
http://androidoll.com/
専用フォームから。

meetroid
http://www.meetroid.com/
メール

アプリゲット
http://appget.com/
ログイン後、専用フォームから

aivie
http://aivie.jp/pc/index.html/
ログイン後、専用フォームから

Androidapps100
http://android-100.com/
専用フォームから

2012年7月17日火曜日

[Android]WebViewのloadDataで文字化けしてしまう対処

WebViewで簡単なhtmlを表示したい場合に、プログラム上でhtmlを書いてしまいたいことがあります。
(assetsにhtml用意したりしない)

そのときに、
WebView.loadData(String data, String mimeType, String encoding)を使うと文字化けてしまうのです。


webView = (WebView)findViewById(R.id.webView);
String data = "<html><head><meta http-equiv=\"content-type\" content=\"text/html;charset=UTF-8\"></head>";
data += "ウェブビューに表示するぞ!!";
webView.loadData(data, "text/html", "UTF-8");

XPERIA PLAY → OK文字化けしない
Google NEXUS → NG文字化けする

GNだと文字化けしてしまいました。
WebSettingsでデフォルトの文字コードを取得してみると、"Shitft_JIS"

WebSettingsの文字コード変えたり、
dataの文字コードを変えても変わらず。。


二進も三進もいかず、別のAPIを使ってみると・・・

webView.loadDataWithBaseURL(null, data, "text/html", "UTF-8", null);

あっさり成功。何なんでしょうね。。

2012年6月25日月曜日

[Android]回転矩形と点の当たり判定

Matrixで回転させた矩形をタッチしたかどうかを判定します。

当たり判定をチェックするには、円で計算したほうが楽です。

public boolean isPointInside(PointF point, float x, float y) {
// 標的とタッチされたポイントとの距離を計算します
    float dx = x - (point.x);
    float dy = y - (point.y);
float distance = (float) Math.sqrt(dx * dx + dy * dy);

if (distance <= curRatio * bmpWidth / 2) {
return true;
}
return false;
}

ただし、これ正方形の画像にしか使えないです。


今回は、
長方形の画像の判定をしようと思います。

回転したあとの矩形の位置から範囲を計算しようとすると、とっても複雑なのでした。

そこで矩形を回転させるのではなく、
点を矩形を回転させた分だけ移動させることによって判定します。
ということが、こちらの資料に書いてました。
この資料を元にAndroidに書いてみました。

     //ポイントが当たり判定の範囲内かを返します

        public boolean isPointInside(PointF pt) {
        boolean blRet = false;
// 表示されている画像範囲の計算
float half_w = mBitmap.getWidth() * mScale / 2;
float half_h = mBitmap.getHeight() * mScale / 2;
float left = center.x - half_w;
float right = center.x + half_w;
float top = center.y - half_h;
float bottom = center.y + half_h;
RectF rect = new RectF(left, top, right, bottom);
// (1) 矩形の中心と点の距離を計算
double l = Math.sqrt(Math.pow(pt.x - center.x, 2) + Math.pow(pt.y - center.y, 2));

// (2)矩形の中心を原点として見た相対的な点C'の座標
PointF pt2 = new PointF();
pt2.x = pt.x - center.x;
pt2.y = pt.y - center.y;
// (3)点D'と横軸のなす角r2を求める
double r1, r2;
if(pt2.x != 0) {r1 = Math.atan(pt2.y / pt2.x);}
else{r1 = Math.PI / 2;}
r2 = r1 - mAngle;
// (4)点D'の座標
PointF pt3 = new PointF();
pt3.x = (float)(l * Math.cos(r2));
pt3.y = (float)(l * Math.sin(r2));
// (5)点Dに戻す
pt3.x += center.x;
pt3.y += center.y;
// 普通の矩形と点の当たり判定
if(rect.left <= pt3.x && pt3.x <= rect.right &&
  rect.top <= pt3.y && pt3.y <= rect.bottom) {
blRet = true;
}
return blRet;
        }

こんな感じ。


2012年6月23日土曜日

[Android]Matrixで表示位置を絶対座標で指定する


Matrixで位置を移動する場合、
preTranslate()
setTranslate()
postTranslate()
を使います。

が!!!

すでに指定されていた場合、
その座標を基点にして移動します。(相対座標)

さらに、
setTranslate()を使うと、
回転やスケールもリセットされてしまうのです。


今回は、絶対座標が分かっていて、
その座標を指定する方法です。
(回転やスケールも維持したままです)

便利なAPIが用意されてなさそうなので、以下のような方法で値を指定します。

1.
matrix.getValues(values)
で値を取り出します。

2.
取り出した値に値をセットします
values[Matrix.MTRANS_X] = 移動したいx座標;
values[Matrix.MTRANS_Y] = 移動したいy座標;

3.
セットした値をmatrixに戻します
matrix.setValues(values)

2012年6月19日火曜日

[Android]ライブ壁紙をOpenGLで描画する

OpenGLでライブ壁紙を作ってみました。


参考書籍はこちらの2冊。

OpenGLで作るAndroid SDK ゲームプログラミング
第3章 パーティクルシステム



初めてのOpenGL ES
付録C ライブ壁紙でOpenGL ESを利用する
    C.1 ライブ壁紙とは?
    C.2 ライブ壁紙を作成する
        C.2.1 EngineがOSから受け取るメッセージ
    C.3 XMLの編集

「初めてのOpenGL ES」サンプルコード
http://code.google.com/p/learning-opengl-es/





画像の差替えと表示方法を調整して出来上がったのが、こちら。

こちらからダウンロードできます
Google Play「FlareLiveWallpaper」

2012年6月18日月曜日

Gesture Cameraをレビュー頂きました! by dマーケット アプリ&レビュー様

dマーケット アプリ&レビュー様にGesture Cameraのレビューを掲載して頂きました。

dマーケット アプリ&レビューは、
NTTドコモ様の運営するAndroidアプリのレビューサイトです。