Matthew Vedua Matthew Vedua - 3 months ago 29
Android Question

I need to get the activity in order to request permissions

I am using the "Digits" which is allows the user to login with their phone number. It is provided by Twitter. Anyhow, since I am developing for API level 23, I need to request permission to read contacts from the user. I am overriding the

onClick()
method that it supplies me in order to request permission during run-time. However, I do not know how to pass through an
Activity
for the constructor.

This is the class that I am instantiating with:

public class DigitsRegisterButton extends DigitsAuthButton {

final int loginPerm = 2;
LoginActivity activity;

public DigitsRegisterButton(Context c) {
super(c);
init();
}
public DigitsRegisterButton(Context c, AttributeSet attrs) {
super(c, attrs);
init();
}

public DigitsRegisterButton(Context c, AttributeSet attrs, int defStyle) {
super(c, attrs, defStyle);
init();
}

@Override
public void onClick(View v) {
int loginPermissionCheck = ContextCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA);
if (loginPermissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(/* Need Activity Here */, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, loginPerm);
}
super.onClick(v);
}
}


onClick()
that gets Overridden in
DigitsAuthButton
:

@Override
public void onClick(View v) {
final DigitsAuthConfig digitsAuthConfig = digitsAuthConfigBuilder.build();
getDigitsClient().startSignUp(digitsAuthConfig);

if (onClickListener != null) {
onClickListener.onClick(v);
}
}


Activity Class:

public class LoginActivity extends AppCompatActivity implements LocationListener {

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login_nav_bar);

DigitsRegisterButton digitsButton = (DigitsRegisterButton) findViewById(R.id.account_auth_button);
digitsButton.setCallback(new AuthCallback() {

@Override
public void success(DigitsSession session, String phoneNumber) {
// TODO: associate the session userID with your user model
//username phone number, password is auth session
Toast.makeText(getApplicationContext(), "Authentication successful for " + phoneNumber, Toast.LENGTH_LONG).show();
//new Login(getParentFragment(), )
}

@Override
public void failure(DigitsException exception) {
Log.d("Digits", "Sign in with Digits failure", exception);
}
});
}

Answer

I would recommend requesting the permission before enabling the button. After all, requestPermissions() is asynchronous, and I would assume that you would crash when you call super.onClick(). Have the button be disabled if you do not have permission (calling requestPermissions() in onCreate()), then enable it in onRequestPermissionsResult() if you now have permission.

IMHO, requesting permissions is a controller/presenter thing, not a view thing, in a GUI architecture.


Clarifying based on your comment...

You can call getContext() and cast that to be an Activity, as in your case, it actually is an Activity.

However, your onClick() logic is broken. If you do not have permission, you cannot chain to super.onClick(), as you are doing in your question. After all, the point behind requesting the permission is because you can't just use the existing button click logic, as otherwise you will crash. And, as I noted earlier, requestPermissions() is asynchronous, so you will not have the permission by the time requestPermissions() returns.

Your onClick() would need to look more like this:

@Override
public void onClick(View v) {
    int loginPermissionCheck = ContextCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA);
    if (loginPermissionCheck != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions((Activity)getContext(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, loginPerm);
    }
    else {
        super.onClick(v);
    }
}

This will not look great, as the button will not respond properly to the click event.

I don't know much about Fabric, but hopefully they offer some means of doing this authentication other than by using this button, where you can have greater control over the permission process. Better yet, Fabric could offer hooks for dealing with the runtime permission logic.

Comments