diff --git a/examples/others/android/example/set_log_android.go b/examples/others/android/example/set_log_android.go new file mode 100644 index 00000000..d10da431 --- /dev/null +++ b/examples/others/android/example/set_log_android.go @@ -0,0 +1,77 @@ +//go:build android + +package main + +/* +#cgo LDFLAGS: -landroid -llog +#include +#include +*/ +import "C" +import ( + "bufio" + "log" + "os" + "syscall" + "unsafe" +) + +// from fyne +func init() { + log.SetOutput(infoWriter{}) + // android logcat includes all of log.LstdFlags + log.SetFlags(log.Flags() &^ log.LstdFlags) + r, w, err := os.Pipe() + if err != nil { + panic(err) + } + stderr = w + if err := syscall.Dup3(int(w.Fd()), int(os.Stderr.Fd()), 0); err != nil { + panic(err) + } + go lineLog(r, C.ANDROID_LOG_ERROR) + + r, w, err = os.Pipe() + if err != nil { + panic(err) + } + stdout = w + if err := syscall.Dup3(int(w.Fd()), int(os.Stdout.Fd()), 0); err != nil { + panic(err) + } + go lineLog(r, C.ANDROID_LOG_INFO) +} + +var ( + ctag = C.CString("raylib") + // Store the writer end of the redirected stderr and stdout + // so that they are not garbage collected and closed. + stderr, stdout *os.File +) + +type infoWriter struct{} + +func (infoWriter) Write(p []byte) (n int, err error) { + cstr := C.CString(string(p)) + C.__android_log_write(C.ANDROID_LOG_INFO, ctag, cstr) + C.free(unsafe.Pointer(cstr)) + return len(p), nil +} + +func lineLog(f *os.File, priority C.int) { + const logSize = 1024 // matches android/log.h. + r := bufio.NewReaderSize(f, logSize) + for { + line, _, err := r.ReadLine() + str := string(line) + if err != nil { + str += " " + err.Error() + } + cstr := C.CString(str) + C.__android_log_write(priority, ctag, cstr) + C.free(unsafe.Pointer(cstr)) + if err != nil { + break + } + } +}