Which package should be used in Xamarin Forms instead of Android.Content to get class Intent?

350 views Asked by At

TL;DR:

Need to use class Intent for different things. Found examples online where using Android.Content is used. This doesn't apply to Xamarin.Forms (I think). What NuGet package is needed for it to work?

Nah.. I got time:

Intro (unnecessary read)

I'm starting out with mobile app development so I'm pretty much clueless about anything. Hoping to get a concise answer here.

My app is primarily WebView container with some other minor functionalities. I'm using Visual Studio 2019 and Xamarin.Forms, but at the moment I am compiling to Android alone. iOS and UWP are my goal once, at least one app is fully finished for Android.

Problem 1 and where I am

Now I need to add two things. One is "Rate us" and the other is "Share" link, both in the main menu (swipe from left or click the hamburger icon to open it). I already have three list items in the menu, where each of them open a page in the app.

I figured out how to add another item to the menu, but I currently link this list item to market://details?id=com.mycompany.myapp url of my app on PlayStore. It opens nicely in PlayStore, but after pressing the back button it goes to home screen instead of back to the app.

Current code where I added "Rate Us"

MainPage.xaml.cs

using MyApp.Models;
using Plugin.Geolocator;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;
using Xamarin.Essentials;
using Xamarin.Forms;

namespace MyApp.Views {
    ...
    public partial class MainPage : MasterDetailPage {
        ...
        public async Task NavigateFromMenu(int id) {
            if (!MenuPages.ContainsKey(id) {
                switch(id) {
                    ...
                    case (int)MenuItemType.RateUs:
                        await Browser.OpenAsync("market://details?id=com.mycompany.myapp", BrowserLaunchMode.SystemPreferred);
                        // startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.mycompany.myapp")));
                        break;
                    ...
                }
            }
            ...
        }
    }
}

MenuPage.xaml.cs

using MyApp.Models;
using System.Collections.Generic;
using System.ComponentModel;
using Xamarin.Forms;

namespace MyApp.Views {
    ...
    public partial class MenuPage : ContentPage {
        ...
        public MenuPage() {
            InitializeComponent();
            menuItems = new List<HomeMenuItem> {
                ...
                new HomeMenuItem { id = MenuItemType.RateUs, Title="Rate Us", Icon="\uf005" },
                ...
            }
        }
    }
}

HomeMenuItem.cs

namespace MyApp.Models {
    public enum MenuItemType {
        ...
        RateUs,
        ...
    }
    public class HomeMenuItem {
        public MenuItemType Id { get; set; }
        public string Title { get; set; }
        public string Icon { get; set; }
    }
}

What I tried

As you can see in // comment in MainPage.xaml.cs I found a different solution, that would perhaps return me back to my app after going back from PlayStore.

This particular solution is (obviously???) problematic at startActivity, tooltip stating

The name 'startActivity' does not exist in the current context

but there are other much more complex solution like THIS ONE that have startActivity wrapped in public void function() which - I guess - helps.

Problem 2

I need to add another List Item to side menu titled "Share" where the device will ask which app do you want to share with (or copy to clipboard) and then use that app to share some text and a link of my choosing (same for all users). Again, any LINK I find uses Intent.

At a complete loss here. If you can't give me the tools and a manual how to use them, at least point me in the right direction please.

1

There are 1 answers

0
deczaloth On BEST ANSWER

There are a couple of ways to call the Intent class in your App, one of them, and maybe the best would be by making use of DependencyService.

From the docu:

The DependencyService class is a service locator that enables Xamarin.Forms applications to invoke native platform functionality from shared code.

Small Example for your use case

As you can see from the docu, the first you have to do is to create an Interface to define the method you want to implement. In our case, i will create a simple interface that defines a single method called LaunchAppInPlayStore (this you can call whatever you want!):

namespace App2
{
    public interface Interface1
    {
        void LaunchAppOnPlayStore();
    }
}

Lets go on and implement this in the Android project: for this purpose i add a class called MyInterfaceImplementationAndroid in it and make inherit from Interface1. Then i implement the method from the Interface as follows:

using Xamarin.Forms;
using Android.Content;
using Plugin.CurrentActivity;

[assembly: Dependency(typeof(App2.Droid.MyInterfaceImplementationAndroid))]

namespace App2.Droid
{
    class MyInterfaceImplementationAndroid : Interface1
    {
        public void LaunchAppOnPlayStore()
        {
            CrossCurrentActivity.Current.AppContext.StartActivity(new Intent(Intent.ActionView, Android.Net.Uri.Parse("market://details?id=com.mycompany.myapp")));
        }
    }
}

You should note that in my example i use the Context provided by CurrentActivity plugin by @JamesMontemagno (this is just circumstantial, and in my own apps i myself use a different approach as i described in another SO Post (See the part where i add the MainApplication class to get the Current Context, or see the blog post by @DavidBritch (worth to read!)))

We are almost done! Now you just have to call the method in your shared code as follows: For the sake of this example i created a simple page with a button:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="App2.TestInyection">
    <ContentPage.Content>
        <StackLayout>
            <Button Text="Go to shop!"
                    Clicked="Button_Clicked"
                VerticalOptions="CenterAndExpand" 
                HorizontalOptions="CenterAndExpand" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

and in the code behind i just call the LaunchAppOnPlayStore method as follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace App2
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class TestInyection : ContentPage
    {
        public TestInyection()
        {
            InitializeComponent();
        }

        private void Button_Clicked(object sender, EventArgs e)
        {
            DependencyService.Get<Interface1>().LaunchAppOnPlayStore();
        }
    }
}