2011-01-28 42 views
17

我想选择从照片库中的图像文件,并写入SD卡。以下是导致异常的代码。它似乎在尝试创建FileOutputStream时引发此异常。我有以下行添加到嵌套在应用程序元素内的清单文件。我无法找到一个解决问题的办法:java.io.FileNotFoundException(拒绝)当试图写入到Android SD卡

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

public boolean saveSelectedImage(Uri selectedImage, int imageGroup, 
     int imageNumber) 
{ 
    boolean exception = false; 
    InputStream input = null; 
    OutputStream output = null; 
    if(externalStorageIsWritable()) 
    { 
     try 
     { 
      ContentResolver content = ctx.getContentResolver(); 
      input = content.openInputStream(selectedImage); 
      if(input != null) Log.v(CLASS_NAME, "Input Stream Opened successfully"); 
      File outFile = null; 

      File root = Environment.getExternalStorageDirectory(); 
      if(root == null) Log.v(CLASS_NAME, "FAILED TO RETRIEVE DIRECTORY"); 
      else Log.v(CLASS_NAME, "ROOT DIRECTORY is:"+root.toString()); 

      output = new FileOutputStream(root+"/Image"+ imageGroup + "_" + imageNumber + ".png"); 

      if(output != null) Log.e(CLASS_NAME, "Output Stream Opened successfully"); 
      // output = new FileOutputStream 
      // ("/sdcard/Image"+imageGroup+"_"+imageNumber+".png"); 

      byte[] buffer = new byte[1000]; 
      int bytesRead = 0; 
      while ((bytesRead = input.read(buffer, 0, buffer.length)) >= 0) 
      { 
       output.write(buffer, 0, buffer.length); 
      } 
     } catch (Exception e) 
     { 

      Log.e(CLASS_NAME, "Exception occurred while moving image: "); 
      e.printStackTrace(); 

      exception = true; 
     } finally 
     { 
      // if(input != null)input.close(); 
      // if(output != null)output.close(); 
      // if (exception) return false; 
     } 

     return true; 
    } else 
     return false; 

} 
+0

您是否要求获得在清单中写入的权限? – 2011-01-28 01:52:40

+1

我找到了我的问题的答案uses-permission元素必须在清单文件中的应用程序元素之外。 – joefischer1 2011-01-28 01:58:36

回答

0

你可以尝试使用:

String myPath=Environment.getExternalStorageDirectory()+"/Image"+ imageGroup + "_" + imageNumber + ".png"; 

File myFile = new File();  
input = new FileInputStream(myFile); 
7

您还必须确保外部存储子系统处于正确状态;使用Environment.getExternalStorageState()并查找Environment.MEDIA_MOUNTED这是唯一安全的状态。

这也是一个好主意,狭窄异常处理来围绕这些部分IOException,所以你不要过度追从特定IO-问题,例如媒体未安装。

如果您需要活动,有广播意图(Intent.ACTION_MEDIA_xxx),您可以用IntentListener注册相同的信息。

另请注意,当您使用USB进行调试时,外部存储器可能被禁用

还有设备的启动,其中,外部存储不可用期间延长的时间。如果你在启动时做了一些服务,这是一个问题。

一般来说,访问时,您的应用程序必须知道外部存储状态,和处理情况下是不可用,或者在访问它变得不可用。

+0

只是要具体说明,您应该测试Environment.getExternalStorageState()返回Environment.MEDIA_MOUNTED。这是允许编写的唯一存储状态。 – RenniePet 2016-01-13 22:42:47

+0

谢谢我编辑了我的答案以反映这一点。 – 2016-01-14 18:50:36

24

这是你的清单文件看起来应该像

<application android:icon="@drawable/icon" android:label="@string/app_name"> 
    <activity android:name=".WriteCBTextToFileActivity" 
       android:label="@string/app_name"> 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 
      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
</application> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

+0

非常感谢。它效果很好:) – 2012-05-07 11:22:58

3

如果在清单中设置正确的权限,请确保你的设备是不是在“磁盘驱动器“模式连接到PC时。将其更改为“仅充电”模式,它应该可以工作。

9

我有这个问题,答案在这里没有解决它,因为我做了一个非常愚蠢的错误。

确保你给你的Android模拟器的SD卡...我已经离开了SD卡的大小空白,所以当然无法找到任何东西。最重要的是,我在SD卡内指定了一个尚未创建的目录,所以一定要考虑这种情况。

0

尝试(您可以通过进入Android虚拟设备管理器中,编辑您所选择的仿真器,并输入某一值时,SD卡大小改变AVD的SD卡设置)使用openFileOutput("filename")返回一个FileOutputStream而不是自己指定位置。

检查文档 here

2

注意,除了SAURABH答案,因为API 23,你需要在运行时请求权限。

在这里看到: https://developer.android.com/training/permissions/requesting.html

和Justin费德勒的答案在这里:https://stackoverflow.com/a/33288986/328059

另外,我在使用即时运行允许更改并重新运行该应用程序后的权限没有更新过几个案例。所以,作为一种最佳实践,在更改清单后,我从目标设备上卸载应用程序,然后重新构建。