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

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

  1. 创建一个表示路径名的 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);
    
  2. 创建 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 );
    
  3. 相机活动开始,我可以拍照并批准。然后我的onActivityResult() 被调用。但是我的文件没有被写入。 URI 为:file:///data/data/com.droidstogo.boom1/files/parked.jpg

  4. 我可以创建缩略图 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 可以提供帮助。
  • 你能放一些代码以便更好地理解问题

标签: android image file camera save


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

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

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

这是我的代码示例:

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://stackoverflow.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";
      

      这应该足够了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-12
        相关资源
        最近更新 更多