0

So I've been playing around with Android M style permissions and I have a working demo so long as I do everything from within the MainActivity. I felt that it looked to cumbersome and wanted to split that in to multiple files so it looked a little cleaner and could be more easily maintained.

The problem is by moving the permissions checking into its own file, I am having trouble now getting my permissions checker to go back to MainActivity and launch the demo() method. Where I need to call back to main activities demo method is on line 73 and line 114 of the PermissionsChecker.java

NOTE: I followed this tutorial on Android Permissions I have found this question as well as these questions here & here. I realize this is dangerously close to a duplicate of the last two, they got me close but I haven't quite been able to get it. If someone can break it down a little more for me, I am still fairly new to Java and Android.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> <manifest package="me.johnweland.androidrtp" xmlns:android="http://schemas.android.com/apk/res/android"> <!-- // Permissions --> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.CAMERA" /> <!-- // Features --> <uses-feature android:name="android.hardware.camera" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest> 

MainActivity.java

package me.johnweland.androidrtp; import android.Manifest; import android.annotation.TargetApi; import android.content.pm.PackageManager; import android.os.Build; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.Toast; import java.util.HashMap; import java.util.Map; public class MainActivity extends AppCompatActivity { final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (Build.VERSION.SDK_INT >= 23) { // Marshmallow+ PermissionChecker permissions = PermissionChecker.getInstance(this); permissions.permissionsCheck(); } else { // Pre-Marshmallow demo(); } } @TargetApi(Build.VERSION_CODES.M) public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: { Map<String, Integer> perms = new HashMap<String, Integer>(); // Initial perms.put(Manifest.permission.RECORD_AUDIO, PackageManager.PERMISSION_GRANTED); perms.put(Manifest.permission.CAMERA, PackageManager.PERMISSION_GRANTED); // Fill with results for (int i = 0; i < permissions.length; i++) perms.put(permissions[i], grantResults[i]); // Check for RECORD_AUDIO if (perms.get(Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED && perms.get(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) { // All Permissions Granted demo(); } else { // Permission Denied Toast.makeText(this, R.string.permission_denied_message, Toast.LENGTH_SHORT).show(); } } break; default: super.onRequestPermissionsResult(requestCode, permissions, grantResults); } } protected void demo() { Toast.makeText(this, "Demo toast", Toast.LENGTH_LONG).show(); } } 

PermissionsChecker.java

package me.johnweland.androidrtp; import android.Manifest; import android.annotation.TargetApi; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.pm.PackageManager; import android.os.Build; import java.util.ArrayList; import java.util.List; /** * Created by jweland on 12/11/2015. */ public class PermissionChecker { private static final String TAG = PermissionChecker.class.getSimpleName(); final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 0; private MainActivity mainActivity; private static PermissionChecker instance = null; private PermissionChecker(MainActivity activity) { mainActivity = activity; } static public PermissionChecker getInstance(MainActivity activity) { if (instance == null) { instance = new PermissionChecker(activity); return instance; } else { return instance; } } @TargetApi(Build.VERSION_CODES.M) protected void permissionsCheck(){ List<String> permissionsNeeded = new ArrayList<String>(); final List<String> permissionsList = new ArrayList<String>(); // Add permission check for any permission that is not NORMAL_PERMISSIONS if(!addPermission(permissionsList, Manifest.permission.RECORD_AUDIO)) permissionsNeeded.add(mainActivity.getString(R.string.permission_microphone)); if(!addPermission(permissionsList, Manifest.permission.CAMERA)) permissionsNeeded.add(mainActivity.getString(R.string.permission_camera)); if(permissionsList.size() > 0) { if(permissionsNeeded.size() > 0) { // Need Rationale String message = mainActivity.getString(R.string.permission_grant_message) + permissionsNeeded.get(0); for (int i = 1; i < permissionsNeeded.size(); i++) message = message + "\n" +permissionsNeeded.get(i); showMessageOKCancel(message, new DialogInterface.OnClickListener() { @TargetApi(Build.VERSION_CODES.M) @Override public void onClick(DialogInterface dialog, int which) { mainActivity.requestPermissions(permissionsList.toArray(new String[permissionsList.size()]), REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS); } }); return; } mainActivity.requestPermissions(permissionsList.toArray(new String[permissionsList.size()]), REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS); return; } mainActivity.demo(); } private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) { new AlertDialog.Builder(mainActivity) .setMessage(message) .setPositiveButton(R.string.dialog_ok_button_text, okListener) .setNegativeButton(R.string.dialog_cancel_button_text, null) .create() .show(); } @TargetApi(Build.VERSION_CODES.M) private boolean addPermission(List<String> permissionsList, String permission) { if (mainActivity.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { permissionsList.add(permission); // Check for Rationale Option if (!mainActivity.shouldShowRequestPermissionRationale(permission)) return false; } return true; } } 

Initially in the last code block on lines 73 and 114 I had tried something to the effect of "MainActivity.demo();" where "demo();" is the method I wish to call.

2
  • and what error are you getting? Commented Dec 10, 2015 at 22:49
  • The error depends on how I call the method. Initially calling MainActivity.demo(); in PermissionChecker.java where I have the comments currently // launch method demo(); I was getting the error "Non-static demo() cannot be called form a static context" Trying it a few other ways I was getting a null pointer exception when the app would run. I have made some changes to the code... in PermissionChecker, I've made mainActivity of type MainActivity instead of Activity and then call mainActivity.demo(); and it doesn't throw an error or crash. Commented Dec 11, 2015 at 16:18

1 Answer 1

2

You can make your class ask for your activity as a parameter, save it on a variable and call it's method whenever you want (assuming that your class and activity run on the same thread).

public class MyActivity extends AppCompatActivity { public void myFunction() {/* ... */} } public class MyClass { MyActivity activity; //This could be the constructor public void someFunction(MyActivity gActivity) { activity = gActivity; } public void anotherFunction() { //From activity you can get everything you want like context //resources and anything else activity.myFunction(); } } 

Another way you could do it is by creating an interface which saves a function (on your activity) and passes that interface as argument to your class and calls it whenever you want, but that's slightly more complicated, the first method is better in my opinion.

Sign up to request clarification or add additional context in comments.

4 Comments

I've made changes in the code above and it seems to work. The first run it prompts the user for permissions but I don't see my Toast that the demo() method calls. If I close the app and re-run it it doesn't need permissions to it fires off demo() and I see the toast. I'm not sure if its working 100% correctly (or if I did it correctly) but it certainly is progress.
@john.weland on some parts of the code you have a commented out // launch method demo(); did you maybe perhaps to change that to mainActivity.demo(); ?
I did, I forgot to change it in the updated code. Looks like the only problem I might have left is if permissionList.size() > 0. Is causing my app to prompt for permission then do nothing, if you re run it after permissions were granted it fires off proper.
UPDATE:: I had to move onRequestPermissionsResult out of PermissionChecker and into MainActivity, works like a charm.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.