android 写入内存时遇到问题
void launchImageCapture(Activity context) {
Uri imageFileUri = context.getContentResolver()
.insert(Media.INTERNAL_CONTENT_URI, new ContentValues());
m_queue.add(imageFileUri);
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, imageFileUri);
context.startActivityForResult(i, ImportActivity.CAMERA_REQUEST);
}
上面的代码一直有效,现在在 insert() 中为我生成此异常。
java.lang.UnsupportedOperationException: Writing to internal storage is not supported.
at com.android.providers.media.MediaProvider.generateFileName(MediaProvider.java:2336)
at com.android.providers.media.MediaProvider.ensureFile(MediaProvider.java:1851)
at com.android.providers.media.MediaProvider.insertInternal(MediaProvider.java:2006)
at com.android.providers.media.MediaProvider.insert(MediaProvider.java:1974)
at android.content.ContentProvider$Transport.insert(ContentProvider.java:150)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:140)
at android.os.Binder.execTransact(Binder.java:287)
at dalvik.system.NativeStart.run(Native Method)
这不是一个空间问题,我唯一改变的是一个不相关的类的包在一起。另外,我重新启动了手机。
void launchImageCapture(Activity context) {
Uri imageFileUri = context.getContentResolver()
.insert(Media.INTERNAL_CONTENT_URI, new ContentValues());
m_queue.add(imageFileUri);
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, imageFileUri);
context.startActivityForResult(i, ImportActivity.CAMERA_REQUEST);
}
The above code, which has always worked, is now generating this exception for me at insert().
java.lang.UnsupportedOperationException: Writing to internal storage is not supported.
at com.android.providers.media.MediaProvider.generateFileName(MediaProvider.java:2336)
at com.android.providers.media.MediaProvider.ensureFile(MediaProvider.java:1851)
at com.android.providers.media.MediaProvider.insertInternal(MediaProvider.java:2006)
at com.android.providers.media.MediaProvider.insert(MediaProvider.java:1974)
at android.content.ContentProvider$Transport.insert(ContentProvider.java:150)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:140)
at android.os.Binder.execTransact(Binder.java:287)
at dalvik.system.NativeStart.run(Native Method)
It is not a space issue, and the only thing I changed was the package of an unrelated class all together. Also, I restarted my phone.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在这里面临同样的问题,我很高兴找到这个线程。尽管在这个解决方法中有两件事困扰着我,但这篇文章让我找到了正确的方向。我想分享我自己的解决方法/解决方案。
让我首先阐述一下我不认为自己会经历的事情。
首先,我不想将应用程序私有文件保留为 MODE_WORLD_WRITEABLE。这对我来说似乎毫无意义,尽管我无法确切地弄清楚另一个应用程序如何访问此文件,除非知道在哪里使用完整的名称和路径查找它。我并不是说这对你的场景一定不好,但它仍然以某种方式困扰着我。我更愿意通过让图片文件对我的应用程序真正私有来覆盖我的所有基础。在我的业务案例中,图片在应用程序之外没有任何用处,并且绝不应该通过 Android Gallery 等方式删除它们。我的应用程序将在适当的时间触发清理,以免耗尽 Droid 设备存储空间。
其次,openFileOutput()不保留任何选项,而是将结果文件保存在getFilesDir()的根目录中。如果我需要一些目录结构来保持秩序怎么办?此外,我的应用程序必须处理不止一张图片,因此我希望生成文件名,以便稍后参考。
您看,使用相机拍摄照片并将其保存到 Droid 设备上的公共图像区域(通过 MediaStore)非常简单。从 MediaStore 操作(查询、更新、删除)媒体也很容易。有趣的是,将相机图片插入 MediaStore 会生成一个看起来唯一的文件名。为具有目录结构的应用程序创建私有文件也很容易。 “捕获相机图片并将其保存到内存”问题的症结在于您无法直接执行此操作,因为 Android 会阻止 ContentResolver 使用 Media.INTERNAL_CONTENT_URI,并且根据定义,私有应用程序文件是无法通过(外部)相机活动访问。
最后我采用了以下策略:
这是启动摄像头的代码:
这是我获取摄像头结果的活动:
瞧!现在我们有了一个真正的应用程序私有图片文件,该文件的名称已由 Droid 设备生成。并且公共存储区域中不保留任何内容,从而防止意外的图片篡改。
Facing same problem here, I was happy to find this thread. Even though two things were bugging me in this workaround, this post had me looking in the right direction. I'd like to share my own workaround/solution.
Let me begin by stating what I did not see myself living with.
First, I did not want to leave the application private file as MODE_WORLD_WRITEABLE. This looks like non-sense to me, although I cannot figure exactly how another application could access this file unless knowing where to look for it with complete name and path. I'm not saying it is necessarily bad for your scenario, but it is still bugging me somehow. I would prefer to cover all my bases by having picture files really private to my app. In my business case, pictures are of no use outside of the application and by no means should they be deleteable via, say, the Android Gallery. My app will trigger cleanup at an appropriate time so as to not vampirize Droid device storage space.
Second, openFileOutput() do not leave any option but to save the resulting file in the root of getFilesDir(). What if I need some directory structure to keep things in order? In addition, my application must handle more than one picture, so I would like to have the filename generated so I can refer to it later on.
See, it is easy to capture a photo with the camera and save it to public image area (via MediaStore) on the Droid device. It is also easy to manipulate (query, update, delete) media from MediaStore. Interestingly, inserting camera picture to MediaStore genreates a filename which appears to be unique. It is also easy to create private File for an application with a directory structure. The crux of the "Capturea camera picture and save it to internal memory" problem is that you can't do so directly because Android prevents ContentResolver to use Media.INTERNAL_CONTENT_URI, and because private app files are by definition not accessible via the (outside) Camera activity.
Finally I adopted the following strategy:
Here is the code starting the cam:
And here is my activity getting cam result:
Voila! Now we have a truly application private picture file, which name has been generated by the Droid device. And nothing is kept in the public storage area, thus preventing accidental picture manipulation.
这是我的工作代码,用于将相机捕获的图像保存到应用程序内部存储:
首先,使用所需的文件名创建文件。在本例中它是“MyFile.jpg”,然后按照以下意图启动活动。您的回调方法(
onActivityResult
)将在完成后被调用。调用 onActivityResult 后,您的图像应保存到内部存储中。关键提示:openFileOutput
中使用的模式需要是全局的。Context.MODE_WORLD_WRITEABLE
工作正常,我还没有测试其他模式。并在活动结果方法中:
检索您的图像:
here is my working code to save a captured image from the camera to app internal storage:
first, create the file with the desired filename. in this case it is "MyFile.jpg", then start the activity with the intent below. you're callback method(
onActivityResult
), will be called once complete. After onActivityResult has been called your image should be saved to internal storage. key note: the mode used inopenFileOutput
needs to be global..Context.MODE_WORLD_WRITEABLE
works fine, i have not tested other modes.and in the activity result method:
to retrieve your image:
该相机显然不支持写入内部存储。
不幸的是,文档中没有提到这一点。
MediaProvider.java 有以下代码:
因此暂时禁止写入内部存储。
编辑 - 我认为你可以使用 binnyb 的方法作为解决方法,但我不推荐它;我不确定这是否会在未来的版本中继续有效。我认为其目的是禁止写入媒体文件的内部存储。
我在 Android 问题跟踪器中提交了错误。
编辑 - 我现在明白为什么宾尼布的方法有效。相机应用程序被认为只是另一个应用程序。如果没有权限,则无法写入内部存储。将文件设置为全局可写会授予其他应用程序写入该文件的权限。
然而,我仍然认为这不是一个好主意,原因如下:
The camera apparently doesn't support writing to internal storage.
Unfortunately this is not mentioned in the documentation.
MediaProvider.java has the following code:
So writing to internal storage has been intentionally disabled for the time being.
Edit - I think you can use binnyb's method as a work-around, but I wouldn't recommend it; I'm not sure if this will continue to work on future versions. I think the intention is to disallow writing to internal storage for media files.
I filed a bug in the Android issue tracker.
Edit - I now understand why binnyb's method works. The camera app is considered to be just another application. It can't write to internal storage if it doesn't have permissions. Setting your file to be world-writable gives other applications permission to write to that file.
I still don't think that this is a very good idea, however, for a few reasons: