等待用户回答权限请求
我正在研究一个需要位置许可的Android项目。我遵循文档,一切都可以在许可本身方面效果很好。但是我的应用在很大程度上取决于该许可,因此,如果不授予,什么也不会起作用。 请求权限如下(知道函数haspermission()
只需检查是否授予许可)
public void requestPermission() {
if(!hasPermission()){
ActivityCompat.requestPermissions(MainActivity.this, new String[] {ACCESS_FINE_LOCATION}, REQUEST_CODE);
Toast.makeText(this, "Here", Toast.LENGTH_SHORT).show();
}
}
无论如何,我的问题是我有一个函数, /code>如下:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Location Permission Granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Location Permission Denied", Toast.LENGTH_SHORT).show();
}
}
}
和我的oncreate()
是:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestPermission();
Toast.makeText(this, "In main", Toast.LENGTH_SHORT).show();
}
如何使我的increate()
方法在用户从“权限对话”中选择结束,等待框,因为如果我直接尝试使用haspermission()
功能,它甚至在用户选择之前都会检查吗?
- - - - - - - - - - - - 编辑 - - - - - - - - - - - - - ----------------
onrequestpermissionsresult
被弃用,因此我使用了此信息:
private ActivityResultLauncher<String> permission = registerForActivityResult(new ActivityResultContracts.RequestPermission(), result -> {
if(result){
Toast.makeText(this, "Granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Denied", Toast.LENGTH_SHORT).show();
}
});
和我的increate()
:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
permission.launch(Manifest.permission.ACCESS_FINE_LOCATION);
Toast.makeText(this, "In main", Toast.LENGTH_SHORT).show();
}
以及权限后的吐司。启动()
在完成权限对话框之前进行了运行。
I'm working on an android project that requires location permission. I followed the documentation and everything works fine for the permission itself. But my app heavily depends on that permission so nothing will work if not granted. anyway, my problem is that I have a function that requests the permission as follows (knowing that the function hasPermission()
just checks if permission was granted before or not):
public void requestPermission() {
if(!hasPermission()){
ActivityCompat.requestPermissions(MainActivity.this, new String[] {ACCESS_FINE_LOCATION}, REQUEST_CODE);
Toast.makeText(this, "Here", Toast.LENGTH_SHORT).show();
}
}
I handled my onRequestPermissionsResult
as follows :
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Location Permission Granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Location Permission Denied", Toast.LENGTH_SHORT).show();
}
}
}
and my onCreate()
is :
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestPermission();
Toast.makeText(this, "In main", Toast.LENGTH_SHORT).show();
}
How can I make the Toast in my onCreate()
method wait until the user finishes from choosing from the permission dialog box, because if I directly try to use my hasPermission()
function it will check even before the user chooses?
------------------------Edit----------------------------------
the onRequestPermissionsResult
is deprecated so i used this :
private ActivityResultLauncher<String> permission = registerForActivityResult(new ActivityResultContracts.RequestPermission(), result -> {
if(result){
Toast.makeText(this, "Granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Denied", Toast.LENGTH_SHORT).show();
}
});
and my onCreate()
:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
permission.launch(Manifest.permission.ACCESS_FINE_LOCATION);
Toast.makeText(this, "In main", Toast.LENGTH_SHORT).show();
}
and still the toast after permission. launch()
ran before completing the permission dialog box.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是正常的选择,因为请求权限需要一些时间来检查系统是否已经授予了我的应用程序此权限。这是不同步的;因此,
ongreate()
将继续通过显示吐司和返回来继续执行。一般而言,您不应抓住Android中的主线程,以避免应用不响应(ANR);因此,暂停
onCreate()
,直到检查是否有许可会导致ANR。我们如何知道我们会知道用户会立即选择一个选项或在一个小时后等待?
因此,正确的方法是在
Active> ActivityResultLauncher
回调中,该回调会等待用户反应,或者您可能可以解雇另一个侦听器回调或更新
livedaTaa
对象。但是所有这些也将进入activityResultLauncher
回调。This is normal because requesting the permission takes some time to check if the system already granted this permission to my app or not. And this is done asynchronously; so the
onCreate()
will go ahead and continue executing by showing the Toast and returning.Generally speaking, you shouldn't seize the main thread in Android to avoid Application Not Responding (ANR); so, pausing the
onCreate()
until it checks there is a granted permission or not will cause ANR.How could we know that the user will immediately choose an option or waits one hour later on?
So, the right way to do this is in the
ActivityResultLauncher
callback which waits for the user reaction asynchronously:Or probably you can fire another listener callback or update a
LiveData
object. But all this will also go in theActivityResultLauncher
callback.