2014-10-06 496 views
6

我可以按下按钮,打开本机照相机应用程序,并成功拍照。但是,当我检查手机上的图库或照片原生应用程序时,图片不会保存在那里。我对Android非常陌生,所以很可能我在代码中丢失了一些重要的东西。拍照后照相机未保存

问题:

1)这些图片在哪里被保存?

2)我是否可以修改下面的代码以保存到内部存储器,所以使用我的应用程序拍摄的所有照片都是私人的,只能通过我的应用程序访问? 3)如果我想将这些图片保存到一个对象,并附上一些文本/其他输入,那么最好的方法是什么?我应该保存一个Uri还是一些标识符以后引用图像,或者保存实际的BitMap图像?

任何帮助非常感谢,谢谢!

这里是我的代码拍照:从Google developer guides直取

mImageButton.setOnClickListener(new View.OnClickListener() 
{ 
    public void onClick(View v) 
    { 
     Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
     imageUri = CameraUtils.getOutputMediaFileUri(CameraUtils.MEDIA_TYPE_IMAGE); 
     intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); 
     startActivityForResult(intent, REQUEST_IMAGE); 
    } 
} 

CameraUtils类:

public static Uri getOutputMediaFileUri(int type) 
{ 
    return Uri.fromFile(getOutputMediaFile(type)); 
} 

public static File getOutputMediaFile(int type) 
{ 
    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
      Environment.DIRECTORY_PICTURES), "camera"); 

    if (!mediaStorageDir.exists()) 
    { 
     if (!mediaStorageDir.mkdirs()) 
     { 
      return null; 
     } 
    } 

    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
    File mediaFile; 
    if (type == MEDIA_TYPE_IMAGE) 
    { 
     mediaFile = new File(mediaStorageDir.getPath() + File.separator + 
       "IMG_" + timeStamp + ".jpg"); 
    } 
    else if(type == MEDIA_TYPE_VIDEO) 
    { 
     mediaFile = new File(mediaStorageDir.getPath() + File.separator + 
       "VID_" + timeStamp + ".mp4"); 
    } 
    else 
    { 
     return null; 
    } 

    return mediaFile; 
} 

回答

4

1)通过查看代码,我期望的照片是保存在一个名为'相机'的目录中,该目录可以在设备上的图片文件夹(外部存储)中找到。这些可能不会立即出现在您的画廊中,但是在更高版本的Android中(Kitkat,也许果冻豆虽然我现在无法验证),但您应该能够打开照片应用程序并在其中找到它们。如果情况并非如此,那么启动一个文件浏览器应用程序(例如应用程序是ASTRO文件管理器或X-Plore)并浏览到图片/照相机目录,您应该在其中看到图像。下次您的媒体重新编入索引时(手机重新启动,或从其他地方触发的重新索引),您应该在您的图库/照片应用中看到这些照片。如果您想以编程方式刷新媒体,here可能会有所帮助。最后,请确保您的Android清单中具有READ_EXTERNAL_STORAGE权限(如指定this(Android doc))。 2)如果要将图像保存为仅供应用程序使用,则需要将它们保存到应用程序的内部数据目录中。直接从Android文档中查看this。确保使用MODE_PRIVATE标志。

3)为此,您希望将文件路径存储在您的应用程序可访问的某处。您可以将文件路径保存为包含其他文本数据的文本文件,也可以使用sqlite数据库。最后,你可以使用像ORMLite这样的ORM来保存一个java对象,它可以为你的图片保存数据,并且有一些你想要保留的字段(标题,描述,路径等)。 Herehere是介绍如何开始使用Android中的SQLite数据库(直接从官方文档)。如果你想使用ORMLite,他们的网站上有大量的信息here。开发人员花了很多时间回答StackOverflow的问题。

所有的问题都可以用一些简单的Google搜索来解答。它们是Android中非常标准和基本的事情,所以你应该能够在网上找到大量的信息和教程。

编辑

在回答你关于第二个问题发表评论。这是我可能会做的(或类似的):

请注意,我没有测试这个。它来自我的头顶。如果您有更多问题,请点击此处!

活动代码...

mImageButton.setOnClickListener(new View.OnClickListener() 
{ 
    public void onClick(View v) 
    { 
     Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
     imageUri = CameraUtils.getOutputMediaFileUri(currentActivity, CameraUtils.MEDIA_TYPE_IMAGE); 
     intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); 
     startActivityForResult(intent, REQUEST_IMAGE); 
    } 
} 

