Quantcast
Channel: Xamarin.Forms — Xamarin Community Forums
Viewing all 77050 articles
Browse latest View live

Open contentpage when tap push notification using FirebasePushNotificationPlugin

$
0
0

I am using the following notification payload for sending push notification to my android device using postman.

{
    "to" : "device_key",
 "collapse_key" : "type_a",
 "notification" : {
     "body" : "Body of Your Notification",
     "title": "Title of Your Notification",
     "sound": "default"
 },
 "data" : {
     "body" : "Body of Your Notification in Data",
     "title": "Title of Your Notification in Title",
     "key_1" : "Value for key_1",
     "key_2" : "Value for key_2"
 }
}

Notifications are received to my device and OnMessageReceived() triggered only when the app is in the foreground. When the app is in background state OnMessageReceived is not triggering and not triggering when tapping the notification.

I installed FirebasePushNotificationPlugin and added notification events in App constructor like below.

CrossFirebasePushNotification.Current.OnNotificationReceived += (s, p) =>
{
      System.Diagnostics.Debug.WriteLine("Received");
};

CrossFirebasePushNotification.Current.OnNotificationOpened += (s, p) =>
{
    System.Diagnostics.Debug.WriteLine("Opened");
    foreach (var data in p.Data)
     {
         System.Diagnostics.Debug.WriteLine($"{data.Key} : {data.Value}");
     }
     if (!string.IsNullOrEmpty(p.Identifier))
     {
         System.Diagnostics.Debug.WriteLine($"ActionId: {p.Identifier}");
     }
 };

But when receiving or tapping notification these codes are not triggering.

In one thread I found that above events are triggered when you send data message only, should not be sent notification messages if you want to use this event handler.

But if I send data messages only the notifications are not received to my device. Following is the notification payload for data messages.

{
    "to" : "device_key",
 "collapse_key" : "type_a",
 "data" : {
     "body" : "Body of Your Notification in Data",
     "title": "Title of Your Notification in Title",
     "key_1" : "Value for key_1",
     "key_2" : "Value for key_2"
 }
}

I need to open a content page in the PCL when tapping a notification. But OnNotificationReceived or OnNotificationOpened are not triggering. So what I am missing in this implementation?


How to detect local network hardware device using WIFI?

$
0
0

Hi all,

I would like to detect local network hardware devices using WIFI in Xamarin mobile app. (In this scenario, mobile phone have no internet connection at all)

I search on documentation, but only able to found documentation on detecting phone itself networking state.

Could anyone assist on this?

Thanks.

using statements vs fully qualified names - any difference to performance/ipa and apk size?

$
0
0

Hi guys,

I have a relatively simple XF project that uses the PayPal SDK for Xamarin.Forms to collect payments.

The problem is that the size is around 120MB on iOS and 65MB on Android which I believe is way too much considering that I am using LLVM and Link All options.

Now, I am trying to explore all possible ways to shrink the app size as much as possible so I can compete with real native apps that offer the same functionality but are sizes less than 20MB!

One of the things I noticed as well is that Linker doesn't do much for me as when I disabled it, the increase in size was only 10MB!

My question is would it be better to use fully qualified names instead of using statements on top of the class?

System.IO.File.ReadAllLines or File.ReadAllLines (with using System.IO at top)?

Binding a ViewModel to a Bluetooth Service

$
0
0

Hi,

I am writing a xamarin forms app and I want to bind a property in my ViewModel to the bluetooth adapter state (on/off). In turn, I want to bind a switch in my View to the ViewModel that reflects and can set the bluetooth adapter on and off.

Essentially I want a switch the can set and accurately reflect the state of the bluetooth adapter.

Because it is a xamarin forms app, I am using a dependency service for access to bluetooth on each platform.

The general structure is like this: View (Switch) <-> ViewModel(Property) <-> Interface (Dependency service) <-> Bluetooth Platform (Android)

The View and ViewModel bind to each other without issue, so I will omit that detail.

Here is what I have:

public class BluetoothViewModel : INotifyPropertyChanged
{
    //Ask the container to resolve the service only once.
    private BluetoothServices bluetoothServices;
    protected BluetoothServices BTService => bluetoothServices ?? (bluetoothServices = DependencyService.Get<BluetoothServices>());

