Xamarin forms open another app using Rivets component - xamarin

I have to open an app from another app in Xamarin forms. I found the Rivets component which says it can do what i want but I'm not sure what url it refers to.
I looked at http://applinks.org/documentation/ and it says the url I want opened per mobile platform.
My question is, for iOS, what url is it looking for? I thought it was the link to the app in itunes. All that link does is open the app store at the app but doesn't launch the app if it's already installed.

Unless you have control over the Blue Diamond Party app's code or you know that the Blue Diamond Party app has registered one or more custom app links (which are the custom URLs you have read about), you will not be able to open it from your app on iOS. This is the only way to make that work with Rivets. The Blue Diamond Party app would need to register a custom URI of some kind that it would respond to. Then, using Rivets, your app would call that custom URI.
*Edit: To get your app to handle app links from other apps, you can head to the Xamarin's Getting Started Guide (look under the Handling Incoming App Link Navigation heading):
Android does things different than iOS, but for iOS:
Register the custom URI in the Info.plist (not sure if that is the correct XML but it is something like that, check out the link for an image)(the string under CFBundleURLName is just a custom name for your scheme and then you can list multiple schemes in the array under the name):
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.bluediamondparty.schemes</string>
<key>CFBundleURLSchemes</key>
<array>
<string>bluediamondparty</string>
</array>
</dict>
</array>
The above XML would register the bluediamondparty as your URI scheme for your app to respond to.
Now, in order for your app to do something when a URI with your custom scheme is run, you override OpenUrl in your AppDelegate (this allows you to put things after your custom URI scheme to, for example, open a specific page or item in your app):
public override bool OpenUrl (UIApplication app, NSUrl url, string srcApp, NSObject annotation) {
var rurl = new Rivets.AppLinkUrl (url.ToString ());
if (rurl.InputUrl.Host.Equals ("play")) {
var gameModeType = rurl.InputQueryParameters ["game_mode_type"];
var c = new ProductViewController (gameModeType, rurl.Referrer);
navController.PushViewController (c, true);
return true;
}
return false;
}
To open the URI from your second app, you might run something like this:
UIApplication.SharedApplication.OpenUrl(new NSUrl("bluediamondparty://play?game_mode_type=survival"));
Finally, you might notice that none of that actually required using the Rivets component... so what does that component actually do for us?! What Rivets actually does is to allow your app to pass in a real URL (such as http://rdio.com/song/12345) and Rivets will go to that page and look for special meta tags that describes how the content on the page is linked to a mobile app that the user might have installed on their device. So on that rdio web page they might have the following meta tag:
<meta property="al:ios:url" content="rdio://song/12345" />
In that meta tag it will list the correct custom URI scheme to attempt to open the Rdio app if the user has it installed and it has registered itself with the custom rdio URI scheme.
The other thing to know is that your app does not have exclusive rights to a URI scheme. So if another app chooses the same URI scheme as you and the user installs both of them, then the last app to be installed will respond to the URI scheme.

Related

Xamarin Forms WebView open external link

I have a webview inside my application and when an external link is clicked (that in normal browser is open in a new tab), I can't then go back to my website.
It is possible when a new tab is open to have the menu closed that tab like Gmail do ?
The objective is that, whenever a link is clicked, the user would have the choice to choose which option to view the content with, e.g. Clicking a link would suggest open youtube app or google chrome. The purpose is to appear the google chrome option
Or what suggestions do you have to handle this situation ?
If I understood you correctly, you want to have the option to select how to open the web link - inside your app, or within another app's (browser) context.
If this is correct, then you can use Xamarin.Essentials: Browser functionality.
public async Task OpenBrowser(Uri uri)
{
await Browser.OpenAsync(uri, BrowserLaunchMode.SystemPreferred);
}
Here the important property is the BrowserLaunchMode flag, which you can learn more about here
Basically, you have 2 options - External & SystemPreferred.
The first one is clear, I think - it will open the link in an external browser.
The second options takes advantage of Android's Chrome Custom Tabs & for iOS - SFSafariViewController
P.S. You can also customise the PreferredToolbarColor, TitleMode, etc.
Edit: Based from your feedback in the comments, you want to control how to open href links from your website.
If I understood correctly, you want the first time that you open your site, to not have the nav bar at the top, and after that to have it. Unfortunately, this is not possible.
You can have the opposite behaviour achieved - the first time that you open a website, to have the nav bar and if the user clicks on any link, to open it externally (inside a browser). You have 2 options for this:
To do it from your website - change the a tag's target to be _blank like this;
To do it from your mobile app - create a Custom renderer for the WebView. In the Android project's renderer implementation, change the Control's WebViewClient like so:
public class CustomWebViewClient : WebViewClient
{
public override bool ShouldOverrideUrlLoading(Android.Webkit.WebView view, IWebResourceRequest request)
{
Intent intent = new Intent(Intent.ActionView, request.Url);
CrossCurrentActivity.Current.StartActivity(intent);
return true;
}
}

How to read and set cookies from Browser/WebView in NativeScript?

I'm building an app which mainly displays public data from a website. A few items require authentication to read. I don't want to recreate the entire website in the app so I'd like to have the user log in via a web view or browser popup and grab the cookie containing the token from this session. I would then use it to authenticate my in-app rest calls in order to fetch the data. This should work on iOS and Android but I couldn't come up with a functioning solution yet. How would one read and write cookies from the phone browser / webview? I'm using the latest Angular (9) and NativeScript.
For android
The webview UI
<WebView height="1200px" src="https://www.nativescript.org"
(loadFinished)="onLoadFinished($event)"></WebView>
The typescript code
import * as application from 'application';
declare const android;
....
....
....
onLoadFinished(args: LoadEventData) {
android.webkit.CookieManager.getInstance().getCookie(<cookie name>)
android.webkit.CookieManager.getInstance().setCookie(<cookie name>, <cookie value>)
}
For IOS seems it is little bit complicated
Refer StackOverflow set cookie in IOS nativescript

Can we control when the Bluetooth access prompt is shown programmatically (like location)?

I asked a question recently on how to access the callback from the new Bluetooth access prompt in iOS 13 regarding the new description - NSBluetoothAlwaysUsageDescription. I'm not sure I even saw a Bluetooth access prompt unless Bluetooth was off with the old description - NSBluetoothPeripheralUsageDescription.
Registering the prompt callback involved implementing an instance of CBCentralManager and registering the UpdatedState event handler.
Now I'm wondering - is there a way to determine when the prompt is shown?
If we create a default Xamarin.Forms/Xamarin.iOS application and add the following to it's Info.plist file-
<key>UIBackgroundModes</key>
<array>
<!--The app communicates with BLE peripherals using the Core Bluetooth framework.-->
<string>bluetooth-central</string>
<!--The app shares data using the Core Bluetooth framework.-->
<string>bluetooth-peripheral</string>
</array>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>App would like to use bluetooth.</string>
<key>NSBluetoothAlwaysUsageDescription</key>
<string>App would like to use bluetooth.</string>
It would appear the new Bluetooth prompt is ALWAYS shown on application start. Can we as developers address this like location?
Here's what I mean by "like location". Similarly if location access is added to the plist file, like below, then the prompt occurs on application start. HOWEVER this prompt's timing to be shown to the user can be manipulated!
Simply instantiate the LocationManager instance when we want the prompt to be shown -
Manager = new LocationManager();
Manager.LocationUpdated += HandleLocationChanged;
The problem we are facing is that even without initializing any Bluetooth related instances/classes/implementations/etc the app ALWAYS prompts for Bluetooth first. So-
Can we control when the Bluetooth access prompt is shown programmatically (like location)?
(In case anyone be curious- to access callback for Location prompt register the CLLocationManager.AuthorizationChanged event)
And similarly these are the plist entries we currently have for location
<key>UIBackgroundModes</key>
<array>
<string>location</string>
</array>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>App would like to access location.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>App would like to access location.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>App would like to access location.</string>
If you check the source code of CBCentralManager. You will find that it has a constructor
public CBCentralManager(ICBCentralManagerDelegate centralDelegate, DispatchQueue queue, CBCentralInitOptions options);
So you can set the property ShowPowerAlert as true when init the CBCentralManager
CBCentralManager manager = new CBCentralManager(new xxxDelegate(),null,new CBCentralInitOptions() { ShowPowerAlert=true});
When CentralManager is initialized, an Alert will pop up if bluetooth is not turned on .

Windows Phone: Navigate between apps

I have an app that needs to include a links to a second app in the same phone.
If the app is not installed the link should point to the windows store to install it (that part is working fine).
But if the app is already installed the link should go straight to the app and open it. How can I do that?
The app has two versions one form WP7 and other from WP8. if the solution is different for them please point the difference.
Thanks for the help...
I believe a URI Association is what you want. You should be able to create a different association in your WP7 app and in your WP8 app, and handle them accordingly.
A URI association allows your app to automatically launch when another app launches a special URI.
Also note:
If you are interested only in launching your own apps, consider using
APIs from the Windows.Phone.Management.Deployment namespace. You can
use this API to check for other apps that you’ve published, and then
launch them if they’re installed.
You basically just need to update the WMAppManifest.xml file to include the URI Association and then listen for that URI. Example:
<Extensions>
<Protocol Name="contoso" NavUriFragment="encodedLaunchUri=%s" TaskID="_default" />
</Extensions>
Then you can use a custom URI Mapper to handle your association (full example in top link above):
public override Uri MapUri(Uri uri)
{
tempUri = System.Net.HttpUtility.UrlDecode(uri.ToString());
// URI association launch for contoso.
if (tempUri.Contains("contoso:ShowProducts?CategoryID="))
{
// Get the category ID (after "CategoryID=").
int categoryIdIndex = tempUri.IndexOf("CategoryID=") + 11;
string categoryId = tempUri.Substring(categoryIdIndex);
// Map the show products request to ShowProducts.xaml
return new Uri("/ShowProducts.xaml?CategoryID=" + categoryId, UriKind.Relative);
}
// Otherwise perform normal launch.
return uri;
}
Hope this helps!
Is the secondary app one that you have created? If so, do something like this:
IEnumerable<Package> packages = InstallationManager.FindPackagesForCurrentPublisher();
foreach (Package package in packages)
{
if (package.Id.ProductId.ToString().ToLower() == "product id of secondary app")
{
//Launch the app
package.Launch();
}
}
Make sure that your publisher ids match in the WMAppManifest for both apps.
If this secondary app was published by someone else, you'll need to use a custom Uri schema. The app needs to have this feature added by the developer, you can't just launch any app.

Register an application to a URL protocol (all browsers) via installer

I know this is possible via a simple registry change to accomplish this as long as IE/firefox is being used. However, I am wondering if there is a reliable way to do so for other browsers,
I am specifically looking for a way to do this via an installer, so editing a preference inside a specific browser will not cut it.
Here is the best I can come up with:
IE: http://msdn.microsoft.com/en-us/library/aa767914(VS.85).aspx
FireFox: http://kb.mozillazine.org/Register_protocol
Chrome: Since every other browser in seems to support the same convention, I created a bug for chrome.
Opera: I can't find any documentation, but it appears to follow the same method as IE/Firefox (see above links)
Safari: Same thing as opera, it works, but I can't find any documentation on it
Yes. Here is how to do it with FireFox:
http://kb.mozillazine.org/Register_protocol
and Opera:
http://www.opera.com/support/kb/view/535/
If someone looks like a solution for an intranet web site (for all browsers, not only IE), that contains hyperlinks to a shared server folders (like in my case) this is a possible solution:
register protocol (URI scheme) via registry (this can be done for all corporative users i suppose). For example, "myfile:" scheme. (thanks to Greg Dean's answer)
The hyperlink href attribute will then should look like
<a href='myfile:\\mysharedserver\sharedfolder\' target='_self'>Shared server</a>
Write a console application that redirects argument to windows explorer (see step 1 for example of such application)
This is piece of mine test app:
const string prefix = "myfile:";
static string ProcessInput(string s)
{
// TODO Verify and validate the input
// string as appropriate for your application.
if (s.StartsWith(prefix))
s = s.Substring(prefix.Length);
s = System.Net.WebUtility.UrlDecode(s);
Process.Start("explorer", s);
return s;
}
I think this app can be easily installed by your admins for all intranet users :)
I couldn't set up scheme setting to open such links in explorer without this separate app.

Resources