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

8

哎呀,我还是不能在发送拍照请求的意图时保存图片。这是我的做法:

  1. Make a URI representing the pathname

    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. Create the Intent (don't forget the pkg name!) and start the activity

    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. The camera activity starts, and I can take a picture, and approve it. My onActivityResult() then gets called. But my file doesn't get written. The URI is: file:///data/data/com.droidstogo.boom1/files/parked.jpg

  4. I can create thumbnail OK (by not putting the extra into the Intent), and can write that file OK, and later read it back).

有没有人能看出我犯了什么简单的错误?在logcat中没有明显显示——相机明显已经拍照。谢谢。

Peter


我应该提一下,在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>

有什么想法吗?有哪些尝试的方法,以获取更多关于问题的信息?


也许这篇问题可以帮到您。 - kgiannakakis
你能否提供一些代码以更好地理解问题? - the100rabh
4个回答

7
  1. 正如Steve H所说,你不能仅使用file:///data/data/com.droidstogo.boom1/files/parked.jpg。这是你的应用程序私有目录,相机无法写入其中。你可以使用一些SD卡文件,例如-它对所有人都可用。

  2. 就像stealthcopter所说,意图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:
    //https://dev59.com/YXI-5IYBdhLWcg3wVWti
    //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. 
  }

}

1

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

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

改为:

 intent.putExtra("com.droidstogo.boom1"

1

你的问题可能与你尝试存储文件的目录有关。要将文件保存到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,成功将位图保存到SD卡的DCIM/Camera文件夹中,并以当前时间命名文件。(时间以自1970年1月1日起的毫秒数保存,也被称为“纪元”。)

只是挑刺一下...要将文件保存到SD卡中,你确实需要权限。我认为这在API级别4中已经改变了。 - Jeremy Logan
@fiXedd:只是想要挑刺一下 :P 结果你说得对,他们确实引入了需要写外部存储权限才能写入SD卡的要求。在v1.5上,没有问题,但在v2.1上需要该权限。然而,在2.1和1.5上,似乎都不需要权限就可以写入Media Store。 - Steve Haley

0

正如Steve所说,你应该将图片保存在SD卡中。你试图保存的目录是私有的,除非你的设备已经root,否则你无法在那里写入。 尝试替换这行代码:

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

使用这行代码

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

这应该足够了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接