2009年8月アーカイブ

Donut の標準カメラアプリを使ってみました。

 

まずは、起動後のメイン画面。

camera_main.png

カメラのプレビューに枠がついています。

右側の列には、上から、「撮影後のサムネイル」「動画/静止画切り替え」「シャッターボタン」。

 

撮影後のサムネイルをタッチすると、右側の列もかわります。

camera_thumbnail.png

 

メニューキーを押すと、メニューが表示されますが、基本的にはCupcakeと同じように見えます。

camera_menu.png

 

その他のサブメニューでは、「Show on Maps」が増えているようにも見えます。

camera_menu_other.png

 

最後に、「動画/静止画切り替え」をタッチして、動画モード。

camera_movie.png

「撮影後のサムネイル」が非表示となって、「シャッターボタン」も変更になります。

 

うーむ。

やはり、ズームが見当たらない。。。

あくまでも開発中のものですが。

Android SDK には、顔認識用の API が標準で含まれています。

※android.media パッケージ - FaceDetector クラス

 

使い方

  1. 顔認識させたい画像の幅、高さ、認識させたい最大数を引数として FaceDetector クラスをインスタンス化する。
  2. 顔認識させたい画像のビットマップ(16bit形式)と結果を受け取る Face 配列を引数として findFaces() メソッドを呼び出す。
  3. findFaces() メソッドの戻り値に、認識した顔の数が返されるので、1以上であれば、Face 配列を参照する。 

 

以下、簡単なサンプルコードです。

Bitmap orgBitmap = // ここに認識させたいBitmapがあるとする
FaceDetector.Face[] faces = new FaceDetector.Face[3]; // 結果受け取り用
FaceDetector detector = new FaceDetector(
    orgBitmap.getWidth(), // ビットマップの幅
    orgBitmap.getHeight(), // ビットマップの高さ
    faces.length); // ここでは、最大3つの顔認識結果を受け取れるように指定
int numFaces = detector.findFaces(orgBitmap, faces); // 顔認識実行
if (numFaces > 0) {
    // ここでは、結果をわかりやすくするために、元のビットマップを複製し、
    // 赤い四角を描画しています
    Bitmap newBitmap = orgBitmap.copy(Bitmap.Config.RGB_565, true);
    Paint paint = new Paint();
    paint.setColor(Color.argb(255, 255, 0, 0)); // 赤
    paint.setStyle(Style.STROKE); // 塗りつぶしなしの線
    Canvas canvas = new Canvas(newBitmap);
    for (int i = 0; i < numFaces; i++) { // 認識した数だけ処理
        Face face = faces[i];
        PointF midPoint = new PointF(0, 0);
        face.getMidPoint(midPoint); // 顔認識結果を取得
        float eyesDistance = face.eyesDistance(); // 顔認識結果を取得
        RectF rect = new RectF(); // 正方形
        rect.left = midPoint.x - eyesDistance / 2;
        rect.top = midPoint.y - eyesDistance / 2;
        rect.right = midPoint.x + eyesDistance / 2;
        rect.bottom = midPoint.y + eyesDistance / 2;
        canvas.drawRect(rect, paint); // 正方形を描画
    }
}

Android Developers の公式ページにある Hello World チュートリアル の次に試すサンプルコードは、
Notepad Tutorial でなく、Android SDK に含まれている SkeletonApp が良いと思います。

※本記事は、友人がHT-03Aを購入したのを記念して、初心者向けに書いております^^;

 

SkeletonApp とは

  • Android SDK に含まれる標準サンプルアプリケーションの一つ。
  • 約140行ほどのソースコードで、ボタン、エディットテキスト、メニューを試すことができます。

SkeletonApp.png

 

