カメラのプレビューの上にボタンを表示したいのですが。

2,198 views
Skip to first unread message

西澤 眞人

unread,
Jul 25, 2011, 9:51:09 PM7/25/11
to android-g...@googlegroups.com
にけ@横浜と申します。

実験に使うソフトを作りかけていましたが
カメラのプレビューの上にボタンを表示するところで
エラーが出て、昨日1日調べてもわからなかったので、質問させてください。


gabuさんの「Android SDK開発のレシピ」の064のサンプルを元に

layout:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<SurfaceView
android:layout_width="fill_parent"
android:id="@+id/camera_view"
android:layout_height="fill_parent"/>
<Button android:text="Button"
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</FrameLayout>


と必要最小限のlayoutにして、

カメラの表示は本の内容を参考に

// レイアウトとビューを生成して
mFrameLayout = new FrameLayout(this);
// mCameraView = new SurfaceView(this); //gabuさんに教えて
mCameraView = (SurfaceView)findViewById(R.id.camera_view); //もらった修正。
mOverlayView = new OverlayView(this);

// 重ねます
mFrameLayout.addView(mCameraView);
// 後にaddViewしたビューが手前に表示されます。
mFrameLayout.addView(mOverlayView);
setContentView(mFrameLayout);

のように、rayoutからcamera_viewのIdを得るようにしたのですが、
これだと、なぜかエラーが出てしまいます。
エラーメッセージは「予期せず終了」みたいなもので、原因が表示されてません。

エミュレータでも実機でもエラーが出るので、実機との相性ではないと思います。


すごく初歩的なミス(初心者ですので、充分に理解できていない所が多いですが)
だと思うのですが、
どのように対策したら良いか教えていただけますか?

bina

unread,
Jul 25, 2011, 11:06:55 PM7/25/11
to 日本Androidの会
にけさん

はじめまして。binaと申します。
まずはログを見てみるといいかと思います。
きっと、ログに強制終了の原因が表示されているはずです。
また、ログを見ても分からない場合は、
そのログの内容をこちらで質問すれば、回答も得られやすいかと思います。

西澤 眞人

unread,
Jul 26, 2011, 3:12:15 AM7/26/11
to android-g...@googlegroups.com
binaさんご進言ありがとうございます。

LogCatでログを取ってみましたが、原因がわかりません。
18行目のWarningあたりでエラーのダイアログが出ているようですが、
何かヒントがあるでしょうか?

開発環境はWindows7 Professional 64bit
Eclipse 3.7
jdk1.6.0_26
ターゲットはAndroid2.3.3 API10
実機はGalaxy S II で確認。

