簡體   English   中英

Appstate 繼續在 Android 中更改 React Native

[英]Appstate keep on getting change in React native in Android

我正在開發 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

它繼續,永不停止。

如何處理? 有什么建議么?

我有同樣的問題。 不要使用 AppState。 有故障。

問題在於 RN 對“背景”的定義。 react-native 使用 android 的活動(UI 線程的持有者和您的 UI 所在的位置)onPause 回調作為發送“背景”信號的觸發器。 但是,onPause 每次出現在您的活動視圖層次結構前面時都會調用,例如對話框(例如權限框)、其他活動(例如文件選擇器)等; 對於 android react-native,“背景”表示“被外部 UI 元素/android 任務遮蔽”而不是“暫停並發送到后台執行其他操作”,從而導致您看到的循環。 最短的解決方案是在 ReactActivity 中覆蓋 onPause,並添加控制條件以確保 super.onPause 僅在您實際進入后台時調用,例如檢查您的任務堆棧,或者如果正在調用權限對話框,因此您避免這種循環/錯誤調用。 第二種選擇是提供您自己的應用程序生命周期事件,並帶有明確的觸發條件。

今天我遇到了類似的問題。

我可以使用 android 中的“焦點”和 ios 中的“更改”來解決它。

我有一個這樣的自定義鈎子:

import { useEffect } from 'react';
import { AppState, Platform } from 'react-native';


const focusEvent = Platform.OS === 'ios' ? 'focus' : 'change';

const useLocationListener = () => {


  useEffect(() => {
    AppState.addEventListener(focusEvent, handleAppStateChange);

    getLocationAsync();
    return () => {
      AppState.removeEventListener(focusEvent, handleAppStateChange);
    };
  }, []);

  const handleAppStateChange = (nextAppState: string) => {
    if (nextAppState === 'active') {
      getLocationAsync();
    }
  };

  const getLocationAsync = async () => {
    const { canAskAgain, status } = await Permissions.getAsync(
      Permissions.LOCATION
    );

    if (canAskAgain) {
      const response = await Permissions.askAsync(Permissions.LOCATION);
       // handle location 
    } 
       // handle location with "status"
    
  };
};

export default useLocationListener;

您可以使用一個標志來檢查應用程序是否應該處理后台或者它只是一個權限調用。

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

並且在獲得許可請求后,您可以使標志為真

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM