Deep linking in .NET MAUI app on Android only partially works - android

I am trying to implement deep linking in my app. That is, when a user goes to my website, it should open the app.
I feel like I am missing something small to get this to finally work but I don't know what. Below my description I'll attach screenshots of everything I mention.
To test if it works, I've created a webpage with two links on it. One link links to the Application ID (which in my case is "il.co.lilo.journal_app_v2") so the link is: https://il.co.lilo.journal_app_v2/bubu/1. When clicking on it, the app opens and I handle the event in the MainActivity.cs file, in the OnCreate event. So that works (though when you go back to the browser it shows an ugly 'Site can't be reached' error).
The other link, links to my website "https://lilo.co.il/bubu/1". Clicking on this link simply goes to the website without opening the app and this is what I need help with.
I've created the assetlinks.json and it exists at https://lilo.co.il/.well-known/assetlinks.json
For testing I created an APK using the keystore file I used for the assetlinks.json file and installed on my phone.
My MainActivity.cs file has the following Intent Filters:
[IntentFilter(new[] { Android.Content.Intent.ActionView },
DataScheme = "http",
DataHost = "lilo.co.il",
DataPathPrefix = "/bubu",
AutoVerify = true,
Categories = new[] { Android.Content.Intent.ActionView, Android.Content.Intent.CategoryDefault, Android.Content.Intent.CategoryBrowsable })]
[IntentFilter(new[] { Android.Content.Intent.ActionView },
DataScheme = "https",
DataHost = "lilo.co.il",
DataPathPrefix = "/bubu",
AutoVerify = true,
Categories = new[] { Android.Content.Intent.ActionView, Android.Content.Intent.CategoryDefault, Android.Content.Intent.CategoryBrowsable })]
[IntentFilter(new[] { Android.Content.Intent.ActionView },
DataScheme = "http",
DataHost = "il.co.lilo.journal_app_v2",
DataPathPrefix = "/bubu",
AutoVerify = true,
Categories = new[] { Android.Content.Intent.ActionView, Android.Content.Intent.CategoryDefault, Android.Content.Intent.CategoryBrowsable })]
[IntentFilter(new[] { Android.Content.Intent.ActionView },
DataScheme = "https",
DataHost = "il.co.lilo.journal_app_v2",
DataPathPrefix = "/bubu",
AutoVerify = true,
Categories = new[] { Android.Content.Intent.ActionView, Android.Content.Intent.CategoryDefault, Android.Content.Intent.CategoryBrowsable })]
The HTML for the page I created to test is:
https://il.co.lilo.journal_app_v2/bubu/1<br>
https://lilo.co.il/bubu/1<br>
When clicking on the top link (https://il.co.lilo.journal_app_v2/bubu/1) my app opens great but when I go back to the browser, I see this which is not good:
When I click the second link, as I said before, it simply goes to the website even though when I look at my apps "Supported web addresses" in the App Info:
I can see it shows my site URL:

Okay, So I finally got it to work.
The following steps are what I did to get it working (please correct me if there is an easier way)
I created an app in the Google Play console and then created a bundle in VS and uploaded it (in other words you can't test deep linking without opening a Google development account).
I then went to Grow -> Deep Links in the Google Play Console
It will give you details about the links defined in your manifest and will point out any issues. It will also check your assetlinks.json on the webiste and will tell you what your assetlinks.json needs to have if what you have is incorrect (in my case it had changes which I did)
The link still did not work when testing in the emulator. It only worked after downloading the APK from the Google Play Console and installing on my phone: and then
At this point, clicking on the link in a browser on my physical phone, opened my app correctly

Related

Xamarin Android How to declare Intent Filter correctly to match custom file types?

I am currently working on an app which features should include a custom file extension to which my app is connected. What I basically want is that when I click the custom file in the Android file system my app starts automatically and reads the file contents. To achieve this I tried to implement an Intent Filter, but I just can't get it to work.
How my IntentFilter looks:
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable }, DataMimeType ="*/*" ,DataSchemes = new[] { "file","content" }, DataPathPattern = ".*\\.cm")]
My problem is that this filter does recognize .cm files but also every other file which is not what I want. I tried many different solutions which didn't match every file type but also not files of type .cm. Also I read that DataHost has to be specified or otherwise DataPathPattern will be ignored, but when I also include DataHost in the declaration, nothing works anymore.
Any help will be appreciated, thanks!
Do you want to achieve the result like following result?
If so, please change your IntentFilter like following format.
[IntentFilter(new[] { Android.Content.Intent.ActionView, Android.Content.Intent.ActionEdit }, Categories = new[] { Android.Content.Intent.CategoryDefault }, DataMimeType = "application/octet-stream", DataHost = "*", DataPathPattern = ".*\\.cm")]
You can google:Registering Your Android App for File Types and Email Attachments, It is an helpful article about it

