我正在编写一个应用程序,其中它的唯一功能是充当低功耗蓝牙的接收器。如果用户不允许 BLE,则该应用程序无用。当应用程序第一次启动时,我希望它向用户询问位置权限(因为 Android 需要它用于 BLE)。我调出权限对话框,但当用户阅读对话框、启动 BLEScanner 等时,应用程序的其余部分仍在继续。我希望应用程序在用户阅读对话框并决定要做什么时暂停。这是我的设置:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_CODE);
}
//More UI preparation stuff
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE: {
if (permissions[0].equals(Manifest.permission.ACCESS_COARSE_LOCATION)) {
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
PermissionDialog newDialog = new PermissionDialog();
newDialog.show(getSupportFragmentManager(), "Request Location Permission");
}
}
}
}
“PermissionDialog”是一个不同的类,它使用 DialogFragment 来解释为什么应用程序需要权限,然后关闭/重新启动应用程序。在这种情况下,应用程序的其余部分继续,尝试在用户仍在阅读弹出的权限对话框时执行蓝牙操作!天真地,我以为我可以使用同步锁来做到这一点,如下所示,但在这种情况下,永远不会调用回调:
private final Object initLock = new Object();
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_CODE);
}
Log.i("Lock", "At the lock!");
try {
synchronized (initLock) {
initLock.wait();
}
}
catch (InterruptedException e) {
//TODO find out what to do here
}
Log.i("Lock", "Past the lock!");
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE: {
if (permissions[0].equals(Manifest.permission.ACCESS_COARSE_LOCATION)) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
synchronized (initLock){
initLock.notify();
}
}
else{
PermissionDialog newDialog = new PermissionDialog();
newDialog.show(getSupportFragmentManager(), "Request Location Permission");
}
}
}
}
}
执行此操作的正确方法是什么?我有一些想法,但它们的范围都在膨胀。我是否需要创建另一个继承 AppCompatActivity 的类来执行权限并将其称为线程?但是我怎么知道 onRequestPermissionResult 回调会去哪里呢?我很茫然。
最佳答案
将代码放入您的//More UI preparation stuff
到一个新方法中。在权限之后,说'init()
'
private void init(){
//More UI preparation stuff
}
然后在 onCreate
中,如果已经授予权限,则调用 init();
否则请求权限。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_CODE);
} else {
init();
}
}
现在在 onRequestPermissionsResult
中处理用户的响应 - 如果用户已授权,则初始化 UI,否则阻止该功能和/或将此问题通知用户。
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE: {
if (permissions[0].equals(Manifest.permission.ACCESS_COARSE_LOCATION)) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
init();
} else{
PermissionDialog newDialog = new PermissionDialog();
newDialog.show(getSupportFragmentManager(), "Request Location Permission");
}
}
}
}
}
PS:出于同样的目的,我准备了一个库,它使这个过程变得容易得多。看看my library.
关于java - 如何在权限请求完成之前正确暂停应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52378583/