Eclipse から SkeletonApp プロジェクトをインポートするには(※1)

  1. Eclipseを起動する。
  2. [File] メニュー > [New] > [Android] をクリックする。
  3. [New Android Project] 画面が表示されたら、
    [Contents] グループボックス内の [Create project from existing source] ラジオボタンをクリックし、
    [Location] エディットテキストに、インストールした Android SDK に含まれる SkeletonApp ディレクトリを入力する。
    ※例えば、C:\Android\android-sdk-windows-1.5_r3\platforms\android-1.5\samples\SkeletonApp など。
  4. すると、[Project name]、[Build Target]、[Application name]、[Min SDK Version] が自動的に入力されるので、[Finish] ボタンを押して、完了させる。
  5. Package Explorer で SkeletonActivity が追加されていれば成功です。

import.png

package_explorer.png

 

使い方

  • メソッド(メンバ関数)にブレイクポイントを設定して、実際のソースコードをデバッグしてみてください(※2)。
  • 慣れてきたら、ボタン、または、メニューアイテムを追加して、
    それらが押された時に、トースト(※3)を表示するようなコードを追加してみてください。

 

SkeletonApp の次に試すサンプルコードは・・・

  • 同じく、Android SDK に含まれる標準サンプルアプリケーションの一つである ApiDemos です。
    Android アプリケーションで実現できる機能の多くを見ることができるので、
    興味がある機能をデバッグしながら、対応する API を調べてみてください。

 

あわせて読みたい

HTC Magic(HT-03A) などのトラックボールには、ライトが搭載されており、
電話の着信があったときなどにトラックボールが光ます。

では、どうやって光らせるんだろう?と調べていたら、HardwareService クラス setAttentionLight() メソッドに行き着きました(多分コレ?)。

しかしながら、この HadrwareService クラスは、残念ながら非公開クラスでした。。。

他にも、pulseBreathingLight() メソッドみたいなものもあって、たぶんアレだと思うのですが。。。

公開クラスにしてくれればいいのに。。。

frameworks/base/services/java/com/android/server/HardwareService.java

逆引きAndroid入門に書いていた

フルスクリーン(Full Screen)/全画面表示をするには

を更新しました。

 

具体的には、AndroidManifest.xml でフルスクリーン/全画面表示したいアクティビティのテーマで、

android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"

を指定する方法を(方法2として)追記しました。

 

標準のカメラアプリが、このような実装になっていました。

たいていの場合には、こっちの方がお手軽かも。

詳しくは、「フルスクリーン(Full Screen)/全画面表示をするには - 逆引きAndroid入門」に記載しています。

 

あわせて読みたい

アクティビティ(画面)の背景を透過にするには - 逆引きAndroid入門

日経Linux2009年9月号を読みました。

気になった記事は、以下の2点。

 

  • Android機「HT-03A」をLinuxに接続してみる
    リモート操作やネットストレージを各種無料ソフトで有効活用
    P.10~P.11

VLC RemoteConnectBotSwiFTPOnAir などについて書かれています。

 

  • 次世代モバイルOS Moblinの最新技術
    P.153~P.156

FastBoot で起動時間5秒を実現するための取り組みなども書かれています。

これ、Android にも適用してほしいです。

 

日経 Linux (リナックス) 2009年 09月号 [雑誌]

com.android.internal.util (非公開)パッケージに FastMath というクラスがあり、
小数点丸め計算の高速版メソッドがありましたので、どれくらい高速なのか実験してみました。

 

実験用ソースコード 

package com.adakoda.android.fastmathtest;

import android.app.Activity;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;

public class FastMathTestActivity extends Activity {
    // This is copy of com.android.internal.util.FastMath.round method
    public static int round(float x) {
        long lx = (long)(x * (65536 * 256f));
        return (int)((lx + 0x800000) >> 24);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        long start = SystemClock.uptimeMillis();
        {
            float a = 0.1f;
            for (int i = 0; i < 1000000; i++) {
//                Math.round(a);    // 1.java.lang.Math
                round(a);        // 2.com.android.internal.util.FastMath
            }
        }
        long end = SystemClock.uptimeMillis();
        Log.v("time[ms]", String.valueOf(end - start));
    }
}

 

実験結果

単精度小数点を100万回丸め計算するのに要した時間は、
以下のとおり FastMath.round() の方が、java.lang.Math.round() より 約2.25倍高速でした(≠ 赤い彗星)。

  1. java.lang.Math.round() ・・・ 6,626 [ms]
  2. FastMath.round() ・・・ 2,940[ms]

 

