我需要获取 activity 才能请求权限

I need to get the activity in order to request permissions

我正在使用 "Digits",它允许用户使用他们的 phone 号码登录。它由推特提供。无论如何,由于我正在为 API 级别 23 开发,我需要请求权限才能读取用户的联系人。我正在覆盖它提供给我的 onClick() 方法,以便在 运行 期间请求许可。但是,我不知道如何为构造函数传递 Activity

这是我要实例化的 class:

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()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);
            }
        });
    }

我建议在启用按钮之前请求许可。毕竟,requestPermissions() 是异步的,我假设您在调用 super.onClick() 时会崩溃。如果您没有权限(在 onCreate() 中调用 requestPermissions()),请禁用该按钮,如果您现在有权限,则在 onRequestPermissionsResult() 中启用它。

恕我直言,在 GUI 架构中请求权限是 controller/presenter 的事情,而不是视图的事情。


正在根据您的评论进行澄清...

您可以调用 getContext() 并将其转换为 Activity,在您的情况下,它实际上 一个 Activity

但是,您的 onClick() 逻辑被破坏了。如果您没有权限,则不能像您在问题中所做的那样链接到 super.onClick()。毕竟,请求权限背后的意义在于你不能只使用现有的按钮点击逻辑,否则你会崩溃。而且,正如我之前提到的,requestPermissions() 是异步的,因此到 requestPermissions() returns.

时您将没有权限

您的 onClick() 需要看起来更像这样:

@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);
    }
}

这看起来不太好,因为按钮不会正确响应点击事件。

我对 Fabric 了解不多,但希望他们提供了一些方法来执行此身份验证,而不是使用此按钮,您可以在其中更好地控制权限过程。更好的是,Fabric 可以提供处理运行时权限逻辑的钩子。