将照片保存到文件时出现问题

Posted

技术标签:

【中文标题】将照片保存到文件时出现问题【英文标题】:Problems saving a photo to a file 【发布时间】:2011-02-11 09:12:08 【问题描述】:

伙计,当我发送一个要求拍照的意图时,我仍然无法保存图片。这就是我正在做的事情:

    创建一个表示路径名的 URI

    android.content.Context c = getApplicationContext(); 
    
    String fname = c.getFilesDir().getAbsolutePath()+"/parked.jpg";
    
    java.io.File file = new java.io.File( fname ); 
    
    Uri fileUri = Uri.fromFile(file);
    

    创建 Intent(不要忘记 pkg 名称!)并开始活动

    private static int TAKE_PICTURE = 22;
    
    Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE );
    
    intent.putExtra("com.droidstogo.boom1." + MediaStore.EXTRA_OUTPUT, fileUri);
    startActivityForResult( intent, TAKE_PICTURE );
    

    相机活动开始,我可以拍照并批准。然后我的onActivityResult() 被调用。但是我的文件没有被写入。 URI 为:file:///data/data/com.droidstogo.boom1/files/parked.jpg

    我可以创建缩略图 OK(通过不将额外内容放入 Intent),并且可以写入该文件 OK,然后再将其读回。

谁能看出我犯了什么简单的错误? logcat 中没有任何明显的显示 - 相机显然正在拍照。谢谢,

彼得


我应该提到我在 AndroidManifest.xml 文件中设置了适当的权限:

    <uses-permission android:name="android.permission.READ_OWNER_DATA" />
    <uses-permission android:name="android.permission.WRITE_OWNER_DATA" />

    <uses-permission android:name="android.permission.CAMERA" />

    <uses-feature android:name="android.hardware.camera" />
    <uses-library android:name="com.google.android.maps" />



</application>

有什么想法吗?有什么想法可以尝试,以获取有关该问题的更多信息?

【问题讨论】:

也许这个question 可以提供帮助。 你能放一些代码以便更好地理解问题 【参考方案1】:

    正如 Steve H 所说,您不能只使用 file:///data/data/com.droidstogo.boom1/files/parked.jpg 来实现这一点。这是您的应用程序私有目录,相机不能在那里写入。例如,您可以使用一些 SD 卡文件 - 它可供所有人使用。

    正如stealthcopter 所说,intent extra 只是没有你的包名的 MediaStore.EXTRA_OUTPUT。

    仅供参考。我猜这个操作实际上不需要您指定的任何权限。

这是我的代码示例:

final int REQUEST_FROM_CAMERA=1;

private File getTempFile()

    //it will return /sdcard/image.tmp
    return new File(Environment.getExternalStorageDirectory(),  "image.tmp");


private void getPhotoClick()

  Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
  intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(getTempFile()));
  startActivityForResult(intent, REQUEST_FROM_CAMERA);



protected void onActivityResult(int requestCode, int resultCode, Intent data) 
  if (requestCode == REQUEST_FROM_CAMERA && resultCode == RESULT_OK) 
    InputStream is=null;

    File file=getTempFile();
    try 
        is=new FileInputStream(file);
     catch (FileNotFoundException e) 
        e.printStackTrace();
    

    //On HTC Hero the requested file will not be created. Because HTC Hero has custom camera
    //app implementation and it works another way. It doesn't write to a file but instead
    //it writes to media gallery and returns uri in intent. More info can be found here:
    //http://***.com/questions/1910608/android-actionimagecapture-intent
    //http://code.google.com/p/android/issues/detail?id=1480
    //So here's the workaround:
    if(is==null)
        try 
            Uri u = data.getData();
            is=getContentResolver().openInputStream(u);
         catch (FileNotFoundException e) 
            e.printStackTrace();
        
    

    //Now "is" stream contains the required photo, you can process it
    DoSomeProcessing(is);

    //don't forget to remove the temp file when it's not required. 
  


【讨论】:

【参考方案2】:

是不是因为你多加了一个点:

 intent.putExtra("com.droidstogo.boom1."

代替:

 intent.putExtra("com.droidstogo.boom1"

【讨论】:

【参考方案3】:

您的问题可能与您尝试存储文件的目录有关。要将文件保存到 SD 卡,您不需要任何特殊权限,但获取文件夹引用的方式与您的方式不同我做到了。这还取决于您是否希望以 MediaStore 可以检索的方式保存图像(即,像画廊或相册应用程序,或任何其他依赖于这些应用程序来查找图像的应用程序)。假设您希望它在 MediaStore 中列出,下面是执行此操作的代码:

ContentValues newImage = new ContentValues(2);
newImage.put(Media.DISPLAY_NAME, "whatever name you want shown");
newImage.put(Media.MIME_TYPE, "image/png");

Uri uri = contentResolver.insert(Media.EXTERNAL_CONTENT_URI, newImage);

try 
    Bitmap bitmap = //get your bitmap from the Camera, however that's done  
    OutputStream out = contentResolver.openOutputStream(uri);
    boolean success = bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
    out.close();
    if (success)
        Log.d("Image Writer", "Image written successfully.");                   
     else 
        Log.d("Image Writer", "Image write failed, but without an explanation.");
    

 catch (Exception e)
    Log.d("Image Writer", "Problem with the image. Stacktrace: ", e);

在我运行 v1.5 的模拟器上,这成功地将位图保存到 DCIM/Camera 文件夹中的 SD 卡上,其文件名是当前时间。 (时间从 1970 年 1 月 1 日开始以毫秒为单位保存,由于某种原因也称为“纪元”。)

【讨论】:

只是为了挑剔...将文件保存到您必须具有权限的 SDCard。我认为这在 api 级别 4 中有所改变。 @fiXedd:只是为了挑剔作为回报:P 结果你是对的,他们引入了写入 SD 卡的 write_external_storage 权限的要求。在 v1.5 上,它可以正常工作,但在 v2.1 上它需要许可。但是,要写入媒体商店,在 2.1 和 1.5 上似乎都不需要权限。【参考方案4】:

正如史蒂夫所说,您应该将图片保存在 SD 卡中。您尝试保存的目录是私有的,除非您的设备已植根,否则您将无法在那里写入。 尝试替换这一行:

String fname = c.getFilesDir().getAbsolutePath()+"/parked.jpg";

用这条线

String fname = Environment.getExternalStorageDirectory().getAbsolutePath() + "somePathYouKnownExists" + +"/parked.jpg";

这应该足够了。

【讨论】:

以上是关于将照片保存到文件时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

ORA-06502: PL/SQL: 尝试将 XML 保存到文件时出现数字或值错误

iPhone 使用文件共享保存文件时出现问题

保存用相机拍摄或从相机胶卷中选择的图像时出现长时间延迟 - iPhone

将 UIImage 保存到 Core Data 时出错

将超过特定大小的文件发布到 Elastic Beanstalk (EC2) 服务器时出现问题

将文本从 UITextView 保存到领域(Swift 5)时出现问题