私はeコマースアプリベースの反応ネイティブを作成しています。ここで、共有されたURLから単一の製品ページを開く必要があります。実際には、アプリが強制終了状態にあるときに機能しますが、アプリがバックグラウンド/非アクティブ状態にある場合は機能しません。バックグラウンド/非アクティブ状態で開くと、共有URLがnullになります。コードを添付しました。
// following code working for app killing state
componentWillMount() {
if (Platform.OS === 'Android') {
console.log("Testing");debugger
//Constants.OneTimeFlag == false;
Linking.getInitialURL().then(url => {
console.log(url);
var str = url
var name = str.split('/')[4]
Constants.isLinking = true;
this.setState({ shop_Id: name})
if (str)
{
this.setState({ isFromHomeLinking:'FROM_LINK' })
this.props.navigation.navigate('SingleProductScreen', { ListViewClickItemHolder: [this.state.shop_Id,1,this.state.isFromHomeLinking] });
}
});
}
else {
Linking.addEventListener('url', this.handleNavigation);
}
}
Not working code following..
componentDidMount() {
AppState.addEventListener('change', this._handleAppStateChange);
}
componentWillUnmount() {
AppState.removeEventListener('change', this._handleAppStateChange);
}
this.state.appState declared in constructor(props)
_handleAppStateChange = (nextAppState) => {
if (this.state.appState.match(/inactive|background/) && nextAppState === 'active') {
console.log('App has come to the foreground!');debugger
if (Platform.OS === 'Android') {
console.log("Testing");debugger
//Constants.OneTimeFlag == false;
Linking.getInitialURL().then(url => {
console.log(url);
var str = url
var name = str.split('/')[4]
Constants.isLinking = true;
this.setState({ shop_Id: name})
if (str)
{
this.setState({ isFromHomeLinking:'FROM_LINK' })
this.props.navigation.navigate('SingleProductScreen', { ListViewClickItemHolder: [this.state.shop_Id,1,this.state.isFromHomeLinking] });
}
});
}
else {
Linking.addEventListener('url', this.handleNavigation);
}
}
}
whatsappとアプリからバックグラウンド状態で外部リンクを開くと、Linking.getInitialURL()がnullとして受信されました。
以下はマニフェストファイルにあります
<activity
Android:name=".MainActivity"
Android:label="@string/app_name"
Android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
Android:windowSoftInputMode="adjustResize"
Android:launchMode="singleTask">
<intent-filter>
<action Android:name="Android.intent.action.MAIN" />
<category Android:name="Android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action Android:name="Android.intent.action.VIEW" />
<category Android:name="Android.intent.category.DEFAULT" />
<category Android:name="Android.intent.category.BROWSABLE" />
<data Android:scheme="http"
Android:Host="demo1.zgroo.com" />
</intent-filter>
</activity>
以下は私のサンプルURLです。
解決策を教えてください。
前もって感謝します..
フックを使用したAnuragの回答のバージョンは次のとおりです。
export function useDeepLinkURL() {
const [linkedURL, setLinkedURL] = useState<string | null>(null);
// 1. If the app is not already open, it is opened and the url is passed in as the initialURL
// You can handle these events with Linking.getInitialURL(url) -- it returns a Promise that
// resolves to the url, if there is one.
useEffect(() => {
const getUrlAsync = async () => {
// Get the deep link used to open the app
const initialUrl = await Linking.getInitialURL();
setLinkedURL(decodeURI(initialUrl));
};
getUrlAsync();
}, []);
// 2. If the app is already open, the app is foregrounded and a Linking event is fired
// You can handle these events with Linking.addEventListener(url, callback)
useEffect(() => {
const callback = ({url}: {url: string}) => setLinkedURL(decodeURI(url));
Linking.addEventListener('url', callback);
return () => {
Linking.removeEventListener('url', callback);
};
}, []);
const resetURL = () => setLinkedURL(null);
return {linkedURL, resetURL};
}
その後、次のもので使用できます。
const {linkedURL, resetURL} = useDeepLinkURL();
useEffect(() => {
// ... handle deep link
resetURL();
}, [linkedURL, resetURL])
関数resetURL
を追加しました。ユーザーが同じファイルをアプリと2回共有する場合、2回ロードする必要があるためです。ただし、ディープリンクが同じになるため、useEffect
は再度トリガーされません。 linkedURL
をnullに設定することで、再度トリガーすることができます。これにより、次回ファイルが共有されたときに、useEffect
が実行されることが確実になります。
また、decodeURI
を使用して、渡されたURLをデコードしました。react-native-fsなどのライブラリを使用して、指定されたパスからファイルをロードすると、スペースが含まれているファイルを処理できないためです。 decodeURI
を使用する場合を除き、名前。