john.weland
john.weland

Reputation: 266

How to call an activity's methods from a separate class

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.

Upvotes: 0

Views: 1593

Answers (1)

Tom Tsagkatos
Tom Tsagkatos

Reputation: 1494

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.

Upvotes: 2

Related Questions