0

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);
            }
        });
    }
Matthew Vedua
  • 63
  • 1
  • 7
  • @SohailZahid What exactly do I need to implement from that? I know I need to request permission, however I am requesting them in a class that is not and does not extend an Activity. – Matthew Vedua Aug 16 '16 at 17:12
  • runtime permissions needs a activity reference to be initiate so get it in your activity code. – Sohail Zahid Aug 16 '16 at 17:13
  • I have already did same thing have a single look here http://stackoverflow.com/questions/38141523/directory-creation-not-working-in-marshmallow-android/38141778#38141778 – Sohail Zahid Aug 16 '16 at 17:14
  • I know runtime permissions need an activity, that is why I am asking my question. However, since my class is not an activity, I cannot simply use `ClassName.this`. – Matthew Vedua Aug 16 '16 at 17:20

1 Answers1

1

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.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • The only issue with that is I only need this permission for this one button. I would prefer not to have to prompt the user to accept the permission if I don't have to. I am also using Facebook and Google to let the user login. So, if they want to login with Google, they don't have to accept an unnecessary permission. – Matthew Vedua Aug 16 '16 at 17:14
  • Thank you for the help. Unfortunately, I am dumb. The permission is only needed if the user wants to share their contacts so they can find their friends, which I am not implementing. Sorry for the trouble. – Matthew Vedua Aug 16 '16 at 19:22
  • @MatthewVedua: I thought that it was a bit odd that Fabric used the camera for authentication, but I couldn't rule it out. :-) – CommonsWare Aug 16 '16 at 19:23
  • Woops, that was a copy/paste error. It was supposed to be `READ_CONTACTS` – Matthew Vedua Aug 16 '16 at 19:26