なんだか懐かしい感じです。

[Android] NDK でスクリーンショット(キャプチャ)アプリを作るも root 権限が

の続き。

androidzaurus先生のはてぶの指摘にしたがい、Androidアプリ内からNDKでadbdに接続してみました。

 

ループバックアドレスの5037ポートに接続してみると。

 

「せっ、せっ、接続できてた・・・」

 

何かの間違いかと思って、続けて write() してみても、エラーにならない。。。(((;゜Д゜))

 

おそるおそる read() してみても、エラーにならない。。。((((;゜Д゜)))

 

で、肝心のadbdから読む込んだバッファをみてみると、

adbd_responce.png

おおおっー。"FAIL"の文字が!!!

 

なんで"FAIL"で喜んでいるかというと、この文字列は、adbdが作っているからなんです。

期待値は、"OKAY"なんですが、それはさておき、ハンドシェイクは成功ということになります。

 

残念ながら時間切れなので、ここまでです。

 

誰か、後は頼んだよ!(これ以上無理かもしんないですが・・・)


※追記:エミュレータだと接続できましたが、HT-03Aだと接続できませんでした・・・orz...

Android 周辺の人のが結構 Twitter 使っているみたいだったので、
自分も、ずいぶん昔に取得して、放置していたアカウントを再開してみることにしました。

が、

早速、HT-03A に Twidroid をインストールするも繋がらず。。。

よくわからずググってたら、こんな画面が・・・。

twitter_down.png

運が悪いとしか思えない。

結論から言えば、/dev/graphics/fb0 へのアクセス権限があれば
NDK を使ってスクリーンショット(キャプチャ)Androidアプリを作れます。

 

検証用に、エミュレーター/ADP1で、同ディレクトリのアクセス権を変更し、
NDK を使ってフレームバッファをコピーするソースコードを書いて、Androidアプリに組み込んで実行してみたところ、
スクリーンショット(キャプチャ)をとることができました。

 

ですが、 

肝心の HT-03A では、そもそも root 権限を取得できないので、結局のところ、この方法は使えません。。。

 

参考までに試してみたソースコードの断片を貼っておきます。。。

 

C言語側のサンプルソースコード 

// 説明を簡略化するために、エラー処理など諸々省略・・・
struct fb_fix_screeninfo fi;
struct fb_var_screeninfo vi;
int fd = open("/dev/graphics/fb0", O_RDONLY);
ioctl(fd, FBIOGET_FSCREENINFO, &fi);
ioctl(fd, FBIOGET_VSCREENINFO, &vi);
// 例えば、
// vi.xres には 320 [pixel]
// vi.yres には 480 [pixel]
// vi.bits_per_pixel には 16 [bpp]
// などの値を取得できます
void *bits = mmap(0, fi.smem_len, PROT_READ, MAP_SHARED, fd, 0);
// ここでC言語側でメモリを確保して返すか、
// 呼び出し側(Java)で確保したメモリ(※1)にコピーする(※2)
munmap(bits, fi.smem_len);
close(fd);

 

※1: Java 側のサンプルコード

ByteBuffer buffer = ByteBuffer.allocate(必要なメモリサイズ);
hoge(buffer.array()); // ここで C言語側に渡す
Bitmap bitmap = Bitmap.createBitmap(幅(320とか), 高さ(480), Bitmap.Config.RGB_565(16bppの場合));
bitmap.copyPixelsFromBuffer(buffer); // 16BPP のBMP 完成!

※2:C言語側のサンプルソースコード

hoge
(
    JNIEnv* env,
    jobject thiz,
    jbyteArray buffer
)
{
    ...
    jbyte* jbyteBuffer = (*env)->GetByteArrayElements(env, buffer, &b);
    memcpy(jbyteBuffer, bits, fi.smem_len);
    (*env)->ReleaseByteArrayElements(env, buffer, jbyteBuffer, 0);
    ...
}
<<前のページへ 123

Android Advent Calendar 2011

2012年2月

      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29