public void onActivityResult(int requestCode, int resultCode, Intent data) 
{ 
    if (requestCode == REQUEST_IMAGE) 
    { 
     if (resultCode == RESULT_OK) 
     { 
      String pathToInternallyStoredImage = CameraUtils.saveToInternalStorage(this, imageUri); 
      // Load the bitmap from the path and display it somewhere, or whatever 
     } 
     else if (resultCode == RESULT_CANCELED) 
     { 
      //Cancel code 
     } 
    } 
} 

CameraUtils类代码...

public static Uri getOutputMediaFileUri(int type) 
{ 
    return Uri.fromFile(getOutputMediaFile(type)); 
} 

public static File getOutputMediaFile(int type) 
{ 
    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
      Environment.DIRECTORY_PICTURES), "camera"); 

    createMediaStorageDir(mediaStorageDir); 

    return createFile(type, mediaStorageDir); 
} 

private static File getOutputInternalMediaFile(Context context, int type) 
{ 
    File mediaStorageDir = new File(context.getFilesDir(), "myInternalPicturesDir"); 

    createMediaStorageDir(mediaStorageDir); 

    return createFile(type, mediaStorageDir); 
} 

private static void createMediaStorageDir(File mediaStorageDir) // Used to be 'private void ...' 
{ 
    if (!mediaStorageDir.exists()) 
    { 
     mediaStorageDir.mkdirs(); // Used to be 'mediaStorage.mkdirs();' 
    } 
} // Was flipped the other way 

private static File createFile(int type, File mediaStorageDir) // Used to be 'private File ...' 
{ 
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
    File mediaFile = null; 
    if (type == MEDIA_TYPE_IMAGE) 
    { 
     mediaFile = new File(mediaStorageDir .getPath() + File.separator + 
       "IMG_" + timeStamp + ".jpg"); 
    } 
    else if(type == MEDIA_TYPE_VIDEO) 
    { 
     mediaFile = new File(mediaStorageDir .getPath() + File.separator + 
       "VID_" + timeStamp + ".mp4"); 
    } 
    return mediaFile; 
} 

public static String saveToInternalStorage(Context context, Uri tempUri) 
{ 
    InputStream in = null; 
    OutputStream out = null; 

    File sourceExternalImageFile = new File(tempUri.getPath()); 
    File destinationInternalImageFile = new File(getOutputInternalMediaFile(context).getPath()); 

    try 
    { 
     destinationInternalImageFile.createNewFile(); 

     in = new FileInputStream(sourceExternalImageFile); 
     out = new FileOutputStream(destinationInternalImageFile); 

     // Transfer bytes from in to out 
     byte[] buf = new byte[1024]; 
     int len; 
     while ((len = in.read(buf)) > 0) 
     { 
      out.write(buf, 0, len); 
     } 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
     //Handle error 
    } 
    finally 
    { 
     try { 
      if (in != null) { 
       in.close(); 
      } 
      if (out != null) { 
       in.close(); 
      } 
     } catch (IOException e) { 
      // Eh 
     } 
    } 
    return destinationInternalImageFile.getPath(); 
} 

所以,现在你有路径指向您的内部存储的图像,你可以然后从你的onActivityResult操纵/加载。

+0

感谢您的回复!关于#2,我已经看过那部分文档,但我不确定如何将它应用到我的应用中。你知道任何示例说明如何去做吗?我只能找到代码片段。 – pez 2014-10-06 22:26:05

+0

再次感谢!在我的手机上运行您的代码,在我拍摄照片后,它似乎总是在相机应用程序中冻结。使用'Log.d',似乎所有东西都被调用,并且logcat没有显示任何错误。但是在我拍照之后,它不会让我用原生相机应用程序中的复选标记来确认它;我只能点击“x”重新拍摄照片,或者按手机导航栏上的“主页”或“后退”按钮。 – pez 2014-10-06 23:35:26

+1

你的Android清单中有这三个权限吗? '' '' '' 你真的只需要写入权限来保存图像(以及我相信的相机功能)。但通常阅读也包括在内,因为你可能需要它。 – maraci 2014-10-07 15:21:27