以下、LogCat出力
07-26 07:02:34.520: DEBUG/AndroidRuntime(558): >>>>>> AndroidRuntime START com.android.internal.os.RuntimeInit <<<<<<
07-26 07:02:34.520: DEBUG/AndroidRuntime(558): CheckJNI is ON
07-26 07:02:35.050: DEBUG/AndroidRuntime(558): Calling main entry com.android.commands.pm.Pm
07-26 07:02:35.070: DEBUG/AndroidRuntime(558): Shutting down VM
07-26 07:02:35.080: DEBUG/dalvikvm(558): GC_CONCURRENT freed 101K, 71% free 297K/1024K, external 0K/0K, paused 1ms+1ms
07-26 07:02:35.080: DEBUG/dalvikvm(558): Debugger has detached; object registry had 1 entries
07-26 07:02:35.090: INFO/AndroidRuntime(558): NOTE: attach of thread 'Binder Thread #3' failed
07-26 07:02:35.460: DEBUG/AndroidRuntime(568): >>>>>> AndroidRuntime START com.android.internal.os.RuntimeInit <<<<<<
07-26 07:02:35.460: DEBUG/AndroidRuntime(568): CheckJNI is ON
07-26 07:02:36.000: DEBUG/AndroidRuntime(568): Calling main entry com.android.commands.am.Am
07-26 07:02:36.020: INFO/ActivityManager(61): Force stopping package com.nike.toHole uid=10036
07-26 07:02:36.020: INFO/Process(61): Sending signal. PID: 543 SIG: 9
07-26 07:02:36.030: INFO/ActivityManager(61): Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.nike.toHole/.ToHole } from pid 568
07-26 07:02:36.060: INFO/ActivityManager(61): Start proc com.nike.toHole for activity com.nike.toHole/.ToHole: pid=576 uid=10036 gids={1006}
07-26 07:02:36.091: DEBUG/AndroidRuntime(568): Shutting down VM
07-26 07:02:36.100: DEBUG/dalvikvm(568): GC_CONCURRENT freed 102K, 69% free 321K/1024K, external 0K/0K, paused 1ms+1ms
07-26 07:02:36.110: DEBUG/dalvikvm(568): Debugger has detached; object registry had 1 entries
07-26 07:02:36.730: WARN/ActivityThread(576): Applicationcom.nike.toHoleis waiting for the debugger on port 8100...
07-26 07:02:36.730: INFO/System.out(576): Sending WAIT chunk
07-26 07:02:36.751: INFO/dalvikvm(576): Debugger is active
07-26 07:02:36.940: INFO/System.out(576): Debugger has connected
07-26 07:02:36.940: INFO/System.out(576): waiting for debugger to settle...
07-26 07:02:37.171: INFO/System.out(576): waiting for debugger to settle...
07-26 07:02:37.392: INFO/System.out(576): waiting for debugger to settle...
07-26 07:02:37.590: INFO/System.out(576): waiting for debugger to settle...
07-26 07:02:37.790: INFO/System.out(576): waiting for debugger to settle...
07-26 07:02:37.990: INFO/System.out(576): waiting for debugger to settle...
07-26 07:02:38.194: INFO/System.out(576): waiting for debugger to settle...
07-26 07:02:38.390: INFO/System.out(576): waiting for debugger to settle...
07-26 07:02:38.600: INFO/System.out(576): waiting for debugger to settle...
07-26 07:02:38.818: INFO/System.out(576): waiting for debugger to settle...
07-26 07:02:39.028: INFO/System.out(576): waiting for debugger to settle...
07-26 07:02:39.240: INFO/System.out(576): debugger has settled (1420)
07-26 07:02:39.650: DEBUG/dalvikvm(576): threadid=1: still suspended after undo (sc=1 dc=1)
07-26 07:02:46.052: WARN/ActivityManager(61): Launch timeout has expired, giving up wake lock!
07-26 07:02:46.654: WARN/ActivityManager(61): Activity idle timeout for HistoryRecord{40794198 com.nike.toHole/.ToHole}
07-26 07:02:51.780: DEBUG/dalvikvm(127): GC_EXPLICIT freed 29K, 51% free 2929K/5895K, external 4670K/5568K, paused 62ms
07-26 07:03:01.376: DEBUG/SntpClient(61): request time failed: java.net.SocketException: Address family not supported by protocol

> --
> このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
> このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
> このグループから退会するには、android-group-j...@googlegroups.com にメールを送信してください。
> 詳細については、http://groups.google.com/group/android-group-japan?hl=ja からこのグループにアクセスしてください。
>

=======================================
西澤 眞人(NISHIZAWA Masato)

セントラルエンジニアリング株式会社 通信機事業部
〒222-0033 横浜市港北区新横浜2-3-19 新横浜ミネタビル6F
 TEL:045-473-2058 FAX:045-472-8513

 不在の場合、ご連絡は携帯電話にお願いいたします。
 TEL:080-6671-4169

E-mail:nishizaw...@central-eng.co.jp
URL:http://www.central-eng.co.jp


駄猫

unread,
Jul 26, 2011, 3:20:16 AM7/26/11
to 日本Androidの会
こんにちは、駄猫と申します。

なんとなくですが、layoutをxmlで作成する場合と、ソースで作成する場合とで
色々と混在しているのが原因ではないかなと思われます。

恐らくfindViewByIdでnullが返却されていませんか?

指摘を受けた修正内容は、特定の一箇所をfindViewByIdにするのではなく、
xmlのレイアウトを使用するのなら、setContentVeiwでレイアウトを指定し、
必要な箇所はfindViewByIdにしろという意味だったのではないかな…と勝手に脳内で考えております。
(違っておりましたらスミマセン)

にけさんのlayoutのまま下記のように試しましたところ、
当方環境(desire)では特段問題なく動いておりましたので、よければ参考にしてみてください。

public void onCreate( Bundle savedInstanceState) {

super.onCreate( savedInstanceState);

// layoutをmain.xmlと仮定してます
setContentVeiw( R.layout.main);

mCameraView = (SurfaceView) findViewById( R.id.camera_view);

SurfaceHolder holder = mCameraView.getHolder();
/*
* SurfaceHolder.Callback を implements したクラスを突っ込んでいます。
* 中でカメラをOpenしたりpreviewを開始したりしてます。
*/
holder.addCallback( new CameraPreview());
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

mButton = (Button) findViewById( R.id.button1);

mButton.setOnClickListener( new OnClickListener() {

public void onClick( View v) {
// とりあえずLogだけ…
Log.d( "test", "button click");
}
});
}


もしソースのみで書く事や、混在させることが前提でしたら添付を…と思ったのですが、
ここから添付ってどうやるんでしょう…ってことでそのままべた書きしてみました。
→一応動いていました。

