1

私のプログラムの目標は、(少なくともこの段階では)ガラスから写真を取得し、それを画面に表示することです(私はイマージョンを使用しています)。

私のクラス(extends Activityもちろん)には次のものがあります:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_picture_analysis);

    Intent getTheImageIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(getTheImageIntent, 25);
}

カメラを起動します。ユーザーが写真を撮って受け入れると、私のpublic void onActivityResultメソッドが呼び出されます

public void onActivityResult(int requestCode, int resultCode, Intent data) {



    // A bunch of debug logging that I inserted
    Log.d("glass", "got a pic!!");
    Log.d("glass", String.valueOf(resultCode));
    Log.d("glass", String.valueOf(resultCode==RESULT_OK));


    if (data.getExtras() != null && requestCode == 25) {
        Log.d("glass", "in the if");

        //Create an instance of bundle and get the returned data
        Bundle extras = data.getExtras();

        final String pathToImage = (String) extras.get("picture_file_path");

        for (String key : extras.keySet()) {
            Object value = extras.get(key);
            Log.d("glass", String.format("%s %s (%s)", key,
                    value.toString(), value.getClass().getName()));
        }




        FileObserver observer = new FileObserver(pathToImage) {

            @Override
            public void onEvent(int event, String path) {

                Log.d("glass", "we observed an event");

                if (event == FileObserver.CLOSE_WRITE || event==FileObserver.CLOSE_NOWRITE) {
                    Bitmap thePicUnscaled = BitmapFactory.decodeFile(pathToImage);

                    Log.d("glass", "observer found a close_write event");


                    Bitmap thePic = Bitmap.createScaledBitmap(thePicUnscaled,
                            getResources().getDisplayMetrics().widthPixels,
                            getResources().getDisplayMetrics().heightPixels,
                            true);

                    ImageView imgView = (ImageView) findViewById(R.id.thePictureView);
                    imgView.setImageBitmap(thePic);
                }
            }
        };

        observer.startWatching();
        Log.d("glass","observer started watching");


    } else {
        Log.d("glass", "There were no extras passed with intent in onActivityResult");
    }

}

ここでの問題は、ファイル オブザーバーを呼び出したにもかかわらず、実際に変更を監視しないことです。Log.d("glass", "we observed an event");イベントが発生するたびにログに記録する必要がありますが、ログには記録されません。私のlogcat(私のタグでフィルタリングされたもの)は次のようになります:

05-16 14:27:31.007    4976-4976/com.nkhosla.glasstest.app D/dalvikvm﹕ Late-enabling CheckJNI
05-16 14:27:31.007    4976-4976/com.nkhosla.glasstest.app D/dalvikvm﹕ Try to disable coredump for pid 4976
05-16 14:27:31.007    4976-4976/com.nkhosla.glasstest.app D/dalvikvm﹕ Process 4976 nice name: com.nkhosla.glasstest.app
05-16 14:27:31.007    4976-4976/com.nkhosla.glasstest.app D/dalvikvm﹕ Extra Options: not specified
05-16 14:27:32.031    4976-4976/com.nkhosla.glasstest.app D/OpenGLRenderer﹕ Enabling debug mode 0
05-16 14:27:35.625    4976-4976/com.nkhosla.glasstest.app D/glass﹕ got a pic!!
05-16 14:27:35.625    4976-4976/com.nkhosla.glasstest.app D/glass﹕ -1
05-16 14:27:35.625    4976-4976/com.nkhosla.glasstest.app D/glass﹕ true
05-16 14:27:35.625    4976-4976/com.nkhosla.glasstest.app D/glass﹕ in the if
05-16 14:27:35.625    4976-4976/com.nkhosla.glasstest.app D/glass﹕ thumbnail_file_path /storage/emulated/0/thumbnail_cache/t_thumb_20140516_142732_930.jpg (java.lang.String)
05-16 14:27:35.625    4976-4976/com.nkhosla.glasstest.app D/glass﹕ picture_file_path /storage/emulated/0/DCIM/Camera/20140516_142732_930.jpg (java.lang.String)
05-16 14:27:35.640    4976-4976/com.nkhosla.glasstest.app D/glass﹕ observer started watching

オブザーバーが監視を開始した直後に、そこにあるファイルにアクセスしようとしましたが、NullPointerExceptionを使用して作成されたビットマップにアクセスしようとすると、Bitmap thePicUnscaled = BitmapFactory.decodeFile(pathToImage);

私は、ファイル オブザーバーを少なくとも 5 秒ほど監視したままにしました。これは、フラッシュの書き込み速度では永遠です。私の問題が何であるかわかりません。

参考までに、私のlayout.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="com.nkhosla.glasstest.app.PictureAnalysis">


    <ImageView
        android:layout_height="fill_parent"
        android:layout_width="fill_parent"
        android:id="@+id/thePictureView"
        android:maxHeight="300dp"
        android:maxWidth="640dp"
        android:scaleType="centerCrop"
        android:adjustViewBounds="true"/>

</RelativeLayout>
4

1 に答える 1

1

Camera Intent を使用するときに関心があるのは画像の縮小バージョンだけである場合は、これらの理由から、全体像の代わりにCameraManager#EXTRA_THUMBNAIL_FILE_PATHを使用する必要があります。

  1. すぐに利用できます。後処理が原因で、完全なイメージが書き込まれるまでに数秒かかる場合があります。
  2. すでにプレビュー サイズに縮小されています

完全なイメージが必要な場合、FileObserver はファイル自体ではなく、ファイルの親ディレクトリを監視する必要があります。デベロッパー ガイドで提供しているコード スニペットは次のとおりです。

private static final int TAKE_PICTURE_REQUEST = 1;

private void takePicture() {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(intent, TAKE_PICTURE_REQUEST);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == TAKE_PICTURE_REQUEST && resultCode == RESULT_OK) {
        String picturePath = data.getStringExtra(
                CameraManager.EXTRA_PICTURE_FILE_PATH);
        processPictureWhenReady(picturePath);
    }

    super.onActivityResult(requestCode, resultCode, data);
}

private void processPictureWhenReady(final String picturePath) {
    final File pictureFile = new File(picturePath);

    if (pictureFile.exists()) {
        // The picture is ready; process it.
    } else {
        // The file does not exist yet. Before starting the file observer, you
        // can update your UI to let the user know that the application is
        // waiting for the picture (for example, by displaying the thumbnail
        // image and a progress indicator).

        final File parentDirectory = pictureFile.getParentFile();
        FileObserver observer = new FileObserver(parentDirectory.getPath(),
                FileObserver.CLOSE_WRITE | FileObserver.MOVED_TO) {
            // Protect against additional pending events after CLOSE_WRITE
            // or MOVED_TO is handled.
            private boolean isFileWritten;

            @Override
            public void onEvent(int event, String path) {
                if (!isFileWritten) {
                    // For safety, make sure that the file that was created in
                    // the directory is actually the one that we're expecting.
                    File affectedFile = new File(parentDirectory, path);
                    isFileWritten = affectedFile.equals(pictureFile);

                    if (isFileWritten) {
                        stopWatching();

                        // Now that the file is ready, recursively call
                        // processPictureWhenReady again (on the UI thread).
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                processPictureWhenReady(picturePath);
                            }
                        });
                    }
                }
            }
        };
        observer.startWatching();
    }
}
于 2014-05-19T16:50:07.303 に答える