My app is a hybrid with a native login activity and a webview. In some cases you get a link in an email that navigates you to a certain screen inside the webview. This part works just fine, the webview opens and the user is taken to the correct adress.
When the link is clicked in outlook the whole app seems to open inside outlook and I can even reach my native login screen still inside outlook. It's like my webview is hijacked.
Is there something missing from my webview config?
AndroidManifest.xml:
`
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<application
android:allowBackup="true"
android:configChanges="orientation"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.Androidappshell"
android:usesCleartextTraffic="true">
<activity
android:name="package.name.LoginActivity"
android:exported="true"
android:theme="#style/Theme.App.SplashScreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="package.name.MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</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="https"
android:host="domain.com"
android:port="9201" />
</intent-filter>
</activity>
</application>
`
Webview setup:
#SuppressLint("SetJavaScriptEnabled")
private fun webViewSetUp(jsonData: String, url: String) {
wb_webView.webViewClient = object : WebViewClient() {
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
wb_webView.evaluateJavascript(
"javascript:localStorage.setItem('clientMode', 'android')", null
)
}
override fun onPageFinished(view: WebView, url: String) {
wb_webView.evaluateJavascript("javascript:setUpAngular($jsonData)", null)
}
}
wb_webView.clearCache(false)
wb_webView.loadUrl(url)
wb_webView.settings.javaScriptEnabled = true
wb_webView.settings.domStorageEnabled = true
wb_webView.addJavascriptInterface(JsWebInterface(this, this), "androidApp")
}
The problem was that my activities were not marked as singleton instances adding: android:launchMode="singleInstance" to my activites.
Related
I made a GET request
#GET("/oauth2/authorize?client_id=id&scope=scope&redirect_uri=http://localhost&response_type=token")
fun getContent():Call<ResponseBody>
and i get a access token, but, when i open webview, each second i'm getting new access token
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://id.twitch.tv/oauth2/authorize?client_id=id&scope=scope&redirect_uri=http://localhost&response_type=token"))
startActivity(intent)
after that code i get this webview, but this access token which i marked a red circle is changing each second, and in the logcat a am getting a lot of tokens, and when i press back button nothing happens,
webview updating all the time.
How to get access token one time and after it close the webview?
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".ui.activities.MainActivity">
<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:host="localhost"
android:scheme="http"/>
</intent-filter>
</activity>
</application>
I'm implementing deep-linking in android, what I'm trying to do is when a user clicks on the link, he gets redirected on the application, and this already works, but I also want that the user can see some values I pass inside the link.
Example:
My link is: https://examplelink.com/123456789. The application needs to get 123456789 code.
How do I do this?
NB: I've alredy put this on the manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.sendsharedlink">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter android:label="#string/app_name">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Accepts URIs that begin with "example://gizmosā -->
<data android:scheme="https"
android:host="examplelink.com" />
</intent-filter>
</activity>
</application>
I HAVE RESOLVED BY PUTTING:
Intent intent = getIntent();
String action = intent.getAction();
Uri data = intent.getData();
String[] link = data.toString().split("/");
txt.setText(link[3]);
Thanks for the help.
The first copy this code in manifest
<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:host="your host name"
android:pathPrefix="your path"
android:scheme="https" />
</intent-filter>
This is our app link: https://myapp.page.link/path?email=your#gmail.com&token=12345
and in my splash activity i get data with kotlin code:
Firebase.dynamicLinks
.getDynamicLink(intent)
.addOnSuccessListener(this) { pendingDynamicLinkData ->
// Get deep link from result (may be null if no link is found)
val data: Uri? = intent?.data
// get path
val path = data?.path
// get param
val email = data?.getQueryParameter("email").toString()
}.addOnFailureListener(this) { e -> MLog.e(TAG, "getDynamicLink:onFailure $e") }
I am on Android and I want to use DeepLink to open a specific screen using react navigation.
Here is my manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.samtbook">
<application
android:name=".MainApplication"
android:label="#string/app_name"
android:icon="#mipmap/ic_launcher"
android:roundIcon="#mipmap/ic_launcher_round"
android:allowBackup="false"
android:theme="#style/AppTheme"
android:supportsRtl="false"
android:usesCleartextTraffic="true"
>
<activity
android:launchMode="singleTask"
android:name=".MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter android:autoVerify="true">
<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="samtbook.me"/>
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="API_KET"/> // HIDDEN
</application>
and here is the link I use:
http://samtbook.me/test/
and I registered my deepLink like this:
componentDidMount() {
Linking.addEventListener('url', this.handleOpenURL);
}
componentWillUnmount() {
Linking.removeEventListener('url', this.handleOpenURL);
}
handleOpenURL = (event) => {
this.navigate(event.url);
};
navigate = (url) => {
this.props.navigation.navigate('TestScreen');
};
The poblem is When the app is not running in the background(Means dead)
I click over the link and it opens the app but not navigate to intended screen
but when the app is running in background it navigates
Thanks in advance
Use react navigation deeplinking mentioned in doc:
https://reactnavigation.org/docs/en/deep-linking.html
Http scheme is detected as a web url just change your scheme to a custom scheme for example "myapp" and change your url to myapp://samtbook.me/test/ good luck!
I've a React-Native app with the following code (here App.js, the app entry point) that manages deep link on Android.
Linking.getInitialURL().then((deepLinkUrl) => {
if (deepLinkUrl) {
manageDeepLink(deepLinkUrl);
} else {
Navigation.startSingleScreenApp('rootScreen');
}
});
The problem here is that getInitialURL is called every time I launch my app, from both deep link or normally, and everytime it contains deepLinkUrl parameter empty.
I've registered in AndroidManifest my intent as follows:
<application
android:name=".MainApplication"
android:allowBackup="true"
android:launchMode="singleTask"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:windowSoftInputMode="adjustResize">
<!-- deeplink -->
<intent-filter android:label="#string/app_name">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="myapp" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
UPDATE
I'm using react-native navigation to register screens, if this can e useful.
It seems it doesn't work if you register listener too soon in the app lifecycle (ex. directly in some .js file, so it's executed when app is loaded).
If you move it into componentDidMount() on the root component everything works fine.
componentDidMount() {
Linking.addEventListener('url', event => {
console.warn('URL', event.url)
})
Linking.getInitialURL().then(url => {
console.warn('INITIAL', url)
})
}
Because you added android:launchMode="singleTask" to AndroidManifest.xml. Please modify it to android:launchMode="singleTop", then your problem will be gone.
Hi custom url scheme is not working for me. Here is my code
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".MainActivity" android:label="#string/app_name"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.LAUNCHER" />
<data android:scheme="http" android:host="jinilabs.test" />
</intent-filter>
</activity>
</application>
when I type the url on the emulator browser - http://jinilabs.test
It is giving me web page not available error.
Is there anything wrong here? Plz let me know
Simply typing the URL into the bar won't do it. Your url needs to be a clickable link on a webpage because the browser method that checks if it's a custom url only fires when a link is clicked; it simply runs url's that are entered in the address bar(and ignores custom urls).
Clicking this link should launch your app as it is now. If it still doesn't work, you may need additional code in your manifest file. Mine looked like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="appcall.thing"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="4" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".AppCallActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<data android:scheme="stoneware.app.switcher" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>
</activity>
</application>
</manifest>
Of course, you will have to substitute some of the names in here for names relative to your app. I would also recommend starting your url scheme with something unique rather than http in case the http is confusing the browser. My url scheme, for example was stoneware.app.switcher://
Hopefully this can be of some use to you :)
Add this code to manifest file :
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
and then try.