ちなみにOverlayViewは自前で実装されたクラスと判断し、とりあえずButtonに置き換えております。

/**
* ソースのみでレイアウトを生成することを前提とした場合
*/
public void onCreate( Bundle savedInstanceState) {

super.onCreate( savedInstanceState);

FrameLayout layout = new FrameLayout(this);
mCameraView = new SurfaceView( this);
mButton = new Button( this);

// レイアウトのパラメータ設定は適当です
layout.addView( mCameraView, new
LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
layout.addView( mButton, new LayoutParams( LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));

SurfaceHolder holder = mCameraView.getHolder();
holder.addCallback( new CameraPreview());
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

// ボタンのリスナーは省略…

setContentView( layout);
}


/**
* 混在版
*/
public void onCreate( Bundle savedInstanceState) {

// FrameLayoutのみのxml(main2.xml)を指定
setContentView( R.layout.main2);

mCameraView = new SurfaceView( this);
mButton = new Button( this);

addContentView( mCameraView, new
LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
addContentView( mButton, new LayoutParams( LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));

SurfaceHolder holder = mCameraView.getHolder();
holder.addCallback( new CameraPreview());
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

// ボタンのリスナーは省略…
}


以上です。

西澤/にけ@横浜

unread,
Jul 26, 2011, 3:35:12 AM7/26/11
to android-g...@googlegroups.com
駄猫さん、
ご丁寧にお答えいただいて、ありがとうごさいます。
今出張先に向かっているところなので、今晩か明日試してみます。

___________
nike.y...@nifty.com



駄猫 <3a3k...@gmail.com> 作成:


Shoya Tsukada

unread,
Jul 26, 2011, 4:30:51 AM7/26/11
to android-g...@googlegroups.com
にけさん

がぶです。

まず、先に解説をします。
FrameLayoutでView重ねる方法は、大きく二通りあります。

1.XMLで

掲載頂いたXMLで問題ありませんが、
XMLで行う場合は、ソースコードの方でnewやaddしなくてもOKです。

シンプルに
setContentView(R.layout.main);
するだけでOKです。

また、findViewById()メソッドはsetContentView()メソッドを呼び出した後に実行してください。

なので、合わせると

setContentView(R.layout.main);
mCameraView = (SurfaceView)findViewById(R.id.camera_view);

で、OKです。

> // レイアウトとビューを生成して
> mFrameLayout = new FrameLayout(this);
> // mCameraView = new SurfaceView(this); //gabuさんに教えて
> mCameraView = (SurfaceView)findViewById(R.id.camera_view); //もらった修正。
> mOverlayView = new OverlayView(this);
>
> // 重ねます
> mFrameLayout.addView(mCameraView);
> // 後にaddViewしたビューが手前に表示されます。
> mFrameLayout.addView(mOverlayView);

これらはXMLで実現しているのでソースコードには不要です。削除してください。

2.ソースコードで

こちらの2つめの方法が、レシピ064で採用している方法です。
XMLは不要です。

【まとめ】
絶対どちらが良いということはないので用途に応じて使い分けて頂ければと思います。
が、特別な理由がない場合はXMLでViewの定義を行ったほうが良いです。

以上です。試してみてください。
宜しくお願いいたします。

--
塚田 翔也
Shoya Tsukada
tsukada...@gmail.com
Twitter: http://twitter.com/gabu
Blog: http://d.hatena.ne.jp/gabuchan/
つ部: http://sites.google.com/site/androidnagoyatsubu/

にけ

unread,
Jul 26, 2011, 9:08:15 AM7/26/11
to android-g...@googlegroups.com
がぶさん、駄猫さん
にけです。
何度もすみません。m(_ _)m

ようやく思い通りに動きました。

がぶさんの言われていた、XMLでもソースでも大丈夫というのは、
本当にどちらかで設計すればいいんですね。

というか、多分今回のエラーは、findViewById()メソッドでnullが
返っているのかなというのは、Google先生で分かったのですが、
最初に何を実行していいのかわかりませんでした。

VC++とかでGUIで設計することしか経験がないので、
XMLの方が楽なので、こちらのやり方にします。

ここで随分躓きましたが、色々調べたことも
教えていただいたことで整理出来ました。

ありがとうございました。

> --
> このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
> このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
> このグループから退会するには、android-group-j...@googlegroups.com にメールを送信してください。
> 詳細については、http://groups.google.com/group/android-group-japan?hl=ja からこのグループにアクセスしてください。

----------------------
にけ@横浜
nike.y...@nifty.com
http://nike.cocolog-nifty.com/

Reply all
Reply to author
Forward
0 new messages