A software engineer's blog

About this Blog

Welcome to my blog! My name is Nikos and I am an engineer. In this blog I will post algorithms and software related stuff that I find interesting or I had a hard time to find online.

Saturday, June 4, 2016

How to invoke the checkSelfPermission method from Android API 22 and bellow


I build android apps using NetBeans and the NBDroid plugin. I don't use Gradle and AppCompat framework so sometimes I have to "hack" a few things.

Recently I had to make an app that needs access to the coarse location of the user. The app is written for Android API 19 (Android 4.4.2) so I added the android.permission.ACCESS_COARSE_LOCATION permission to the manifest.xml and everything was fine until a few people installed it on their Android 6 phone.

Well... in Android 6 (API 23) the permission system is bit different. The API 23 has a new featured called  "Requesting Permissions at Run Time" so if you need to have access to coarse or fine location then you have to call the checkSelfPermissions method

I spent my whole evening trying to figure out how I can make my API 19 android app to call the checkSelfPermissions  method if someone installs it on an Android API 23. After a very long evening  I finally managed to make it and I decided to share it with you.

Hope you find it useful!


 @Override  
  public void onCreate(Bundle savedInstanceState)  
  {  
     super.onCreate(savedInstanceState);  
     setContentView(R.layout.activity_main);  
     CheckForCoarseLocationPermission();  
  }  

 private void CheckForCoarseLocationPermission()  
 {  
     if (android.os.Build.VERSION.SDK_INT >= 23)  
     {  
       // ANDROID 6.0 AND UP!  
       boolean accessCoarseLocationAllowed = false;  
       try  
       {  
         // Invoke checkSelfPermission method from Android 6 (API 23 and UP)  
         java.lang.reflect.Method methodCheckPermission = Activity.class.getMethod("checkSelfPermission", java.lang.String.class);  
         Object resultObj = methodCheckPermission.invoke(this, Manifest.permission.ACCESS_COARSE_LOCATION);  
         int result = Integer.parseInt(resultObj.toString());  
         if (result == PackageManager.PERMISSION_GRANTED)  
         {  
           accessCoarseLocationAllowed = true;  
         }  
       }  
       catch (Exception ex)  
       {  
       }  
       if (accessCoarseLocationAllowed)  
       {  
         return;  
       }  
       try  
       {  
         // We have to invoke the method "void requestPermissions (Activity activity, String[] permissions, int requestCode) "  
         // from android 6  
         java.lang.reflect.Method methodRequestPermission = Activity.class.getMethod("requestPermissions", java.lang.String[].class, int.class);  
         methodRequestPermission.invoke(this, new String[]  
         {  
           Manifest.permission.ACCESS_COARSE_LOCATION  
         }, 0x12345);  
       }  
       catch (Exception ex)  
       {  
       }  
     }  
 }  

6 comments:

  1. those android devs are bat shit crazy. all i want to do is to use the damn sdcard i bought.

    ReplyDelete
  2. i am trying to save a file onto the S7 sdcard.

    after calling requestPermissions android.permission.WRITE_EXTERNAL_STORAGE
    the checkSelfPermission will no longer report -1 and will report 0 as expected

    yet i still get blocked. any ideas?

    Caused by: java.io.FileNotFoundException: /storage/0000-0000/Application Volume Information.txt: open failed: EACCES (Permission denied)
    at libcore.io.IoBridge.open(IoBridge.java:452)
    at java.io.RandomAccessFile.(RandomAccessFile.java:117)
    at java.io.RandomAccessFile.(RandomAccessFile.java:149)
    at ScriptCoreLibJava.BCLImplementation.System.IO.__File.WriteAllBytes(__File.java:135)
    ... 22 more
    Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
    at libcore.io.Posix.open(Native Method)
    at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
    at libcore.io.IoBridge.open(IoBridge.java:438)
    ... 25 more


    ReplyDelete
  3. for it to work it seems the prefix must be as returned by
    getExternalMediaDirs

    like
    /storage/0000-0000/Android/media/SDCardRSAExperiment.Activities

    ReplyDelete
  4. Thanks a lot I spent the full day looking for that

    ReplyDelete