Request Android permissions.

This commit is contained in:
Greg Pomerantz 2026-06-05 10:57:53 -04:00
parent be123cf48d
commit ac2e0e444d
7 changed files with 194 additions and 43 deletions

44
.gitignore vendored
View File

@ -8,47 +8,9 @@
# build files
*.apk
*.idsig
pad
# IDE
.idea/
.vscode/
# OS files
.DS_Store
Thumbs.db
# Syncthing
.stfolder/
# Go test cache
*.test
*.out
# build files
*.apk
*.idsig
pad
# IDE
.idea/
.vscode/
# OS files
.DS_Store
Thumbs.db
# Syncthing
.stfolder/
# Go test cache
*.test
*.out
# build files
*.apk
*.idsig
pad
*.jar
./pad
cmd/pad/pad
# IDE
.idea/

67
cmd/pad/Permissions.java Normal file
View File

@ -0,0 +1,67 @@
package st.wow.git.logbook;
import java.lang.Runnable;
import java.lang.String;
import android.os.Environment;
import android.os.Handler;
import android.content.Context;
import android.util.Log;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.provider.Settings;
import android.view.View;
public class Permissions extends Fragment {
Context ctx;
Handler handler;
final int PERMISSIONS_REQUEST = 1;
public Permissions(View view) {
Log.d("gio", "Permissions()");
this.ctx = view.getContext();
this.handler = new Handler(this.ctx.getMainLooper());
Permissions inst = this;
handler.post(new Runnable() {
public void run() {
Activity act = (Activity)ctx;
FragmentTransaction ft = act.getFragmentManager().beginTransaction();
ft.add(inst, "Permissions");
ft.commitNow();
}
});
}
@Override public void onAttach(Context ctx) {
super.onAttach(ctx);
Log.d("gio", "onAttach()");
if (ctx instanceof Activity) {
Log.d("gio", "It's an Activity!");
}
if (ctx.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ctx.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
Log.d("gio", "Requesting permissions");
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSIONS_REQUEST);
}
if (!Environment.isExternalStorageManager()){
Intent intent = new Intent();
intent.setAction(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
Uri uri = Uri.fromParts("package", getActivity().getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}
Log.d("gio", "Loading gio library");
System.loadLibrary("gio");
}
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d("gio", "onActivityResult(" + requestCode + "): " + resultCode);
super.onActivityResult(requestCode, resultCode, data);
}
}

View File

@ -2,10 +2,66 @@
package main
/*
#cgo LDFLAGS: -landroid -llog
#include <stdlib.h>
#include "jni_android.h"
*/
import "C"
import (
"errors"
"fmt"
"log"
"runtime"
"unsafe"
"gioui.org/app"
"gioui.org/io/event"
_ "gioui.org/app/permission/storage"
)
type JNIEnv = C.JNIEnv
var (
startpath="/storage/emulated/0/Notes"
startpath="/storage/emulated/0/Documents"
jvm uintptr
theJVM *C.JavaVM
)
func impl_start() { }
func handleEvent(e event.Event) {
switch e := e.(type) {
case app.AndroidViewEvent:
log.Print("ViewEvent")
theJVM = (*C.JavaVM)(unsafe.Pointer(app.JavaVM()))
RunInJVM(func(env *JNIEnv) {
C.registerFragment(env, (C.jobject)(unsafe.Pointer(e.View)))
})
}
}
func RunInJVM(f func(env *C.JNIEnv)) {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
var env *C.JNIEnv
var detach bool
if res := C.GetEnv(theJVM, &env, C.JNI_VERSION_1_6); res != C.JNI_OK {
if res != C.JNI_EDETACHED {
panic(fmt.Errorf("JNI GetEnv failed with error %d", res))
}
if C.AttachCurrentThread(theJVM, &env, nil) != C.JNI_OK {
panic(errors.New("runInJVM: AttachCurrentThread failed"))
}
detach = true
}
if detach {
defer func() {
C.DetachCurrentThread(theJVM)
}()
}
f(env)
}

View File

@ -2,6 +2,13 @@
package main
import (
"gioui.org/io/event"
)
var (
startpath="."
)
func handleEvent(e event.Event) { }

43
cmd/pad/jni_android.c Normal file
View File

@ -0,0 +1,43 @@
//#include <stdlib.h>
#include <stdio.h>
#include <jni.h>
#include "jni_android.h"
#include "_cgo_export.h"
void
registerFragment(JNIEnv *env, jobject view) {
jclass cls = (*env)->GetObjectClass(env, view);
jmethodID mid = (*env)->GetMethodID(env, cls, "getContext", "()Landroid/content/Context;");
jobject ctx = (*env)->CallObjectMethod(env, view, mid);
cls = (*env)->GetObjectClass(env, ctx);
mid = (*env)->GetMethodID(env, cls, "getClassLoader", "()Ljava/lang/ClassLoader;");
jobject loader = (*env)->CallObjectMethod(env, ctx, mid);
cls = (*env)->GetObjectClass(env, loader);
mid = (*env)->GetMethodID(env, cls, "findClass", "(Ljava/lang/String;)Ljava/lang/Class;");
jstring str = (*env)->NewStringUTF(env, "st/wow/git/logbook/Permissions");
cls = (*env)->CallObjectMethod(env, loader, mid, str);
mid = (*env)->GetMethodID(env, cls, "<init>", "(Landroid/view/View;)V");
jobject inst = (*env)->NewObject(env, cls, mid, view);
}
void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID) {
(*env)->CallVoidMethod(env, obj, methodID);
}
jint GetEnv(JavaVM *vm, JNIEnv **env, jint version) {
return (*vm)->GetEnv(vm, (void **)env, version);
}
jint AttachCurrentThread(JavaVM *vm, JNIEnv **p_env, void *thr_args) {
return (*vm)->AttachCurrentThread(vm, p_env, thr_args);
}
jint DetachCurrentThread(JavaVM *vm) {
return (*vm)->DetachCurrentThread(vm);
}
jobject
NewGlobalRef(JNIEnv *env, jobject o) {
return (*env)->NewGlobalRef(env, o);
}

13
cmd/pad/jni_android.h Normal file
View File

@ -0,0 +1,13 @@
#include <jni.h>
void registerFragment(JNIEnv *env, jobject view);
void GetId(JNIEnv* env, jobject p, int chint);
void Decrypt(JNIEnv* env, jobject p, char* cdata, int datalen, int chint);
void Encrypt(JNIEnv* env, jobject p, char* cid, int idlen, char* cdata, int datalen, int chint);
void Clip(JNIEnv* env, jobject p, char* cdata, int datalen);
void stringResult(JNIEnv* env, jclass cls, jint requestCode, jobject response);
void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID);
jint GetEnv(JavaVM *vm, JNIEnv **env, jint version);
jint AttachCurrentThread(JavaVM *vm, JNIEnv **p_env, void *thr_args);
jint DetachCurrentThread(JavaVM *vm);
jobject NewGlobalRef(JNIEnv *env, jobject o);

View File

@ -136,6 +136,9 @@ func run(w *app.Window) error {
logic.SearchQueryChan() <- newQuery
}
logic.LayoutChan() <- glyphLayout
default:
log.Printf("pad: default event")
handleEvent(e)
}
}
}