Instant app with Dynamic Features always show Disambiguation dialog with 1 option - android

I'm experimenting with Dynamic Features and Instant Apps.
To navigate between various features, I use Deep Links.
Each time I navigate to another Activity, I see the disambiguation dialog for less than 1 second, with 1 app listed. Notice how the options for "Once" and "Always" (in dutch) are greyed out.
Sample Github Project
I created a minimalistic sample, that matches my current structure on Github. Requires Android Studio 3.5 - RC2
Some Context:
I'm quite confident, the deeplinks are configured correct. But since you guys want to check that anyway, here's the configuration:
1 - Manifest:
<activity
android:name=".ProfileActivity">
<intent-filter
android:autoVerify="true"
android:priority="100">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="giddy.entreco.nl"
android:pathPrefix="/profile"
android:scheme="http" />
<data android:scheme="https" />
</intent-filter>
</activity>
2 - Assetlinks
My domain contains a publicly accessible assetlinks.json
3 - Sha's are correct
The sha's I use are correct
Executing tasks: [signingReport] in project
SHA1: 3A:52:19:77:C1:AD:18:F4:98:21:77:74:37:DC:9B:89:02:64:6E:C6
SHA-256: 25:DD:C3:7B:8E:35:D3:39:D5:D4:6C:B5:EA:7D:14:AF:82:EC:9C:56:A6:F5:76:A3:E1:D7:69:B3:EC:58:72:E8
Valid until: Saturday, March 21, 2048
4 - Confirmed digital asset link file
All checks pass
https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://giddy.entreco.nl&relation=delegate_permission/common.handle_all_urls
5 - Testing a URL intent
Also works! The only problem is I see the disambiguation dialog for a brief period.
Additional info
I use apply plugin: 'com.android.dynamic-feature' in all my modules (except app off course)
Android Studio: 3.5 RC2; Android-gradle-plugin: 3.5.0-rc02
My Device is a OnePlus6 - with Oxygen 9.0.7 & Android 9
The google official sample also shows this behaviour on my device
Some Samsung devices, behave different. Instead of showing the Disambiguation with 1 option, it lists my app twice, and will keep waiting until you either select Once or 'Always'. (Note, I got this from the pre-launch reports in the play store)
I see this behaviour, no matter if I build an APK, an App Bundle or download through Google Play. It's always the same.
Any suggestions to get that annoying dialog out of the way?
When I analyse the apk/bundle, I do see two entries for the specific Activity. Once in the base module's manifest, but also in the profile module's manifest. I have little understanding of how Android/PlayStore merges those manifests while installing modules, but I guess it could make sense to see the dialog in this case.

So yes... I believe I have seen this before, it is some odd behavior when navigating from one dynamic-feature (instant) to another (non-instant) via a URL intent.
Until this gets addressed, I don't recommend using a URL intent to navigate between modules, instead, use reflection to directly get to the other module's activity, example:
if (doesModuleExist()) {
val intent = Intent()
.setClassName(getPackageName(), "com.sample.ProfileActivity")
.addCategory(Intent.CATEGORY_DEFAULT)
.addCategory(Intent.CATEGORY_BROWSABLE)
startActivity(intent)
}
Where doesModuleExist() checks if either:
examining your sample manifest, it looks like your profile module is not part of your instant app dist:instant="false", so you would never have access to it, therefore you could simply do a isNotInstantApp() check instead and never attempt the launch while as instant app.
once in your installed app, then you technically don't need to check, as it is always include="true"
but if your profile module is an onDemand module, or just for safety precautions, you should utilize splitInstallManager.getInstalledModules(), see /app-bundle/playcore#manage_installed_modules (note, you can also use this API in your instant app)
And since it looks like this odd behavior varies between different devices, that might mean they've implemented subtle differences in intercepting and handling that URL intent, and/or it's just a different Android version (pre-O vs O+).
Also yes, associating multiple package names to a single website domain for common.handle_all_urls might cause some additional misbehavior when the system tries to verify the association when your app goes live.

