Dre*_*rew 161 camera android return-value android-intent android-camera-intent
我们正在尝试使用原生相机应用程序让用户拍摄新照片.如果我们省略EXTRA_OUTPUT extra并返回小的Bitmap图像,它就可以正常工作.但是,如果我们putExtra(EXTRA_OUTPUT,...)在启动它之前处于意图状态,那么一切都会有效,直到您尝试点击相机应用程序中的"确定"按钮."确定"按钮无效.相机应用程序保持打开状态,没有任何锁定.我们可以取消它,但文件永远不会被写入.我们究竟要做什么ACTION_IMAGE_CAPTURE才能将拍摄的照片写入文件?
编辑:这是通过MediaStore.ACTION_IMAGE_CAPTURE意图完成的,只是为了清楚
yan*_*kwa 144
在某些版本的android中,这是一个记录良好的错误.也就是说,在google体验构建的android上,图像捕获不能像记录的那样工作.在公用事业类中,我通常使用的是这样的东西.
public boolean hasImageCaptureBug() {
// list of known devices that have the bug
ArrayList<String> devices = new ArrayList<String>();
devices.add("android-devphone1/dream_devphone/dream");
devices.add("generic/sdk/generic");
devices.add("vodafone/vfpioneer/sapphire");
devices.add("tmobile/kila/dream");
devices.add("verizon/voles/sholes");
devices.add("google_ion/google_ion/sapphire");
return devices.contains(android.os.Build.BRAND + "/" + android.os.Build.PRODUCT + "/"
+ android.os.Build.DEVICE);
}
Run Code Online (Sandbox Code Playgroud)
然后当我启动图像捕获时,我创建一个检查错误的意图.
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
if (hasImageCaptureBug()) {
i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File("/sdcard/tmp")));
} else {
i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
}
startActivityForResult(i, mRequestCode);
Run Code Online (Sandbox Code Playgroud)
然后在我返回的活动中,我根据设备做不同的事情.
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
switch (requestCode) {
case GlobalConstants.IMAGE_CAPTURE:
Uri u;
if (hasImageCaptureBug()) {
File fi = new File("/sdcard/tmp");
try {
u = Uri.parse(android.provider.MediaStore.Images.Media.insertImage(getContentResolver(), fi.getAbsolutePath(), null, null));
if (!fi.delete()) {
Log.i("logMarker", "Failed to delete " + fi);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} else {
u = intent.getData();
}
}
Run Code Online (Sandbox Code Playgroud)
这可以节省你必须编写一个新的相机应用程序,但这个代码也不是很好.最大的问题是
你永远不会从有bug的设备上获得全尺寸的图像.您将获得插入图像内容提供程序的512px宽的图片.在没有bug的设备上,一切都作为文档工作,你得到一个很大的正常图片.
你必须保持清单.如上所述,设备可以使用安装了错误的android版本(例如cyanogenmod的版本)进行刷新.如果发生这种情况,您的代码将崩溃.修复是使用整个设备指纹.
Don*_*ker 50
我知道这已经得到了回答,但我知道很多人都对此感到懊恼,所以我要添加评论.
我在Nexus One上遇到了同样的问题.这是来自相机应用程序启动前磁盘上不存在的文件.因此,我确保在启动相机应用程序之前存在该文件.这是我使用的一些示例代码:
String storageState = Environment.getExternalStorageState();
if(storageState.equals(Environment.MEDIA_MOUNTED)) {
String path = Environment.getExternalStorageDirectory().getName() + File.separatorChar + "Android/data/" + MainActivity.this.getPackageName() + "/files/" + md5(upc) + ".jpg";
_photoFile = new File(path);
try {
if(_photoFile.exists() == false) {
_photoFile.getParentFile().mkdirs();
_photoFile.createNewFile();
}
} catch (IOException e) {
Log.e(TAG, "Could not create file.", e);
}
Log.i(TAG, path);
_fileUri = Uri.fromFile(_photoFile);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE );
intent.putExtra( MediaStore.EXTRA_OUTPUT, _fileUri);
startActivityForResult(intent, TAKE_PICTURE);
} else {
new AlertDialog.Builder(MainActivity.this)
.setMessage("External Storeage (SD Card) is required.\n\nCurrent state: " + storageState)
.setCancelable(true).create().show();
}
Run Code Online (Sandbox Code Playgroud)
我首先使用MD5哈希创建一个唯一的(某种程度)文件名,并将其放入相应的文件夹中.然后我检查它是否存在(不应该,但无论如何都要检查它的良好做法).如果它不存在,我得到的父目录(文件夹)和最多创建文件夹层次结构,以它(如果因此导致该文件的位置的文件夹不存在,他们将这一行后,再之后我创建了文件.一旦文件被创建,我得到Uri并将其传递给intent,然后OK按钮按预期工作,并且都是黄金.
现在,当在相机应用程序上按下确定按钮时,该文件将出现在给定位置.在这个例子中,它将是/sdcard/Android/data/com.example.myapp/files/234asdioue23498ad.jpg
无需复制上面发布的"onActivityResult"中的文件.
dee*_*ter 33
我已经经历了许多照片捕捉策略,似乎总是存在一个案例,一个平台或某些设备,其中上述部分或全部策略将以意想不到的方式失败.我能够找到一个使用下面的URI生成代码的策略,该代码似乎在大多数情况下都有效.
mPhotoUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new ContentValues());
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mPhotoUri);
startActivityForResult(intent,CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE_CONTENT_RESOLVER);
Run Code Online (Sandbox Code Playgroud)
为了进一步为讨论做出贡献并帮助新手,我创建了一个示例/测试应用程序,它展示了几种不同的照片捕获实现策略.绝对鼓励其他实现的贡献添加到讨论中.
https://github.com/deepwinter/AndroidCameraTester
Yen*_*chi 30
我有同样的问题,相机应用程序中的确定按钮什么也没做,无论是在模拟器上还是在nexus上.
指定一个没有空格但没有特殊字符的安全文件名后问题就消失了.MediaStore.EXTRA_OUTPUT 另外,如果要指定一个文件驻留在尚未创建的目录中,则必须先创建它.相机应用程序不会为您执行mkdir.
Ret*_*ier 28
您描述的工作流程应该如您所描述的那样工作.如果您可以向我们展示创建Intent的代码,这可能会有所帮助.一般来说,以下模式应该让你做你正在尝试的.
private void saveFullImage() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(Environment.getExternalStorageDirectory(), "test.jpg");
outputFileUri = Uri.fromFile(file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, TAKE_PICTURE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if ((requestCode == TAKE_PICTURE) && (resultCode == Activity.RESULT_OK)) {
// Check if the result includes a thumbnail Bitmap
if (data == null) {
// TODO Do something with the full image stored
// in outputFileUri. Perhaps copying it to the app folder
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,Camera Activity将创建并保存文件,它实际上不是应用程序的一部分,因此它不具有应用程序文件夹的写入权限.要将文件保存到app文件夹,请在SD卡上创建一个临时文件,然后将其移动到onActivityResult处理程序中的app文件夹中.
要跟进Yenchi上面的评论,如果相机应用程序无法写入相关目录,则OK按钮也不会执行任何操作.
这意味着您无法在只能由您的应用程序编写的位置创建该文件(例如,某些getCacheDir())东西getExternalFilesDir()应该在某些东西下工作,但是.
如果相机应用程序向日志打印错误消息,如果它无法写入指定的EXTRA_OUTPUT路径,那将是很好的,但我找不到.
| 归档时间: |
|
| 查看次数: |
174103 次 |
| 最近记录: |