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.
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.