4

ネイティブ Android カメラを起動し、指定した場所に画像を保存したいと思います。問題は、写真をクリックした後、プレビューに保存/破棄のオプションが表示されることです。[保存] をクリックすると、カメラが再び起動し、キャプチャした画像が指定した場所に保存されません。代わりに、デフォルトの場所に保存されます。実際には、クリックした画像の場所が必要です。カメラを起動するために使用するコードは次のとおりです。

MediaScannerConnection_MSC = null;
String fileName = String.valueOf(System.currentTimeMillis())+".jpg";
f = new File(Environment.getExternalStorageDirectory(), fileName);
_imageUri = Uri.fromFile(f);
// create new Intent
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
intent.putExtra(MediaStore.EXTRA_OUTPUT, _imageUri);
startActivityForResult(intent, 1);

カメラから戻った後のコードは次のとおりです

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == 1) {
            if (resultCode == RESULT_OK) {
                // use imageUri here to access the image

                final String imagePath = f.getAbsolutePath();
                _MSC = new MediaScannerConnection(this, new MediaScannerConnectionClient() {

                    public void onMediaScannerConnected() {
                        _MSC.scanFile(imagePath, null);
                    }

                    public void onScanCompleted(String path, Uri uri) {
                        _MSC.disconnect();
                        _MSC = null;
                    }

                });
                _MSC.connect();

            }
        }
    }

私はここで何の間違いをしているのですか

4

1 に答える 1

2

私はあなたの答えを持っていると思います.私はこれを高低で検索しました.それはちょっと難しいです.

まず第一に、特定の携帯電話では

intent.putExtra(MediaStore.EXTRA_OUTPUT, _imageUri);

無視されます:-(

したがって、私の最善の答えは、「EXTRA_OUTPUT」フラグを設定せずに、通常どおり実行して新しい画像 URI を返すことです。次に、そこから、次を使用します。

Uri u = intent.getData();

新しい画像の情報を取得するには、そこから FileOutputStream を使用して、画像ファイルを必要な新しい場所に書き込みます。最後に、元のファイルを削除します。:-)

私はそれが一種のばかげていることを知っていますが、それは機能し、かなり信頼できると思います. :-)

それが役立つことを願っています。:-)

-ジャレッド

8-28-11

@ランゴJ

わかりました、これがコード全体です。コピーして貼り付けて、それが機能するかどうかを確認してください:-)

まず、次のようにカメラを呼び出します。

startActivityForResult(CameraIntent, TAKE_PICTURE);

次に、結果としてこれが必要になります:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    if (resultCode == Activity.RESULT_OK) {
        switch (requestCode) {
        case TAKE_PICTURE:
            Uri u = intent.getData();
            //Toast.makeText(getApplicationContext(), u.getPath(), Toast.LENGTH_SHORT).show();
            WriteFiles(u);
            break;

        }
    }
}

そして、この関数で主な魔法が起こります。

private void WriteFiles(Uri myNewPic) {
    String TempFilePath;
    String TempPath;

    File directory = new File("/sdcard/" + getString(R.string.app_name));

    if (!directory.exists()) {
        directory.mkdirs();
    }

    String TempPictureFile;
    try {
        TempPictureFile = myNewPic.getLastPathSegment() + ".jpg";
        TempFilePath = directory.getPath() + "/" + TempPictureFile;
        FileOutputStream myOutStream = new FileOutputStream(TempFilePath);
        InputStream myInStream = getContentResolver().openInputStream(myNewPic);
        FileIO myFileIO = new FileIO();
        myFileIO.copy(myInStream, myOutStream);
        //now delete the file after copying
        getContentResolver().delete(myNewPic, null, null);
        TempFilePaths.add(TempFilePath);
    } catch (Exception e) {
        Toast.makeText(getApplicationContext(), getString(R.string.ErrorOpeningFileOutput), Toast.LENGTH_SHORT).show();
    }
}

ネイティブのカメラアプリを使って保存するために必要なパーツはこれだけだと思います。ただし、注意しなければならないのは、これが提供するよりも柔軟性と信頼性が必要だったため、最終的にこのコードを放棄することになりました (このアプリを多数の異なる電話で使用すると、1 つの理由で問題が発生する可能性があると考えています)。たとえば、Samsung が UI をカスタマイズした結果、たくさんの問題が発生したため、Samsung 以外のすべての電話でうまく機能します. :-P)。だから私は自分のカメラアプリを作成するだけになりましたが、アプリケーションによってはこれでうまくいくかもしれません。いずれにせよ....頑張ってください!:-)

わかりました、これが私が使用する FileIO クラスです。申し訳ありませんが、最初にこれを含めませんでした。

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.util.Log;

public class FileIO {
private static final int BUFFER_SIZE = 1024 * 2;

public FileIO() {
    // Utility class.
}

public int copy(InputStream input, OutputStream output) throws Exception, IOException {
    byte[] buffer = new byte[BUFFER_SIZE];

    BufferedInputStream in = new BufferedInputStream(input, BUFFER_SIZE);
    BufferedOutputStream out = new BufferedOutputStream(output, BUFFER_SIZE);
    int count = 0, n = 0;
    try {
        while ((n = in.read(buffer, 0, BUFFER_SIZE)) != -1) {
            out.write(buffer, 0, n);
            count += n;
        }
        out.flush();
    } finally {
        try {
            out.close();
        } catch (IOException e) {
            Log.e(e.getMessage(), null);
        }
        try {
            in.close();
        } catch (IOException e) {
            Log.e(e.getMessage(), null);
        }
    }
    return count;
}

}
于 2011-04-08T04:11:15.963 に答える