Skip to content

add runtime request permission(android) #2533

@MatejMagat305

Description

@MatejMagat305

I know that is practical duplicate, but I will sugest with "prototype" of cgo and go code...........

Is your feature request related to a problem? Please describe:

sometime is nice to request permision at runtime and sometime the android ignore manifest.xml.......... or sometime I want to be certain I have permision in runtime or change.......

Is it possible to construct a solution with the existing API?

It is possible add, for version media or version v3.....(maybe for early)

Describe the solution you'd like to see:

add to code to internal/driver/mobile/app/android.c or add to code of internal/driver/mobile/android.c or somewhere where it pass best, I was trying in internal/driver/mobile/app/android.c (the patern is https://stackoverflow.com/questions/55062730/how-to-request-android-ndk-camera-permission-from-c-code):

static jmethodID request_permissions;  //which init in function ANativeActivity_onCreate

jclass android_permission_name(JNIEnv* env, const char* perm_name) {
    // nested class permission in class android.Manifest,
    // hence android 'slash' Manifest 'dollar' permission
    jclass ClassManifestpermission = find_class(env, "android/Manifest$permission");
    jfieldID lid_PERM = (*env)->GetStaticFieldID(env,
       ClassManifestpermission, perm_name, "Ljava/lang/String;"
    );
    jclass ls_PERM = (jclass)((*env)->GetStaticObjectField(env,
        ClassManifestpermission, lid_PERM
    ));
    return ls_PERM;
}

bool android_has_permission(JNIEnv* env, const char* perm_name) {
    bool result = false;

    jstring ls_PERM = android_permission_name(env, perm_name);

    int PERMISSION_GRANTED = -1;
    {
       jclass ClassPackageManager = find_class(env, "android/content/pm/PackageManager" );
       jfieldID lid_PERMISSION_GRANTED = (*env)->GetStaticFieldID(env,
          ClassPackageManager, "PERMISSION_GRANTED", "I"
       );
       PERMISSION_GRANTED = (*env)->GetStaticIntField(env,
          ClassPackageManager, lid_PERMISSION_GRANTED
       );
    }
    {
       jclass ClassContext = find_class(env,  "android/content/Context"   );
       jmethodID MethodcheckSelfPermission = find_method(env, ClassContext,
       "checkSelfPermission", "(Ljava/lang/String;)I" );
       int int_result =(int) (*env)->CallIntMethod(env,
           current_class, MethodcheckSelfPermission, ls_PERM
       );
       result = (int_result == PERMISSION_GRANTED);
    }
    return result;
}

void android_request_file_permissions(JNIEnv* env, char* permissions) {
    jobjectArray perm_array = (*env)->NewObjectArray(env,
      2,
      find_class(env, "java/lang/String"),
      (*env)->NewStringUTF(env, "")
    );
    (*env)->SetObjectArrayElement(env,
          perm_array, 1,
          android_permission_name(env, permissions)
        );
    (*env)->CallVoidMethod(
       current_class, request_permissions, perm_array, 0
    );
}
void android_permissions(JNIEnv* env,  char* perm_name) {
    bool OK = android_has_permission(
       env, perm_name
    ) ;
    if(!OK) {
       android_request_file_permissions(env,perm_name );
    }
}

next add to internal/driver/mobile/app/android.go(or somewhere.........):

func requestPermision(permision string){
	n := C.CString(permision)
	RunOnJVM(func(vm, jniEnv, ctx uintptr) error {
		env := (*C.JNIEnv)(unsafe.Pointer(jniEnv))
		C.android_permissions(env, n)
		return nil
	})
	C.free(unsafe.Pointer(n))
}

other OS should have: func requestPermision(permision string){}

maybe add package permision(or put to package storage):

permision/android:

// +build android
package permisions

import (
	"fyne.io/fyne/v2/internal/driver/mobile"
)


func RequestPermision(permision string){
	mobile.RequestPermision(permision)
}

permision/non_android:

// +build !android
package permisions
func RequestPermision(permision string){}

and in basic it look like:

package main
import (
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/permisions"
	"fyne.io/fyne/v2/widget"
)

func main() {
	a := app.New()
	w := a.NewWindow("Hello")

	hello := widget.NewLabel("Hello Fyne!")
	w.SetContent(container.NewVBox(
		hello,
		widget.NewButton("Hi!", func() {
			hello.SetText("Welcome :)")
			permisions.RequestPermision("< PERMISION NAME >")
		}),
	))

	w.ShowAndRun()
}

of course I do not know wheter is posible in IOS and on descopt it could request for root...... and I m sorry this is only sugestion prototype because I try to compile them and on doscopt it work(dont cause any error), but I do not know make headers of funkcion android_permissions link to go.......

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionA question has been asked

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions