当应用程序处于后台状态 React native 时深度链接不起作用
Deep linking not working when app is in background state React native
我正在创建基于 React 的电子商务应用程序 native.here 我需要从 url 打开单个产品页面 shared.actually 当应用程序处于终止状态时它会工作,但如果应用程序处于 background/inactive 状态,它不会工作。在 background/inactive state.I 上打开时共享 url 变为空已附上我的代码。
// 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 和应用程序打开外部 link 时 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..
请告诉我任何解决方案..
提前致谢..
您需要为此案例注册链接侦听器。
componentDidMount() {
Linking.addEventListener('url', this._handleOpenURL);
},
componentWillUnmount() {
Linking.removeEventListener('url', this._handleOpenURL);
},
_handleOpenURL(event) {
console.log(event.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
,因为如果用户与该应用程序共享同一个文件两次,您会想要加载它两次。但是,因为深度 link 最终会相同,所以 useEffect
不会再次被触发。您可以通过将 linkedURL
设置为空来使其再次触发,因此下次共享文件时,您可以确定它会导致 useEffect
变为 运行。
此外,我使用decodeURI
解码传入的URL,因为如果你使用像react-native-fs这样的库从指定路径加载文件,它不会除非您使用 decodeURI
.
,否则能够处理名称中带有空格的文件
从 componentwillunmount
中删除侦听器。
无需在componentwillunmount
中编写任何代码,因为链接的addListener
将始终监听,然后只有当您从后台(通过单击新的深层链接)进入活动状态时才会触发。
我正在创建基于 React 的电子商务应用程序 native.here 我需要从 url 打开单个产品页面 shared.actually 当应用程序处于终止状态时它会工作,但如果应用程序处于 background/inactive 状态,它不会工作。在 background/inactive state.I 上打开时共享 url 变为空已附上我的代码。
// 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 和应用程序打开外部 link 时 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..
请告诉我任何解决方案..
提前致谢..
您需要为此案例注册链接侦听器。
componentDidMount() {
Linking.addEventListener('url', this._handleOpenURL);
},
componentWillUnmount() {
Linking.removeEventListener('url', this._handleOpenURL);
},
_handleOpenURL(event) {
console.log(event.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
,因为如果用户与该应用程序共享同一个文件两次,您会想要加载它两次。但是,因为深度 link 最终会相同,所以 useEffect
不会再次被触发。您可以通过将 linkedURL
设置为空来使其再次触发,因此下次共享文件时,您可以确定它会导致 useEffect
变为 运行。
此外,我使用decodeURI
解码传入的URL,因为如果你使用像react-native-fs这样的库从指定路径加载文件,它不会除非您使用 decodeURI
.
从 componentwillunmount
中删除侦听器。
无需在componentwillunmount
中编写任何代码,因为链接的addListener
将始终监听,然后只有当您从后台(通过单击新的深层链接)进入活动状态时才会触发。