    // ... OnPropertyChanged() implementation

    public bool AdapterStatus    // Switch in the View binds to this
    {
        get => BTService.AdapterStatus;
        set
        {
        BTService.AdapterStatus = value;
        OnPropertyChanged();
        }
    }
}



 public interface BluetoothServices   // BluetoothServices interface, used for the bluetooth dependency service
    {
    bool AdapterStatus { get; set; } // Gets/Sets the Bluetooth adapter status
    }



public sealed class BluetoothReceiver : BluetoothServices, INotifyPropertyChanged
{
 private static BluetoothAdapter adapter;

 public bool AdapterStatus
 {
    get => (adapter != null ? adapter.IsEnabled : false);
    set
    {
        if (adapter != null && adapter.IsEnabled != value) // Check that the adapter exists and the status needs to be changed
        {
            switch (value)
            {
                case false:
                    adapter.Disable();  // Disable adapter to reflect switch state
                    break;

                case true:
                    adapter.Enable();   // Enable adapter
                    break;

                default:

                    break;
            }

            OnPropertyChanged();
        }
    }
}

How can I get the change in the adapter status to be propagated to the viewmodel?

Error Call CallbackManager.OnActivityResult(requestCode, (int)resultCode, data)

$
0
0

Error detail :
Unhandled Exception:

System.NotSupportedException: Unable to activate instance of type PinCard.Mobile.Droid.Plugins.FacebookProvider_Android from native handle 0xfff3f75c (key_handle 0xce11d20). occurred

How to do resolve this issue ???
MainActivity.cs

    protected override void OnCreate(Bundle savedInstanceState)
        {
        base.OnCreate(savedInstanceState);
        FacebookSdk.ApplicationId = GetString(Resource.String.facebook_app_id);
                FacebookSdk.SdkInitialize(ApplicationContext);
        .......
    }
    protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
        {
            if (FacebookProvider_Android.Current != null)
            {
                var result = false;
                try
                {
            //Error Here
                    **result = FacebookProvider_Android.Current.CallbackManager.OnActivityResult(requestCode, (int)resultCode, data);**
                    if (result)
                        FacebookProvider_Android.Current.OnSuccess(result);
                }
                catch (Exception ex)
                {
                    //Do SomeThing
                }

            }
            if (GoogleProvider_Android.Current != null)
                GoogleProvider_Android.Current.OnActivityResult(requestCode, (int)resultCode, data);
            base.OnActivityResult(requestCode, resultCode, data);
            InAppBillingImplementation.HandleActivityResult(requestCode, resultCode, data);
        }

FacebookProvider_Android.cs

    [assembly: Dependency(typeof(FacebookProvider_Android))]
    namespace PinCard.Mobile.Droid.Plugins
    {
        public class FacebookProvider_Android : Java.Lang.Object, IFacebookCallback, IFacebookProvider
        {
            private TaskCompletionSource<string> _tcs;
            public FacebookProvider_Android()
            {
                CallbackManager = CallbackManagerFactory.Create();
                LoginManager.Instance.RegisterCallback(CallbackManager, this);
                Current = this;
            }
            public static FacebookProvider_Android Current { get; private set; }
            public ICallbackManager CallbackManager { get; set; }
            public bool IsProcess { get; set; }
            public void OnCancel()
            {
                _tcs.TrySetResult("");
            }
            public void OnError(FacebookException error)
            {
                _tcs.TrySetResult("");
            }
            public void OnSuccess(Java.Lang.Object result)
            {
                if (result is LoginResult lr)
                {
                    AccessToken = lr.AccessToken.Token;
                    UserId = lr.AccessToken.UserId;
                }
                _tcs.TrySetResult(AccessToken);
            }
        public string UserId { get; private set; } // Implement from Interface
            public string AccessToken { get; private set; } // Implement from Interface

            public IntPtr Handle { get; set; } //=> throw new NotImplementedException();

