Appstate 在 Android 中的 React Native 中不断变化

Ani*_*ive 9 android location geolocation addeventlistener react-native

我正在开发 React Native 项目,并且正在获取位置权限。此外,我必须始终跟踪位置权限,就像用户在安装应用程序后授予权限访问权限一样,然后在一段时间后用户转到设备设置中的应用程序设置并禁用/撤销权限。再次,一旦应用程序从后台进入前台,我必须基于此检查权限,需要显示消息。

所以,我正在使用 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);
    }
  };
Run Code Online (Sandbox Code Playgroud)

拒绝许可后继续打印(循环),不再显示

appState --> active
nextAppState --> background
appState --> active
nextAppState --> background
appState --> active
nextAppState --> background
appState --> active
Run Code Online (Sandbox Code Playgroud)

它继续并且永不停止。

如何处理?有什么建议?

Fco*_* P. 11

我有同样的问题。不要使用AppState。有故障。

问题在于 RN 对“背景”的定义。React-Native 使用 Android 的 Activity(UI 线程的持有者以及 UI 所在的位置)的 onPause 回调作为发送“后台”信号的触发器。但是,每当有东西出现在您的活动视图层次结构前面时,就会调用 onPause,例如对话框(如权限框)、其他活动(如文件选择器)等;对于 android react-native,“背景”意味着“被外部 UI 元素/android 任务遮蔽”,而不是“暂停并发送到后台执行其他操作”,从而导致您看到的循环。最短的解决方案是重写 ReactActivity 中的 onPause ,并添加控制条件以确保仅在实际进入后台时调用 super.onPause ,例如检查任务堆栈或正在调用权限对话框,这样就可以避免这种循环/错误调用。第二种选择是提供您自己的应用程序生命周期事件,并具有明确的触发条件。


Ehs*_*har 2

您可以使用一个标志来检查应用程序是否应该处理后台,或者它只是一个权限调用。

const shouldHandleBackground = useRef(true)

const handler = (state) => { 
    if (state === 'active' && shouldHandleBackground.current) { 
        doStuff() 
    }
}

// when calling for permisson make the flag false

shouldHandleBackground.current = false
await Android.permission.LocationPermission()
shouldHandleBackground.current = true
Run Code Online (Sandbox Code Playgroud)

在获得许可请求后,您可以将标志设置为 true