在Android中使用Golang实现静态服务器加载图片

在Android中使用Golang实现静态服务器加载图片 我正在尝试在我的Android应用中运行GO服务器,该应用正在运行相机,并将文件保存在:

file:///storage/emulated/0/Android/media/com.myapp/

我尝试将此路径定义为服务器中的静态路径,如下所示:

fsAndroid := http.FileServer(http.Dir("file:///storage/emulated/0/Android/media/com.myapp/"))
http.Handle("/android/", fsAndroid)

	go func() {
		log.Println(http.ListenAndServe("127.0.0.1:6060", nil))
		<-c
	}()

但是,当我尝试打开从相机拍摄后保存在那里的文件,并访问:

http://127.0.0.1:6060/android/myfile.jpg

我收到了404 page not found错误。

有什么想法吗?


更多关于在Android中使用Golang实现静态服务器加载图片的实战教程也可以访问 https://www.itying.com/category-94-b0.html

7 回复

这真是个绝妙的主意。 你是怎么做到的。 能分享一下示例代码吗

更多关于在Android中使用Golang实现静态服务器加载图片的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


非常感谢。

我会尝试这个方法。

如何在安卓应用(Java)中调用Go服务器

如何在Android内部运行Go代码

packs:

如何在Android中运行Go代码

使用JNI,请查看我分享的仓库:go-android-photo/main at main · hasanAjsf/go-android-photo · GitHub

引用自 packs:

可以分享一下示例代码吗?

当然可以: 我已经解决了这个问题,并在此分享我的文件:这里

  1. 在 Go 端,我使用了以下代码,感谢上面 fizzie 的提示:
	fsAndroid := http.FileServer(http.Dir("/storage/emulated/0/")) // Pictures/tk.cocoon/

	http.Handle("/android/", http.StripPrefix("/android/", fsAndroid))
  1. 在 Android 端,我使用了以下代码:
interface ImageUri {
    companion object {
        fun create() : Uri? {
            // Create an image file name
            val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
            Global.fileName = "IMG_${timeStamp}.jpg"
            Global.filePath = "Pictures/tk.cocoon/IMG_${timeStamp}.jpg"

            val resolver = Global.context.contentResolver
            val contentValues = ContentValues().apply {
                put(MediaStore.MediaColumns.DISPLAY_NAME, Global.fileName)
                put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
                //put(MediaStore.MediaColumns.RELATIVE_PATH, "Android/media/tk.cocoon/")
                put(MediaStore.MediaColumns.RELATIVE_PATH, "Pictures/tk.cocoon/")
            }
            Global.photoURI = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
            return Global.photoURI
        }
    }
}

问题出在http.Dir使用的路径格式上。http.Dir需要的是本地文件系统路径,而不是file://协议的URL。在Android环境中,你需要直接使用文件系统路径。

以下是修正后的代码:

package main

import (
    "log"
    "net/http"
)

func main() {
    // 使用Android文件系统路径,而不是file:// URL
    androidPath := "/storage/emulated/0/Android/media/com.myapp/"
    
    // 创建文件服务器
    fsAndroid := http.FileServer(http.Dir(androidPath))
    
    // 处理/android/路径的请求
    http.Handle("/android/", http.StripPrefix("/android/", fsAndroid))
    
    // 启动服务器
    log.Println("Server starting on 127.0.0.1:6060")
    if err := http.ListenAndServe("127.0.0.1:6060", nil); err != nil {
        log.Fatal("Server failed to start: ", err)
    }
}

关键修改:

  1. 移除了file://前缀,直接使用文件系统路径
  2. 添加了http.StripPrefix来正确处理URL路径映射
  3. 简化了服务器启动逻辑

现在访问http://127.0.0.1:6060/android/myfile.jpg时,服务器会在/storage/emulated/0/Android/media/com.myapp/myfile.jpg路径查找文件。

另外,确保你的Android应用有正确的存储权限。在AndroidManifest.xml中添加:

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

对于Android 10及以上版本,可能需要使用Scoped Storage,这时路径可能会不同。如果遇到权限问题,可以尝试使用Android的Context获取文件路径:

// 在Android环境中,通过JNI获取正确的文件路径
// 这里是一个示例,实际实现需要结合gomobile
androidPath := getAndroidStoragePath() // 实现这个函数来获取正确的路径

如果文件仍然无法访问,可以添加调试日志来确认服务器是否能正确读取文件:

http.HandleFunc("/android/", func(w http.ResponseWriter, r *http.Request) {
    filePath := androidPath + r.URL.Path[len("/android/"):]
    log.Printf("Attempting to serve file: %s", filePath)
    
    // 检查文件是否存在
    if _, err := os.Stat(filePath); os.IsNotExist(err) {
        log.Printf("File not found: %s", filePath)
        http.NotFound(w, r)
        return
    }
    
    // 使用文件服务器处理请求
    http.StripPrefix("/android/", fsAndroid).ServeHTTP(w, r)
})
回到顶部