            public Task<string> LoginAsync() // Implement from Interface
            {
                try
                {
                    string[] scopes = { "email", "public_profile", "user_friends" };
                    if (IsProcess)
                        return Task.FromResult("");
                    _tcs = new TaskCompletionSource<string>();
                    IsProcess = true;
                    LoginManager.Instance.LogInWithReadPermissions(
                        CrossCurrentActivity.Current.Activity, scopes);
                    return _tcs.Task;
                }
                catch (System.Exception)
                {
                    //TODO: Log                
                }
                finally
                {
                    IsProcess = false;
                }
                return Task.FromResult("");
            }

            public void Dispose()
            {

            }
        }
    }

LoginPage.cs

     private async Task SignInAsync(string provider)
     {
                IAuthenticationProvider authProvider;
                switch (provider)
                {
                    case "Facebook":
                        authProvider = DependencyService.Get<IFacebookProvider>();
                        break;
                    case "Google":
                        authProvider = DependencyService.Get<IGoogleProvider>();
                        break;
                    default:
                        authProvider = DependencyService.Get<IAuthenticationProvider>();
                        break;
                }
     }

Thanks All.

NavigationPage.TitleView Height - Android vs iOS

$
0
0

Hello,

On android, titleView does not seem to have a fixed size. On iOS it does.

Here is a sample :

    <NavigationPage.TitleView>

        <Image 
            Source="ic_logo.png"
            Aspect="AspectFit"></Image>

    </NavigationPage.TitleView>

Result is fine on iOS :

But on Android :

Should I force the height of the image if running on Android ? At what height ?

Thanks

Side By side Entries Foe Verification code.

$
0
0

I am try to design like below image entries field any suggestion please?

How to integrate Power BI report in my xamarin form application.

$
0
0

Hello,
Is there any SDK available for integrate Power BI report in xamarin form application?


How to create On-boarding screen in Xamarin form?

$
0
0

I am trying to Design Onboarding screen In Xamarin Forms .Any Suggestion Please?

Set selected item in Picker

$
0
0

How can I set the selected item in a picker? I want to select a grid row then set the selected values into a couple of picker controls based on the selected data in the row. Easy enough to do with text controls. I haven't found a reliable way to set the selected index so I need to select the text. C#, BTW.

Can Xamarin forms be used to make windows application?

$
0
0

Client asked for an application to run on Ios/Android/WindowsPhone. We proposed to use Xamarin.Forms. We are now facing the problem of Windows. The client asked if it's possibile to convert the app from mobile to desktop without using the windows store.

This application will be used on multiple pcs ranging from windows 7 to 8.1 to 10. I was wondering if it's possible to direct export of the project from Xamarin forms.

Thanks.

How to create a unit test project targeting macOS

$
0
0

I have a Xamarin.Forms application with a macOS head project. Is it possible to create a unit test project that targets the macOS head project? (xUnit would be nice as used elsewhere, but not necessary.) Failing that, is it possible to create a unit test project that targets a macOS class library?

how to reduce space between two stacklayout???

$
0
0

Grid containing two stacklayout if i reduce the space it affects nearby column grid

Does anyone know why my CarouselView is not being displayed?

$
0
0

I am trying to display an image slider using CarouselView.FormsPlugin and although I have looked at documentation and watched tutorials I have had no luck in displaying it on my app. I wonder if it is my xaml hierarchy even though I checked that too. I have the CarouselViewRenderer.Init() in both iOS and Android projects too. Please see my code below:
XAML

Code-Behind

Handling Unhandled exception for Android still crashes app?

$
0
0

I have in MainActivity handling undhandled exceptions as below but even though doing this causing app to crash. Is there a way to handle that app is not crashing?