There is a possible solution for using URI intents with dynamic features instead of switching to reflection. You can use a trick where you can get the needed class name during run time with packageManager.queryIntentActivities(), so you don't have to use the hardcoded Activity name.
The following extension function is an example of how you could convert your Intent using the URI or deep link into one that will not show the chooser dialog:
fun Intent.convertToSafeDynamicFeatureModuleIntent(context: Context) {
//Get list of all intent handlers for this Intent. This should only be the actual activity we are looking for
val options = context.packageManager.queryIntentActivities(this, PackageManager.MATCH_DEFAULT_ONLY)
//Set the activity that supported the given intent
setClassName(packageName, options[0].activityInfo.name)
}
Then you can simply do:
intent.convertToSafeDynamicFeatureModuleIntent(context)
startActivity(intent)
A longer explanation can be found here

Related

Android deep link using intent not opening app

I am trying to open an app that I made from mobile chrome browser.
https://developer.chrome.com/multidevice/android/intents
From this link, I figured that I must use the "intent:" syntax to do the job.
However, my app doesn't open. Instead, it opens the Google Play Store, but the store just shows the "item not found" page.
I would love to know if I'm doing anything wrong.
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="myscheme" android:host="myhost" android:path="/"/>
</intent-filter>
This is the intent filter that I wrote.
var androidIntentUrl = 'intent://myhost/#Intent;scheme=myscheme;package=my.test.app.package;end';
if(!isIOS && isChromeAndBiggerThanVer25()) {
location.href = androidIntentUrl;
}
And this is what I wrote on the web.
Must the app be released on Play Store to make this happen?
I don't quite understand the whole stuff yet.
I want to know what's wrong.
PS) The names "myscheme" and "myhost" are just names that I made up for writing this question. The actual names in my code match those written in my project settings and all, including the package name.
As Alexey commented on my post,
<a href="myscheme://myhost/some/other/parameters">
worked just okay for me.
I double checked the official document (the link on my post) and my chrome version (which is 71), so I have no idea why the intent:// syntax did not work.
I guess there were changes on mobile Chrome after version 25 that I missed or couldn't find.
I just encountered the same problem where linking with Intents did not work but the direct scheme linking did. However, I didn't want to use the direct version to have a fallback redirect to the PlayStore.
The solution was that the package parameter in the intent link did not have to match the package given in the AndroidManifest.xml. I was working with a Unity project and had to use the bundle name given in the project setting.
tl;dr: this is still working in Chrome (v78), but the package parameter is not necessarily the package given in the manifest.
The package parameter should match your application id (found in build.gradle or your AndroidManifest.xml)
The sample code above shows package as my.test.app.package, if this is not your app package name or if the app is not installed, the intent will default to the Google Play Store to search for it. Similarly, it would be best change the host and scheme parameters to something custom to your app if you haven't already.
My answer is to open android application from web app using deep linking:
Flipkart - Open Flipkart!
WhatsApp - Open WhatsApp!
Clash Royale - Open Clash Royale!
FaceBook - Open FaceBook!
If the listed application is installed in your mobile then only it will open or you have to handle the case separately.

android Adding Account with AccountManager, No Activity found to handle Intent { act=android.settings.ADD_ACCOUNT_SETTINGS (has extras) }

