android - 在 Kotlin 中将位图保存为图像

标签 android kotlin

我想将位图保存为图像文件。我尝试了以下代码并得到了错误。

val dir = File("/tempfolder/")

if (!dir.exists()) {
    print("dir not exist");
    dir.mkdirs()
}

val output = File("tempfile.jpg")
var os: OutputStream? = null

os = FileOutputStream(output)

bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os)

os.flush()
os.close()
错误:
E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback
E/MessageQueue-JNI: java.io.FileNotFoundException: tempfile.jpg (Read-only file system)
        at java.io.FileOutputStream.open0(Native Method)
        at java.io.FileOutputStream.open(FileOutputStream.java:287)
        at java.io.FileOutputStream.<init>(FileOutputStream.java:223)
        at java.io.FileOutputStream.<init>(FileOutputStream.java:171)
        at com.app.symbolrecogniser.CanV.touchUp(CanV.kt:190)
        at com.app.symbolrecogniser.CanV.onTouchEvent(CanV.kt:102)
        at android.view.View.dispatchTouchEvent(View.java:11776)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
        at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:448)
        at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1829)
        at android.app.Activity.dispatchTouchEvent(Activity.java:3307)
        at androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
        at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:410)
        at android.view.View.dispatchPointerEvent(View.java:12015)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4795)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4609)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4147)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4200)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4166)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4293)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4174)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4350)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4147)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4200)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4166)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4174)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4147)
        at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6661)
        at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6635)
        at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6596)
        at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6764)
        at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:186)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:325)
        at android.os.Looper.loop(Looper.java:142)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)```

最佳答案

你可能想要 Context#getDir 反而

Retrieve, creating if needed, a new directory in which the application can place its own custom data files. You can use the returned File object to create and access files in this directory. Note that files created through a File object will only be accessible by your own application; you can only set the mode of the entire directory, not of individual files.

The returned path may change over time if the calling app is moved to an adopted storage device, so only relative paths should be persisted.

Apps require no extra permissions to read or write to the returned path, since this path lives in their private storage.


但是还有其他一些您可以访问,例如 getCacheDir (对于临时内容,当用户清除应用程序缓存或释放存储空间时会被删除),getFilesDir (只是 getDir 在其中创建新文件夹的主文件夹,如果您实际上不需要单独的文件夹 - 在应用程序卸载时被删除)和 getExternalFilesDir (与 getFilesDir 相同,只是它在外部存储上,如果你想把东西放在那里)。这些都是只有您的应用可以访问的私有(private)存储空间

关于android - 在 Kotlin 中将位图保存为图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64394285/

相关文章:

java - 在 EditText 中输入文本时出现 NullPointerException

android - 模块中未列出的模拟依赖项

kotlin - 使用 Kotlin 按字母对数组进行排序

android - 如何在 Kotlin android 改造中使用 enque 方法

android - 如何修复 DefaultKotlinSourceSetKt 的初始化错误?

android - 我有一个代码,其中调用了Lateinit变量后对其进行了初始化,但我不知道如何

android - 避免将 null 作为 View 根传递(需要在 inflated layout 的根元素上解析布局参数)

java - Openshift 在 Android 应用程序中上传文件

android - 在android开发中我应该为<TargetID>放置什么

kotlin - "lambda@"在 Kotlin 中是什么意思