ラベル Android の投稿を表示しています。 すべての投稿を表示
ラベル Android の投稿を表示しています。 すべての投稿を表示

2013年7月12日金曜日

Android 4.xにしたらonPreviewFrameが呼ばれなくなったので対策した

画像認識やAR用途などでカメラからの映像をキャプチャしたい場合、onPreviewFrameで行うことがあると思う。
しかしAndroid 2.x (Gingerbread)では呼ばれていたonPreviewFrameが、Android 4.x (Ice Cream Sandwich)で動かしたら呼ばれなくなっていた。 その対策方法を見つけたのでメモしておく。

問題の起こるコード
class CameraPreviewSurface implements SurfaceHolder.Callback, Camera.PreviewCallback {

    // 中略
    
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mCamera = Camera.open();
        if (mCamera != null) {
            try {
                mCamera.setPreviewDisplay(holder);
                mCamera.setPreviewCallback(this);
            } catch (IOException e) {
                if(camera != null) {
                    mCamera.release();
                    mCamera = null;
                }
            }
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        mCamera.stopPreview();

        // 中略

        mCamera.setParameters(params);
        mCamera.startPreview();

    }

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {

        // 中略

    }
}

そして、以下が対策済みのコード
class CameraPreviewSurface implements SurfaceHolder.Callback, Camera.PreviewCallback {

    // 中略
    
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mCamera = Camera.open();
        if (mCamera != null) {
            try {
                mCamera.setPreviewDisplay(holder);
                // 不要 mCamera.setPreviewCallback(this);
            } catch (IOException e) {
                if(camera != null) {
                    mCamera.release();
                    mCamera = null;
                }
            }
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        mCamera.stopPreview();

        // 中略

        mCamera.setParameters(params);
        mCamera.setPreviewCallback(this); // stopPreviewを呼んだら、startPreviewを呼ぶ前にsetPreviewCallback
        mCamera.startPreview();

    }

   @Override
   public void onPreviewFrame(byte[] data, Camera camera) {

        // 中略

     }
}

stopPreviewを呼ぶとそれ以前のsetPreviewCallbackは無効になるらしい。

参考にしたページ
Android Camera - A Problem I Spent Almost Twenty Hours On
Thanks!

2012年2月25日土曜日

AndroidとMacをBluetoothのSPPで接続してデータ送受信

AndroidのサンプルコードにBluetoothChatというものがある。
これを改造してMacと繋いで文字列を送受信したので手順を書いておく。

EclipseでBluetoothChatのプロジェクトを作り、BluetoothChatからサンプルコード一式を取ってきて追加する。

BluetoothChatService.javaのUUIDを次のように変更する。
private static final UUID   MY_UUID_SECURE = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

今回、BluetoothChatService.javaのInsecureと書いてある部分は使わないので、メンバ変数から、MY_UUID_INSECUREとmInsecureAcceptThreadを削除する。この状態でビルドするとエラーが出るので、そのエラーに関連する部分もまとめて削除する。
さらにBluetoothChat.javaやリソースXMLの方も、insecureと書いてある部分は使わないので削除してよい。

この状態でビルドしたものをインストールして起動後、メニューボタンを押してMake discoverableを選んでMacから接続しておく。

接続が出来ていれば、Mac側に/dev/tty.NexusOne-BluetoothChatのようなデバイスファイルが出来ているはずだ。
ここまで出来たら、シリアルコンソールで接続する。
例えばscreenを使うなら以下のようにする。
sudo screen /dev/tty.NexusOne-BluetoothChat 9600

双方から文字列をやり取り出来れば完了だ。

Tips
図1のエラーが出る場合は、Mac側から設定を削除した後にもう一度最初から接続設定をするとうまくいくかもしれない。または図2および図3のようにBluetoothの設定画面を開いて、プロトコルを現在RS-232Cが設定されていたらモデムに、モデムならRS-232Cに設定して適用するとうまくいくかもしれない。


図1

図2

図3

参考にしたサイト
BluetoothChatでシリアル接続(SPP)を行う
Androidアプリ開発 ~Bluetooth SPP による無線通信~

2011年2月24日木曜日

スウェーデンでTeliaのプリペイドSIMカードを使う


スウェーデンに行って、SIMロックフリーのNexus Oneに現地のキャリアTeliaのプリペイドSIMカードを買って使った時のメモ。

SIMカード自体はストックホルムのアーランダ空港にある売店で購入。
店番のおばちゃんにプリペイドSIMカード下さい、と言ったらいろいろあるけどどれがいい?と聞かれたので、一番メジャーそうなTeliaを選んだ。

金額はカード本体100SKRと50SKRのチャージ、合わせて150SKR。

APNは、Nexus Oneに刺してデフォルトAPNを選択にしたら勝手に設定された。
おばちゃん曰く、実際に使えるようにするには、レシートに記載されている*125*と#と14桁の番号に電話しろとの事。

結果的には、下記に電話すると通話が出来るようになった。
*125*XXXXXXXXXXXXXX# (XXXXXXXXXXXXXXはレシートに記載されていた14桁の番号)

この組み合わせがちゃんと理解してないと曲者。
上記のように*125*XXXXXXXXXXXXXX#の順序で連続して入力した番号に電話しなければいけないのだ。が、話を聞きそびれて、全て組み合わせてる必要があることが分からなかった。想像を働かせて個別に*125*とか14桁の番号とか#とかを間を置いてバラバラに入力してみたところ、この番号は使われていません的なアナウンスが流れるばかり。ホームページを見てもスウェーデン語は意味不明。

結局なんだかんだとやってるうちに正解を見つけるまでに3日もかかってしまった。
一旦繋がった後は地下鉄でもどこでも利用可能だった。この辺は日本より自由度が高い。
ただし連続したデータ転送を開始すると3GからすぐにEDGEになることから、帯域の連続使用時間がある程度を超えると速度制限がなされる模様。

料金の方はと言うと、Web見たりしまくっていたにもかかわらず消費したのは当初のチャージの範囲で20SKR程度で済んだ。

もし次回利用することがあれば、買ったらすぐに店内で設定するようにして分からなかったらすぐに店員に聞こうと思った。

Refillは Ladda med laddningscheck からが一番簡単っぽい。
残高確認は *120# に電話すると結果が返ってきて画面に表示される。


追記: レシートの画像をアップしました。赤丸の部分が14桁の番号が書かれている部分です。