in some phones (in a certain "oneplus" android v6.0.1 to be exact) . I'm getting No Activity found to handle Intent { act=android.settings.ADD_ACCOUNT_SETTINGS (has extras) } error when I try to call up the account add screen with what seemed to be the "right" way.
Intent intent = new Intent(Settings.ACTION_ADD_ACCOUNT);
intent.putExtra(Settings.EXTRA_ACCOUNT_TYPES, new String[]{Constants.ACCOUNT_TYPE});
startActivity(intent);
I can seemingly add
<intent-filter>
<action android:name="android.settings.ADD_ACCOUNT_SETTINGS" />
</intent-filter>
to my login activity, but should I even do that? if so why is it working on most phones but crashing on one. I want my account intent to go through as if the user is trying to create an account through the phone's settings screen and this seems like a bad shortcut.
I finally found the problem. apparently the phone which I addressed was running on a cyanogen and for whatever reason where other android 6 phones (and emulator) did not require GET_ACCOUNT permission for a request for my own application's account, this phone did.
the error says nothing about lacking permission however after acquiring GET_ACCOUNT with run-time request, it functions as expected.
Four things are needed to set up the Custom accounts in android. Implement Abstractaccountauthenticator to expose methods to add accounts etc. Extend AccountAuthenticatorActivity the view part of the deal. In the android manifest a refrence to an xml resource file that itself refers to icons, string labels and the xml resource file.
Now I suspect you are using a pre-existing account type, google perhaps, that works on most phones. Everything android has gmail or googleplay store. some google app. So the big question is what is the value of Constants.ACCOUNT_TYPE in your code and do you want to make your own custom account type?

App links intent filters in assetlinks.json not working on Android

