我正在做React原生项目,在那里我正在获取位置权限。此外,我必须跟踪位置权限总是喜欢,如果用户有权限访问后安装应用程序,然后在某个时候用户去应用程序设置在设备设置和禁用/撤销的权限。再次,一旦应用程序从后台到前台,我必须检查权限的基础上,需要显示的消息.
所以,我使用的是AppState。但是,奇怪的是,在Android,安装应用程序后,如果用户拒绝与“不再显示”复选框的权限,然后Appstate得到不断变化与后台和活动总是.它是保持循环。
componentDidMount = async () => {
AppState.addEventListener('change', this.handleAppStateChange);
};
componentWillUnmount() {
AppState.removeEventListener('change', this.handleAppStateChange);
Geolocation.clearWatch(this.watchID);
}
handleAppStateChange = async nextAppState => {
const {appState} = this.state;
console.log('nextAppState -->', nextAppState);
console.log('appState -->', appState);
if (appState === 'active') {
// do this
this.showLoader();
await this.requestAndroidLocationPermission();
} else if (appState === 'background') {
// do that
} else if (appState === 'inactive') {
// do that other thing
}
this.setState({appState: nextAppState});
};
requestAndroidLocationPermission = async () => {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{},
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
this.getLatitudeLongitude();
} else if (granted === PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN) {
this.hideLoader();
this.setState({
errorMessage: 'Location permission is denied',
isLoading: false,
});
} else {
this.hideLoader();
this.requestAndroidLocationPermission();
}
} catch (err) {
console.warn(err);
}
};
拒绝使用不再显示后,继续打印(循环)
appState --> active
nextAppState --> background
appState --> active
nextAppState --> background
appState --> active
nextAppState --> background
appState --> active
它继续,永不停止。
怎么处理?有什么建议吗?
3条答案
按热度按时间fcg9iug31#
我也有同样的问题。不要使用AppState。是有缺陷的。
问题在于RN对“背景”的定义。react-native使用android的activity(UI线程的保持器和UI所在的位置)onPause回调作为发送“后台”信号的触发器。但是,每当有东西出现在Activity的视图层次上时,onPause就会被调用,比如对话框(比如权限框),其他Activity(比如文件选择器)等等;对于android react-native,“background”意味着“被外来UI元素/android任务遮蔽”,而不是“暂停并发送到后台去做其他事情”,从而导致你看到的循环。最短的解决方案是在ReactActivity中覆盖onPause,并添加控制条件以确保super.onPause仅在您实际进入后台时调用,例如检查任务堆栈,或者正在调用权限对话框,因此您可以避免这种循环/错误调用。第二种选择是提供您自己的应用生命周期事件,并带有明确的触发条件。
osh3o9ms2#
在Android中使用“焦点”,在iOS中使用“改变”。
我有一个自定义的钩子像这样:
cclgggtu3#
您可以使用一个标志来检查应用程序是否应该处理后台,或者它只是一个权限调用。
在权限请求后,可以使flag为true