 protected override void OnCreate(Bundle bundle)
        {

            AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
            System.Threading.Tasks.TaskScheduler.UnobservedTaskException += TaskSchedulerOnUnobservedTaskException;
            AndroidEnvironment.UnhandledExceptionRaiser += AndroidEnvironmentOnUnhandledException;

using below in UWP works fine. not crashing the app.

  UnhandledException += async (sender, e) =>
            {
                e.Handled = true;   

            };

ListViewAdapter.IsEnabled android.runtime.JavaProxyThrowable: System.NullReferenceException: Object

$
0
0

Hello, I have this Crash:

Xamarin caused by: android.runtime.JavaProxyThrowable: System.NullReferenceException: Object reference not set to an instance of an object
Xamarin.Forms.Platform.Android.ListViewAdapter.IsEnabled(int position)<173f39d71f0d4d928f5bbea42e96ffa8>:0
Android.Widget.BaseAdapter.n_IsEnabled_I(IntPtr jnienv, IntPtr native__this, int position):0
at (wrapper dynamic-method) System.Object:559d609d-c704-4246-85cd-c185afe055df (intptr,intptr,int)
md5b60ffeb829f638581ab2bb9b1a7f4f3f.ListViewAdapter.n_isEnabled(Native Method)
md5b60ffeb829f638581ab2bb9b1a7f4f3f.ListViewAdapter.isEnabled()ListViewAdapter.java:108
android.widget.HeaderViewListAdapter.isEnabled()HeaderViewListAdapter.java:159
android.widget.ListView.setupChild()ListView.java:1988
android.widget.ListView.makeAndAddView()ListView.java:1938
android.widget.ListView.fillDown()ListView.java:719
android.widget.ListView.fillSpecific()ListView.java:1391
android.widget.ListView.layoutChildren()ListView.java:1746
android.widget.AbsListView.onLayout()AbsListView.java:2860
android.view.View.layout()View.java:18010
android.view.ViewGroup.layout()ViewGroup.java:5911
android.support.v4.widget.SwipeRefreshLayout.onLayout()SwipeRefreshLayout.java:636
android.view.View.layout()View.java:18010
android.view.ViewGroup.layout()ViewGroup.java:5911
md5b60ffeb829f638581ab2bb9b1a7f4f3f.ListViewRenderer.n_onLayout(Native Method)
md5b60ffeb829f638581ab2bb9b1a7f4f3f.ListViewRenderer.onLayout()ListViewRenderer.java:65
android.view.View.layout()View.java:18010
android.view.ViewGroup.layout()ViewGroup.java:5911
com.xamarin.forms.platform.android.FormsViewGroup.measureAndLayout()FormsViewGroup.java:28
md5b60ffeb829f638581ab2bb9b1a7f4f3f.VisualElementRenderer_1.n_onLayout(Native Method)
md5b60ffeb829f638581ab2bb9b1a7f4f3f.VisualElementRenderer_1.onLayout()VisualElementRenderer_1.java:72
android.view.View.layout()View.java:18010
android.view.ViewGroup.layout()ViewGroup.java:5911
com.xamarin.forms.platform.android.FormsViewGroup.measureAndLayout()FormsViewGroup.java:28
md5b60ffeb829f638581ab2bb9b1a7f4f3f.ScrollViewContainer.n_onLayout(Native Method)
md5b60ffeb829f638581ab2bb9b1a7f4f3f.ScrollViewContainer.onLayout()ScrollViewContainer.java:46
android.view.View.layout()View.java:18010
android.view.ViewGroup.layout()ViewGroup.java:5911
android.widget.FrameLayout.layoutChildren()FrameLayout.java:344
android.widget.FrameLayout.onLayout()FrameLayout.java:281
android.widget.ScrollView.onLayout()ScrollView.java:2562
md5b60ffeb829f638581ab2bb9b1a7f4f3f.ScrollViewRenderer.n_onLayout(Native Method)
md5b60ffeb829f638581ab2bb9b1a7f4f3f.ScrollViewRenderer.onLayout()ScrollViewRenderer.java:91
android.view.View.layout()View.java:18010
android.view.ViewGroup.layout()ViewGroup.java:5911
md5b60ffeb829f638581ab2bb9b1a7f4f3f.VisualElementRenderer_1.n_onLayout(Native Method)
md5b60ffeb829f638581ab2bb9b1a7f4f3f.VisualElementRenderer_1.onLayout()VisualElementRenderer_1.java:72
android.view.View.layout()View.java:18010
android.view.ViewGroup.layout()ViewGroup.java:5911
com.xamarin.forms.platform.android.FormsViewGroup.measureAndLayout()FormsViewGroup.java:28
md5270abb39e60627f0f200893b490a1ade.NavigationPageRenderer.n_onLayout(Native Method)
md5270abb39e60627f0f200893b490a1ade.NavigationPageRenderer.onLayout()NavigationPageRenderer.java:65
android.view.View.layout()View.java:18010
android.view.ViewGroup.layout()ViewGroup.java:5911
com.xamarin.forms.platform.android.FormsViewGroup.measureAndLayout()FormsViewGroup.java:28
md5270abb39e60627f0f200893b490a1ade.MasterDetailContainer.n_onLayout(Native Method)
md5270abb39e60627f0f200893b490a1ade.MasterDetailContainer.onLayout()MasterDetailContainer.java:45
android.view.View.layout()View.java:18010
android.view.ViewGroup.layout()ViewGroup.java:5911
android.support.v4.widget.DrawerLayout.onLayout()DrawerLayout.java:1193
md5270abb39e60627f0f200893b490a1ade.MasterDetailPageRenderer.n_onLayout(Native Method)
md5270abb39e60627f0f200893b490a1ade.MasterDetailPageRenderer.onLayout()MasterDetailPageRenderer.java:68
android.view.View.layout()View.java:18010
android.view.ViewGroup.layout()ViewGroup.java:5911
md5b60ffeb829f638581ab2bb9b1a7f4f3f.PlatformRenderer.n_onLayout(Native Method)
md5b60ffeb829f638581ab2bb9b1a7f4f3f.PlatformRenderer.onLayout()PlatformRenderer.java:55
android.view.View.layout()View.java:18010
android.view.ViewGroup.layout()ViewGroup.java:5911
android.widget.RelativeLayout.onLayout()RelativeLayout.java:1080
android.view.View.layout()View.java:18010
android.view.ViewGroup.layout()ViewGroup.java:5911
android.widget.FrameLayout.layoutChildren()FrameLayout.java:344
android.widget.FrameLayout.onLayout()FrameLayout.java:281
android.view.View.layout()View.java:18010
android.view.ViewGroup.layout()ViewGroup.java:5911
android.widget.LinearLayout.setChildFrame()LinearLayout.java:1742
android.widget.LinearLayout.layoutVertical()LinearLayout.java:1585
android.widget.LinearLayout.onLayout()LinearLayout.java:1494
android.view.View.layout()View.java:18010
android.view.ViewGroup.layout()ViewGroup.java:5911
android.widget.FrameLayout.layoutChildren()FrameLayout.java:344
android.widget.FrameLayout.onLayout()FrameLayout.java:281
com.android.internal.policy.PhoneWindow$DecorView.onLayout()PhoneWindow.java:3175
android.view.View.layout()View.java:18010
android.view.ViewGroup.layout()ViewGroup.java:5911
android.view.ViewRootImpl.performLayout()ViewRootImpl.java:2784
android.view.ViewRootImpl.performTraversals()ViewRootImpl.java:2477
android.view.ViewRootImpl.doTraversal()ViewRootImpl.java:1544
android.view.ViewRootImpl$TraversalRunnable.run()ViewRootImpl.java:7616
android.view.Choreographer$CallbackRecord.run()Choreographer.java:911
android.view.Choreographer.doCallbacks()Choreographer.java:686
android.view.Choreographer.doFrame()Choreographer.java:622
android.view.Choreographer$FrameDisplayEventReceiver.run()Choreographer.java:897
android.os.Handler.handleCallback()Handler.java:739
android.os.Handler.dispatchMessage()Handler.java:95
android.os.Looper.loop()Looper.java:148
android.app.ActivityThread.main()ActivityThread.java:7406
java.lang.reflect.Method.invoke(Native Method)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run()ZygoteInit.java:1230
com.android.internal.os.ZygoteInit.main()ZygoteInit.java:1120

Any ideas?

Thanks

Flight seat map

$
0
0

How to create flight seat map using xamarin forms.

Forms Previewer - 'An exception occurred while rendering the control'

$
0
0

With Visual Studio 2017 (latest rc) - after opening xaml previewer, I am presented with error in the designer 'an exception occurred while rendering the control'. This occurs while trying to view the Android view. I can however view the ios view when my mac build agent is available.

If I click the (!) icon i see a series of exception messages

i.e.
you must call xamarin.forms.init prior to using it
at xamarin.forms.device.get_info()

etc.

Whenever I bind Command to a Button, the button is always inactive, what could I be doing wrong?

$
0
0

Situation: Every time I bind Command<T> to a button in my project the button is always inactive.

Steps I followed:
1. WORKED: Downloaded the source code for the Xamarin DataBinding examples (https://developer.xamarin.com/samples/xamarin-forms/DataBindingDemos/) and ran the project without any changes and everything worked as expected, paying particular attention to DecimalKeypad which is the simplest example I found of a Command<T> binding.
2. DID NOT WORK: Added the three required files for the DecimalKeypad example from the DataBindingDemos example into my project and made NO changes to the files. Page displays but the Command<T> buttons are inactive...

It seems like I'm missing something fundamental to how Command<T> is supposed to work. See below the fold for examples of other things I've tried.

Any suggestions?

Other things I've tried (adding below the fold to simplify the question)
3. DID NOT WORK: Followed the example from https://devblogs.microsoft.com/xamarin/simplifying-events-with-commanding/ and as soon as I tried the Command<T> example, the button became disabled...
4. DID NOT WORK: Followed the code from https://forums.xamarin.com/discussion/90049/button-disabled-with-viewmodel and updated it to be a Command<T> button, since the example was only for Command, and it stopped working as soon as I implemented Command<T>.

Thank you so much for any help you can offer!
Tim

How I Setup Google Firebase Dynamic Links in Xamarin Forms - Android Edition

$
0
0

Hello All,

I was recently tasked with implementing Firebase Dynamic Links into my company's Xamarin Forms App. They are used to advertise your app. I combed online as much as I could looking for a guide/example/github that explained this or already implemented it. Without finding anything specific, I combined the resources I could find to accomplish this task. I will try my best to document and explain how I got this working, hopefully helping you out or at least pointing you in the right direction.
I currently have only done it in the Android project of my app, so most of this will apply directly to android. I will work on finishing and documenting the iOS implementation in the future.
Disclaimer: I'm not an expert, any or all of this could be wrong. It's just what worked for me and my basic understanding. Please let me know if there are any errors and let's improve our collective intelligence of the Xamarin Community

If you don't already know what Dynamic Links are, watch the 2 min video, it's a great overview. https://firebase.google.com/docs/dynamic-links/

The Setup
Setup is broken up into 2 parts.
Part 1 - Configure the Dynamic Links in the Firebase Console (Easy)
Part 2 - Configure your app to be able to receive and process the Deep Links (Not as Easy)

Part 1 - Configure the Dynamic Links in the Firebase Console (Easy)
1- Setup a free firebase account at https://firebase.google.com/
2- Create a project.
3- Create a new dynamic link, the tab is at the bottom of the 'Grow' section.
It will generate a static domain name for you based off of your project name. Ex. 'https://myproject.page.link'
Short Link url is what users will click on to navigate to your appstore or launch your app.
Deep Link url is what actually gets sent into your app for you to work with. Ex 'https://myproject.com/MainPage'
iOS behavior. Currently set mine to open the link in a url browser, as my app is not connected to it yet.

Android behavior Very Important but not as hard as my explanation makes it look.
Here is where you register your app with firebase. The package name should be easy, use the same one as defined in your
apps Android properties. Ex 'com.mycompany.appname'
Adding the signing certs SHA-1 and SHA-256 are required for Dynamic Links, which is what we are doing here.
Microsoft has a great guide on this, better than I can explain. here
Download the google-services.json file - You will need it later. Also, you will need the one that has incorporated the SHA cert details in it.
Ignore the instructions for adding the firebase SDK, we will add these to our project later using Nuget packages.
When this is all done your app should be selectable in a dropdown for the android behavior.
Finally, add any extra tags to your dynamic link url if you want, its optional.

And that's it! Now you should have a working short link. When used on an android device it should already be able to determine if the app is already installed or not, and then either direct the user to the play store or open the app. However, it won't do anything with that deep link url that you set. That brings us to the next part.

Part 2 - Configure your app to be able to receive and process the Deep Links (Not as Easy)
1- Versions, might be important.
2- Nuget Packages - Hopefully this goes smoother for you than it did for me.
3- The Code
3a- Intent Filters
3b- Handling the Deep Link

1- Versions.
I was having a lot of issues trying to get dynamic/deep linking to work. So I went back and updated everything to the newest versions available at the time.
Visual Studio Professional 2017 - 15.7.5
.NET Framework 4.7.03056
Xamarin 4.10.10.2
Xamarin.Android SDK 8.3.3.2
Android SDK Manager - Got the latest. Android 8.1 API 27 and Android 8.0 API 26 (Targeting 8.1 might be required)
Android Properties -
-Application - Compile using Android Version(Target Framework): Android 8.1 Oreo
-Android Manifest: Target Android Version: Use Compile SDK Version(haven't tried targetting 8.1 directly, might work). My min target is still Android 4.4 API 19 Kit Kat

2- Nuget Packages. These are just for the Android project. MyApp.Android
You shouldn't have to add anything into the .NET Standard Project, just make sure the Xamarin.Forms Versions match
Below is what I did
Update:
Xamarin.Forms - updated to 3.0.0.482510
Install:
This is where it immediately got annoying for me. Issues here are what lead me to go back and update my Android API Levels to the most recent, 8.1
Xamarin.Firebase.Dynamic.Links by Xamarin Inc v60.1142.1 is what you want to install.
The other dependencies should automatically install. In my case, they did not.
Dependency MonoAndroid,Version=v8.0 is important here. That should be the SDK API version that your app is set to compile against.
However, the other dependencies like Xamarin.GooglePlayServices.Basement (= 60.1142.1) have nested dependencies of their own that require MonoAndroid,Version=v8.1
So if you run into issues installing the Dynamic Links Package, thats where I would recommend looking first.
For my purposes, the nested dependencies were not automatically getting installed, so I went down through each of them and their lists and did them all manually. Even the ones that said not to do manually. It's only 20 or so, but my guess would be if I had my project SDK's set to 8.1 before all of this that it would have gone smoothly.

The CODE
Intent Filters
These are defined in your AndroidManifest.xml file
What do they do? They listen for instructions while your app starts.
When an app start matches a pre-defined filter(short link), they it stores your intended action or data on the Intent Class. That is where we pull the deep link from.
For us, this is what let's the android app receive and begin to process the deep link url that you set all the way back in Part 1.
The firebase dynamic link docs have a good breakdown and example of what to do. here
The android developer docs have a good example and breakdown of this also. here
NOTE Focus on whats between the activity tags. I've just included the other tags to show general structure, in case you haven't edited these before.

That is about the minimum of what you need.
The highlighted line should match the Short Dynamic Link you setup in the established in the Firebase Console.
I'd recommend using a Wildcard like I did in the path prefix.
That way you can make new Dynamic Links and your app can handle them without having to release new versions.

Handling the Deep Link
At this point if your app is launched by the short link, you should be able to catch the deep link during the android startup process and handle it how you want.
All I will cover here is a basic example of how to get the Deep Link as a string.
I pass mine to the main app project (.NET Standard Library) using a simple dependency service.
You can use it however you want though, there's actions it can take in either the App or the App.Android project.
The important thing is getting the deep link.
The firebase docs have good examples, but written in java or whatever language native android uses. here
I'll be showing mostly the same, just in C# examples

Get The Intent.
What is the intent you want to get? The deep link you are sending into your app Ex. "https://mycoolapp.com/mainpage"
You want to get it in the MainActivity. Below is an extremely simplified example, but it's just about that easy. Now you should be able to do what you want with that link inside of your app.

TIPS
Be careful if you have something that interrupts your startup procedures.
My Application uses a splash screen. Part of that is a line of code that creates a new Intent, overwriting the one sent in from the dynamic link
So I have my DeepLinkHandler fire off before that operation, and store the deep link in a static string.
Once it's in a static string I can use a dependency service from the Main App(.NET Standard Library) to call the GetDynamicLinkString method and return the deep link as a string.

How to Test Using an Emulator and Debugger
I have a simple settings page on my app. I added a field that would print the deep link, if it has one.
Fire off the emulator like normal using the debugger. The deep link field should be empty.
With the emulator still running, minimize the app.
Open a browser and enter in the short link url.
This should re-launch your app, but this time the deep link field has the url that you set on the firebase console.

Hope this is able to save someone some headaches.
-Tim

Viewing all 77050 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>