My app defines the intent filters to handle URL's from my site defined by
<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:host="www.host.com" android:scheme="http"/>
</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:host="www.host.com" android:scheme="https"/>
</intent-filter>
The app correctly detects URL's of the correct host but queries the user whether to open them in the app or browser. I tried using the App links verification as specified here: https://developer.android.com/training/app-links/index.html
As seen in my server logs, when installing the app, the device queries /well-known/assetlinks.json and it responds with a 200 status. Testing the digital assets file using the
https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://<domain1>:<port>&relation=delegate_permission/common.handle_all_urls
API and it found no errors.
The SHA256 in the assetlinks.json file was obtained using
keytool -list -v -keystore my-release-key.keystore
the same .keystore of which the app was signed.
Running adb shell dumpsys package d returns that the link verification status is "ask" meaning that verification failed. Why might verification be failing?
For us it was Windows line endings!
Testing with "https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://domain1:port&relation=delegate_permission/common.handle_all_urls" proved invaluable as it gave us an "Could not parse statement list (not valid JSON)" error which led us to the problem.
TIP: It was good to use the 'Save File' button in the Android Studio App Links Assistant instead of copying and pasting as we did - that way it generates the file itself and is guaranteed not to have this issue.
There are some common pitfalls which you should check twice (I don't say that you did it wrong. It is just a check list):
Verify that the assetlinks.json is valid and stored accessible from https://example.com/.well-known/assetlinks.json to do that you need to visit https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site= https://example.com&relation=delegate_permission/common.handle_all_urls, there must be no errors.
If you link multiple domains at once, check that all domains are setup correctly as in step 1.
Make sure that those <intent-filters> which contain your <data> tags have the attribute android:autoVerify="true".
Verify that you have the required <meta-data> tag in your <application> tag:
<meta-data
android:name="asset_statements"
android:resource="#string/asset_statements"/>
The content of the asset_statements string must be:
<string name="asset_statements" translatable="false">[{\"include\": \"https://example.com/.well-known/assetlinks.json\"}]
Use for debug also the release signing certificate (don't be scared you cannot upload it accidentally) use this in your build.gradle:
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
debug {
debuggable true
signingConfig signingConfigs.release
}
}
Looking at j__m comment, I found this.
In AndroidManifest write so:
<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" />
<!-- Write <data> tags with one attribute, if you use several domains. -->
<data android:scheme="https" />
<data android:host="example.com" />
</intent-filter>
<!-- Other domains-->
<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="https" />
<data android:host="server.com" />
</intent-filter>
android:autoVerify="true" is needed for App Linking.
Create assetlinks.json using Tools > App Links Assistant. Then press Open Digital Asset Links File Generator, enter domain, application id, select release signing config and press Generate Digital Asset Links File. Then you can save file or copy to clipboard.
You can create several assetlinks.json files (for several applications) and join them into one JSON. To my mind it doesn't depend on Windows line endings (I used Notepad to concatenate JSONs). First time I auto-formatted it with Ctrl + Alt + L, and after uploading to domains App Link didn't work (probably because of later errors in AndroidManifest), so on the 2nd try I didn't format JSON. I created assetlinks.json for release and debug builds of the application.
Upload assetlinks.json to https://example.com/.well-known/assetlinks.json (in this answer I write: example.com and mean your domain like company.name). Check it with https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://example.com&relation=delegate_permission/common.handle_all_urls. The file and the domain have some restrictions. In my case everything was simple, we didn't change settings.
In your DeepLinkActivity you can parse URLs with regular expressions. Use JUnit to create tests. Call this method from onCreate():
private fun processDeepLink() {
if (intent?.data?.isHierarchical == true) {
val data = intent?.dataString
if (intent?.action == Intent.ACTION_VIEW && data != null) {
when {
REGEX.matches(data) -> // Get id and open some screen.
else -> // Either open MainActivity or skip this URL (open web browser instead).
}
finish()
}
}
}
companion object {
val REGEX = "^https://example.com/some_request/(\\d+).*".toRegex()
}
Warning! If you open a web browser from the application, you will fall into a loop. When clicking a link to your domain in the application, a browser won't appear, but your application will be opened automatically! What a surprise! So, in processDeepLink you should check the URL and open MainActivity when URL matches one of your masks. Skip others. Now a user will see a dialog with a list of browsers and your application (like in Deep Link). This happens because your application also handles links to your domains, like a browser.
You can also use WebView instead of a browser (not a good solution), open Chrome Custom Tabs or Chrome.
Use device with Android 6 or later.
If https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://example.com&relation=delegate_permission/common.handle_all_urls returned no errors, build the application. Create an Email message, SMS, QR-code or another application with a link to your domain. Click it, and App Link will open your application or Deep Link will show a dialog to choose an application.
If App Link didn't work, read later.
In LogCat select No Filters and type IntentFilter into search box. There should be:
I/IntentFilterIntentOp: Verifying IntentFilter. verificationId:2 scheme:"https" hosts:"example.com" package:"com.my_package".
I/IntentFilterIntentOp: Verification 0 complete. Success:true. Failed hosts:.
Probably you will get:
I/IntentFilterIntentOp: Verifying IntentFilter. verificationId:0 scheme:"https" hosts:"example.com server.com" package:"com.my_package".
I/IntentFilterIntentOp: Verification 0 complete. Success:false. Failed hosts:server.com.
Later you will try to fix domains in the application, so sometimes you can launch for clean install:
adb shell pm clear com.android.statementservice
Start adb shell dumpsys package d and find your domains. There should be:
Package Name: com.my_package
Domains: example.com server.com
Status: always : 200000000
But probably it will be:
Package Name: com.my_package
Domains: example.com server.com
Status: ask
See also https://chris.orr.me.uk/android-app-linking-how-it-works/. Strange, but in an emulator it wrote: always, while App Link didn't work.
I also tried adb shell am start -a android.intent.action.VIEW -c android.intent.category.BROWSABLE -d "https://example.com" to test App Link without a browser, but later it didn't work.
If you have several domains, comment (or remove) other domains in AndroidManifest (retain only one domain, for example, "example.com"). Then click a URL https://example.com/something and check it uses App Link.
In my case I checked release and debug builds of the application. While the debug build worked with App Link, release didn't (and sometimes vise versa). I used the solution of rekire:
<meta-data
android:name="asset_statements"
android:resource="#string/asset_statements"/>
and it helped for 2 domains, but later stopped, so I removed it. In the end I wrote in AndroidManifest <data> tags with one attribute as j__m said.
Even if only one domain was failing, App Link was not working for other domains either. You can check domains one by one retaining only one domain each time in AndroidManifest.
See also http://androidideas.com/handling-app-links-in-android/, https://willowtreeapps.com/ideas/a-better-user-experience-for-deep-linking-on-android, https://developer.android.com/training/app-links/verify-site-associations,
For me, it came down to checking all the basics:
Verify my assetLinks file is good with this tool: (replace domain1:port with your domain)
https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://domain1:port&relation=delegate_permission/common.handle_all_urls
Always test with a signed APK
Make sure the test device is running Android 6.0 or later (this is the one that bit me because I forgot it - on older versions of android, you always get the user prompt)
For me, it was the fact that my assetlinks.json file was UTF-8 and contained a byte-order mark (BOM), which is a three-byte magic number at the head of the file that signals the encoding to a consuming program. The BOM is optional, and apparently the Google / Android tools do not like to see it. When it was present, Google's digital asset links verifier (URL below) gave me a "malformed JSON" error.
If you're using Visual Studio, here's how to determine if you have the BOM in your file, and remove it if necessary:
Right-click your assetlinks.json file.
Choose "Open With..." from the context menu.
Choose "Binary Editor" in the "Open With" dialog.
Examine the file bytes. If the file starts with EF BB BF, that's the problem.
Delete those characters (you can do this via either column) and save the file.
Re-upload the file and test it using the Google tools (URLs below) and it should work properly for you.
Here's the URL you can use to check your file (replace example.com with your actual URL):
https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://example.com&relation=delegate_permission/common.handle_all_urls
Update
So I resolved my issue. Not sure which one did it (might have been a combination), but this is what I did:
Uninstalled "Google Play Services for Instant Apps": I had previously tinkered around with Instant Apps, so I thought maybe some old configurations might be sticking around like the debug package name, however this is unlikely.
Stopped using proxies: Proxies are helpful for debugging network calls, but HTTP/2 might not be fully supported on the tools I'm using.
Delete intent filter for legacy subdomains: This is the big one. One of my subdomains has been deprecated and is no longer available. In the AndroidManifest, if you have multiple hostnames declared for an activity that contains at least one autoVerify intent filter, each host is checked for the Digital Asset Link JSON file. If autoVerify fails for even one of the hosts, then none of the hosts are auto verified.
Original
When I first faced this issue, it was because my network was blocking calls to Google's servers for verifying the app links.
As OP and other answers have touched on, in general the API call to endpoint:
digitalassetlinks.googleapis.com
must be successful to bypass the chooser dialog.
This is the web call the Android system makes, to verify the Digital Asset Link JSON file, and seems to be made upon app install/update. A helpful place to look is the Logcat, searching for items with the text "I/SingleHostAsyncVerifier:". If you see "--> true" at the end of the log, your app
Lately though, these calls have been failing for me due to what appears to be some bug which may have been introduced recently. The device is receiving this response from the API call above:
Error: unavailable: Wrong content type in HTTP response headers while fetching statements from {host}/.well-known/assetlinks.json (which is equivalent to '{host}/.well-known/assetlinks.json'): expected 'Content-Type: application/json' but found text/html [11] while fetching Web statements from {host}./.well-known/assetlinks.json
It's been awhile since I last looked at these requests, so I don't remember what they looked like before. But it seems possible that there may have been some recent update involving App Links or the Android networking framework, where they switched over to protocol buffers for this feature (and forgot to support it in another one).
Another indication that things may have changed, is that the request path today appears different from the ones mentioned in the previous answers:
https://digitalassetlinks.googleapis.com/google.digitalassetlinks.v1.AssetLinks/Check
I'm sure this doesn't answer the original question, as I think it pre-dates Android App Bundles, but the thing that was ultimately causing a failure for me was that I'd enabled Google Play Console re-signing of the app (required for AABs) and therefore the SHA-256 fingerprint I was getting from keytool did not match the digital signature of the downloaded app.
Updating my assetlinks.json with the fingerprints from the console solved it.
In our case we had 2 intent filters with applinks in our manifest: one with autoVerify="true" and one without.
So the verifier tried to verify domains for the 2nd intent filter and failed, and treated all our applinks as "not verified". You can find more details in this question.
You have to make sure every applink can be verified (which means adding assetlinks.json for every domain to be verified).
In my case, adb shell dumpsys package d revealed that the packageName was incorrectly configured in assetlinks.json. I had used the package attribute value of my manifest tag in AndroidManifest.xml, but I should have used the android.defaultConfig.packageId value in my build.gradle file.
System app selection window in two cases
1) User makes changes to settings related opening links by going to settings > apps > gear icon > opening links > select an app > open supported links > choose prompt every time.
2)Default app is not set by user and auto verify is not enabled in one of the app links supported app
I think in your case auto verify is enabled, so please check user settings.
For me, don't change anything of assetlinks.json including trimming blanks and line-breaks.
Thanks for all the other answers here, I was able to find my issue. In spite of doing everything right. This was my problem.
If your project is huge, chances are you have multiple android module dependencies. Check the merged manifest to find all the activities with intent filter(with autoverify = true).
How this can go wrong is simple. If a project has multiple autoverify urls, then the OS tries to verify it all. Even if one fails then the OS fails the verification of every URL.
Open the manifest file in your main app module, then choose the Merged Manifest option from the bottom tab. Now check the Manifest sources(list) on the right and manually look up manifest files of every library project.
In my case, a third-party library's auto verify flag was enabled. My two-day search comes to an end. Good luck to you.

Deep linking via Google Search - how it works, and what to put in the manifest?

Background
I need to investigate how to integrate with the new (?) Google search deep linking feature.
The problem
This seems like a relatively new feature that's still not so popular, so I can't find a lot of resources about how it works and how to configure it correctly.
What I've tried
I've read some websites of Google and watched some of its videos:
https://www.youtube.com/watch?v=kYLrK-gD2Yg
https://www.youtube.com/watch?v=UjLJoMWSXts
https://developers.google.com/app-indexing/webmasters/app
https://support.google.com/googleplay/android-developer/answer/6041489
https://developers.google.com/app-indexing/webmasters/appindexingapi
https://developers.google.com/app-indexing/
https://plus.google.com/+AppIndexing/posts
http://googlewebmastercentral.blogspot.co.il/2014/06/android-app-indexing-is-now-open-for.html
from what I understand, I need to register the app, change the data (intent handling) in the manifest for an activity, and change the code of the activity too, but I'm not sure I understand how it all works and what's the best way to configure it.
The questions
Even after that much reading, I would still like to ask some questions about deep linking using Google Search:
First, the basic question, to verify that I know what it's all about: It lets apps to be indexed via the "Google Search" app, but those apps must be installed too. Once the user clicks an item within "Google Search" app, it goes to your app and you get the query. Is this correct? Is there anything more than that?
They wrote that minSdkVersion should be 17 or below (here). How come it's "or below" instead of "or above" ?
For some reason, the query of the examples (like here) are of just simple texts, but the app is shown there. Why is it shown? What in the manifest tells Google-Search that the app can handle this query? The code examples show URLs ...
Is it possible to test the deep linking via Google Search without registering it (here) ? All I've found is how to test it via adb, but I don't understand where in the example (here) is the query that the user enters.
Do the deep linking require an actual website that users can visit via the web browser ? I ask this because there is a step called "Verify website" when registering to the service (here) .
Suppose I want to allow the user to search for a phone number via the app. Should I put "tel:" in the "scheme" (as shown here) part inside the manifest? Or is it something else(or more than that)? Would Google-Search know exactly when to show the app (for example, when the phone number is valid)?
Is it possible to use this feature in case the app isn't installed, so that it would encourage people to download the app, and/or search via a real website?
Even when trying to test it, I've failed. Manifest:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<!--should match to : https://somehost/search/?number=-->
<data android:scheme="https"
android:host="somehost"
android:pathPrefix="/search/?" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
code:
Intent intent = getIntent();
String action = intent.getAction();
Uri data = intent.getData();
Log.d("AppLog", "action:"+action+" data:"+data);
adb command (from here) :
adb shell am start -W
-a android.intent.action.VIEW -d "somehost/search/?050" com.example.user.myappli
cation
Starting: Intent { act=android.intent.action.VIEW dat=somehost/search/?050 pkg=c
om.example.user.myapplication }
Error: Activity not started, unable to resolve Intent { act=android.intent.actio
n.VIEW dat=somehost/search/?050 flg=0x10000000 pkg=com.example.user.myapplicatio
n }
I've even tried the exact sample, but with a different package name, and it still didn't work.
What's wrong here?
Google Search app and google.com in Chrome as well. User needs to be signed-in. If app is installed, clicks will deep link to your app.
If the app is not installed, participating in App Indexing can help drive installs:
http://googlewebmastercentral.blogspot.com/2015/04/drive-app-installs-through-app-indexing.html
Also, an indexed app is considered "mobile-friendly" which is a ranking signal. Look for "finding more mobile friendly search" on the same blog.
If your minSdkVersion is 15, 16, 17 that's okay. If it's 18, then that's not okay.
If your app is indexed by Google, deep links to your app can appear in Google Search results for users that have your app installed. Google learns about your app's supported deep links when you tell Google about these links via website markup, your sitemap, or by connecting your website. Look for "Provide Deep Links" in the app indexing documentation.
In order to see what queries your content could show up for, go to the new Search Console (g.co/searchconsole) and sign in. Then, you need to look at what sort of traffic your website is getting from Google and what impressions and clicks your content is getting for what queries. If your app supports the same links and you've provided these app deep links to Google, then these are the same queries your app deep links should show up for.
For App Indexing, website is required -- need to tell Google mapping from a web URL to an app deep link, either through sitemap, website markup, or by verifying your website. But if you do either a sitemap or markup, you don't need to verify your website. If you're just talking about your app supporting deep linking, a website is not required for that.
You can use whatever scheme you want for your deep links, so I would guess that tel: should work (though haven't tried it myself). However, Google won't automatically know when to show this phone number until you've provided a mapping to your web content. See #3.
Yes. As of April 2015 this is now possible. See link in answer to #1.
Some suggestions:
In the manifest file, make path prefix "/search".
For adb command, try specifying your link as
"https://somehost/search"
If that doesn't work, it's possible you need to enter a website for your host, i.e. you need a domain. If that's not what you want to do, just create a custom scheme for testing purposes, e.g.
<data android:scheme="example"
android:host="gizmos" />

How to build an app similar to a suite

I wanna build an app similar to MS office kinda thing; The issue is I've designed each app independently including a home app which contains the links to them. I wanna know how to design it in a way such that if i install the home app, it should automatically trigger the other apps' installation; can i do that?
thanks in advance
Since I am not quite sure what you mean by trigger the other apps' installation, I can see this going 2 ways.
Your entire app and all functionality is installed in one go, and you want a separate icon to be shown in the launcher for each of your word, power point etc. sub apps. In such a case, add the following to the <activity> tag of the main activity you want launched from the sub apps:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
You want one base app, which when installed shows icons to launch the other apps, downloading and installing them if the user clicks on the icon. In such a case, you can check is the app you need is installed using the PackageManager, something like the following. If the app isn't installed, you can prompt the user to download it from an app store if you've published it there, or from your own file server, and then use an intent to install it.
try {
ApplicationInfo info = getPackageManager().getApplicationInfo("your.package.name", 0);
//installed
} catch(NameNotFoundException e) {
//Not installed
}
You may probably use different apk, here's a link that relates to your question and probably step your through doing a multiple apk package.
Multiple Android Application Package .apk files from single source code

Categories

Resources