Applinking in Xamarin.Forms

I have developed a browser(Xamarin App) named "MyBrowser" and now what I want is if a user clicks on any link it should open up a list of browsers (along with "MyBrowser") available for the user.
Once the user selects "MyBrowser", from there it should open the link in "MyBrowser".
If you're trying to catch all the web URLs such as the ones that start with http:// and https://, you can certainly do it on Android but on iOS it's not possible. I'll present a minimal example of how to catch the URL in your application, that should be a good starting point for you to move forward.
Android
On Android, you first need to decorate your main Activity with the IntentFilter attribute that defines the actions, categories and data schemes to utilize (this is basically the same as what you pasted to the comment section but in C#):
[Activity(Label = "UrlSample", MainLauncher = true)]
[IntentFilter(new[] { Intent.ActionView },
Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
DataSchemes = new[] { "http", "https" })]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
...
While the app is compiled, these attributes are parsed and inserted into the final AndroidManifest.xml file. For more information about the process and an example of this, take a look at Microsoft's documentation.
Now, you can check in the OnCreate method of MainActivity.cs, whether the app was launched via an appropriate Intent. MessageCenter will notify all the subscribers about an event called new_url (naming is up to you) with an instance of UrlMessage class as the payload and the Url set to a property within that class:
if (Intent != null && Intent.Action == Intent.ActionView)
{
Uri data = Intent.Data;
/* Get the full url with for example data.ToString() call and do whatever you want with it */
}
iOS
Unfortunately, Apple is not as permissive with the URL schemes as Android. In the official documentation, they state the following:
You cannot claim support for some well-known URL schemes, including http, https, mailto, tel, sms, facetime, and facetime-audio. The system directs well-known types of URLs to the corresponding system apps and well-known http–based URLs to specific apps, such as Maps, YouTube, and Music.

Xamarin.Auth Linkedin custom url interceptor not working

So I've successfully implemented Xamarin.Auth for Google login using this as a guide:
https://github.com/xamarin/Xamarin.Auth
Now, trying to implement the same thing for LinkedIn, for some reason the custom URL interceptor (for deep linking), doesn't catch the redirect URI?
I've set "https://www.linkedin.com/oauth-success" to be my redirect URI on linkedin's app console, and am using it for the Xamarin.Auth's authenticator. It successfully opens up the native UI browser and loads the LinkedIn login page, but once the user logs in, they get left on the LinkedIn website, instead of routed back to the app.
Here is my custom url scheme interceptor code:
[Activity(Label = "ActivityCustomUrlSchemeInterceptor")]
[
IntentFilter
(
actions: new[] { Intent.ActionView },
Categories = new[]
{
Intent.CategoryDefault,
Intent.CategoryBrowsable
},
DataSchemes = new[]
{
"Sybrin.Mobile.OnBoarding.Droid.Sybrin.Mobile.OnBoarding.Droid",
"com.googleusercontent.apps.649780690715-0kajj7q0kgf40mc2fpct709cehgnei16",
"xamarin-auth",
"https://localhost",
"https",
},
DataHosts = new[]
{
"localhost",
"authorize",
"www.linkedin.com"
},
DataPaths = new[]
{
"/oauth2redirect",
"/oauth-success"
},
AutoVerify = true
)
]
Interestingly, when the intent-filter is like that, Google's deep linking breaks, but when I comment out the DataHosts, google successfully routes back into the app after login.
I hope I've been clear. Any help will be greatly appreciated.

<input type="file> does not work in Corona SDK Android web app

I created an android app with Corona SDK, that just opens the mobile version of my website in the app. I only did this because I don't know Java, and I am not able to fully program an app from scratch. It opens the website fine, and looks great, but when I click the "Choose File" button, that on my site is <input type="file">, nothing happens. The little button gets pushed, but no dialog shows to open a file. To open the site in my Corona App, I am using native.newWebView("foobar.com"). In the documentation for that function, it does say: "Native web views are not part of the OpenGL canvas and do not obey the display object hierarchy, so they will always appear in front of normal display objects including images, text, and vector objects." Is this the problem? I want the file open dialog to be able to open in my app.
(On the actual mobile version of my site (in android web browser), the file dialog does open correctly).
You obviously trying to access external storage. Try a build.setting like this.
settings =
{
orientation =
{
default = "portrait",
supported = { "portrait" },
},
android =
{
usesPermissions =
{
"android.permission.INTERNET",
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.READ_INTERNAL_STORAGE",
},
usesFeatures =
{
{ name = "android.hardware.location", required = false },
{ name = "android.hardware.location.gps", required = false },
{ name = "android.hardware.location.network", required = false },
},
},
iphone =
{
plist =
{
CFBundleIconFile = "Icon.png",
CFBundleIconFiles =
{
"Icon.png",
"Icon#2x.png",
"Icon-60.png",
"Icon-60#2x.png",
"Icon-72.png",
"Icon-72#2x.png",
"Icon-76.png",
"Icon-76#2x.png",
"Icon-Small.png",
"Icon-Small#2x.png",
"Icon-Small-40.png",
"Icon-Small-40#2x.png",
"Icon-Small-50.png",
"Icon-Small-50#2x.png",
},
},
},
}

How can I link to an Android app from an email without the need of gmail?

I want to link to my App (made with Xamarin Android) from an email. This works. When I open the link in gmail, the app is opened indeed. However, when using another well known mail client (such as Outlook or Android Email) the situation is different. It tries to browse to the link instead of opening my app.
Here is my html (of the mail):
<a href="http://testje1.mywebdomain.net" style="text-decoration:none;color:#fff;background-color:#5bc0de;border-color:#46b8da;display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px"
role="button">HTTP</a>
<a href="ftp://testje2.mywebdomain.net" style="text-decoration:none;color:#fff;background-color:#5bc0de;border-color:#46b8da;display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px"
role="button">FTP</a>
<a href="doe://testje3.mywebdomain.net" style="text-decoration:none;color:#fff;background-color:#5bc0de;border-color:#46b8da;display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px"
role="button">doe</a>
In gmail, the "ftp" link directly links to my app. The "http" link asks if my browser needs to be opened or my app. The "doe" link does not work (which is no problem).
Here is my C# code with intent filters:
[Activity(Label = "MultiLinks", MainLauncher = true, Icon = "#drawable/icon")]
[IntentFilter(new[] { Android.Content.Intent.ActionView },
DataScheme = "http",
DataHost = "testje1.mywebdomain.net",
Categories = new[] { Android.Content.Intent.CategoryDefault })]
public class MainActivity : Activity
[Activity(Label = "SecondActivity")]
[IntentFilter(new[] { Android.Content.Intent.ActionView },
DataScheme = "ftp",
DataHost = "testje2.mywebdomain.net",
Categories = new[] { Android.Content.Intent.CategoryDefault })]
public class SecondActivity : Activity
[Activity(Label = "ThirdActivity")]
[IntentFilter(new[] { Android.Content.Intent.ActionView },
DataScheme = "doe",
DataHost = "testje3.mywebdomain.net",
Categories = new[] { Android.Content.Intent.CategoryDefault })]
public class ThirdActivity : Activity
How can I link to my app from an email and make it work in another email app than Gmail?
According to the documentation, you need to add the Browsable Category to your IntentFilter if you want a webbrowser to be able to launch your app:
https://developer.android.com/training/app-indexing/deep-linking.html#adding-filters
Include the BROWSABLE category. The BROWSABLE category is required in
order for the intent filter to be accessible from a web browser.
Without it, clicking a link in a browser cannot resolve to your app.
The DEFAULT category is optional, but recommended. Without this
category, the activity can be started only with an explicit intent,
using your app component name.
Hence your categories should look like:
Categories = new[] { Android.Content.Intent.CategoryDefault,
Android.Content.Intent.CategoryBrowsable }
So when another client launches a web browser, the web browser should be able to find out that the link actually belongs to an installed app.
The Chrome browser also supports special url's which can launch an Intent directly or show the play store page if the Intent is not present on the device.
It could look like:
intent://myApp/#Intent;scheme=myScheme;package=my.awesome.package.name;S.browser_fallback_url=http%3A%2F%2Fmyapp.com;end
More about that here: https://developer.chrome.com/multidevice/android/intents

Categories

Resources