17

我正在尝试从照片库中选择一个图像文件并写入 SD 卡。下面是导致异常的代码。尝试创建 FileOutputStream 时似乎会引发此异常。我将以下行添加到嵌套在应用程序元素内的清单文件中。我找不到问题的解决方案:

<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;

}
4

7 回答 7

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" />

于 2011-10-13T10:57:54.290 回答
9

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

确保你给你的 Android 模拟器一张 SD 卡...我把 SD 卡的大小留为空白,所以它当然找不到任何东西。最重要的是,我在所述 SD 卡中指定了一个尚未创建的目录,因此请务必考虑这种情况。

(您可以通过转到 Android 虚拟设备管理器、编辑您选择的模拟器并输入一些 SD 卡大小值来更改 AVD 的 SD 卡设置)

于 2013-03-05T19:03:42.657 回答
7

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

将异常处理范围缩小到IOException这些部分也是一个好主意,这样您就不会从特定于 IO 的问题中过度恢复,例如媒体卸载。

如果您需要事件,则有广播意图 ( Intent.ACTION_MEDIA_xxx),其中包含您可以注册的相同信息IntentListener

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

在设备启动期间还有一段较长的时间,外部存储不可用。如果您在启动时在服务中做一些事情,这是一个问题。

通常,您的应用程序必须在访问外部存储时了解它的状态,并处理它不可用或在访问时变得不可用的情况。

于 2011-10-13T10:48:07.730 回答
3

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

于 2012-09-21T08:22:52.403 回答
2

请注意,除了 Saurabh 的回答之外,从 API 23 开始,您需要在运行时请求权限。

见这里: https ://developer.android.com/training/permissions/requesting.html

贾斯汀·菲德勒在这里的回答:https ://stackoverflow.com/a/33288986/328059

此外,在更改权限并使用 Instant Run 重新运行应用程序后,我遇到过几种情况,但权限未更新。因此,作为最佳实践,在更改清单后,我从目标设备上卸载应用程序,然后重新构建。

于 2017-01-22T23:45:21.517 回答
0

您可以尝试:

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

File myFile = new File();      
input = new FileInputStream(myFile);
于 2011-01-28T04:28:04.353 回答
0

尝试使用openFileOutput("filename")返回 FileOutputStream 而不是自己指定位置。

在此处查看文档

于 2016-10-20T00:14:43.910 回答