私は以前にこのコードスニペットを正常に使用しましたが、ファイルはSDカードのどこかを指しています。
final File temp = new File(getCacheDir(), "temp.jpg");
temp.delete();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(temp));
startActivityForResult(intent, CONFIG.Intents.Actions.SELECT_CAMERA_PHOTO);
ただし、SDカードのlocの代わりにgetCacheDirを使用すると、写真が保存されないようです。これはキャッシュディレクトリと画像キャプチャの制限ですか?
技術的には、これは、カメラアプリケーションを使用して画像をキャプチャする場合、内部ストレージへの書き込みがサポートされていないためです。実際、logcatにWriting to internal storage is not supported
という例外が出力されていることに気付くかもしれません。ただし、これが機能しない本当の理由は、デフォルトでアプリケーションパッケージ専用のファイルを作成していて、別のアプリケーション(つまり、カメラアプリ)がそのファイルの場所にアクセスできないためです。そうする。外部ストレージは、ファイルシステムのグローバルにアクセス可能な唯一の部分です。
回避策は、グローバル(WORLD_WRITEABLE)権限でファイルを作成することです。通常、これにより、カメラアプリは渡されたURIを介してファイルにアクセスできます。 File
で直接これを行う方法は実際にはないため、Context
で使用可能な方法を使用してファイルを作成し、後でそのハンドルを取得する必要があります。
//Remove if exists, the file MUST be created using the lines below
File f = new File(getFilesDir(), "Captured.jpg");
f.delete();
//Create new file
FileOutputStream fos = openFileOutput("Captured.jpg", Context.MODE_WORLD_WRITEABLE);
fos.close();
//Get reference to the file
File f = new File(getFilesDir(), "Captured.jpg");
Context
メソッドは本質的にルートの「files」ディレクトリにファイルを作成し、それをキャッシュディレクトリにリダイレクトできないため、これはファイルを配置できる場所にも制限があります。
HTH
私が見つけた最善の解決策は次のとおりです。FileProvider(support-library-v4が必要)
内部ストレージを使用しています! https://developer.Android.com/reference/Android/support/v4/content/FileProvider.html
アプリケーション要素のマニフェストでFileProviderを定義します。
<provider
Android:name="Android.support.v4.content.FileProvider"
Android:authorities="your.package.name.fileprovider"
Android:exported="false"
Android:grantUriPermissions="true" >
<meta-data
Android:name="Android.support.FILE_PROVIDER_PATHS"
Android:resource="@xml/image_path" />
</provider>
必須の場合は、AndroidManifest.xmlのルート要素にカメラ機能を追加します。
<uses-feature Android:name="Android.hardware.camera"
Android:required="true" />
たとえば、res/xml /image_path.xmlで画像パスを定義します。
<paths xmlns:Android="http://schemas.Android.com/apk/res/Android">
<files-path name="captured_image" path="your/path/"/>
</paths>
Java:
private static final int IMAGE_REQUEST_CODE = 1;
// your authority, must be the same as in your manifest file
private static final String CAPTURE_IMAGE_FILE_PROVIDER = "your.package.name.fileprovider";
4.1キャプチャの意図:
File path = new File(activity.getFilesDir(), "your/path");
if (!path.exists()) path.mkdirs();
File image = new File(path, "image.jpg");
Uri imageUri = FileProvider.getUriForFile(activity, CAPTURE_IMAGE_FILE_PROVIDER, image);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, IMAGE_REQUEST_CODE);
4.2 onActivityResult():
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == IMAGE_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
File path = new File(getFilesDir(), "your/path");
if (!path.exists()) path.mkdirs();
File imageFile = new File(path, "image.jpg");
// use imageFile to open your image
}
}
super.onActivityResult(requestCode, resultCode, intent);
}