1

After starting a new activity I'm trying to open a new xamarin.form but the SetContentView method wants an Android.Views.View input and I do not know how to recover the view from an xamarin.form

Can someone help me? Thanks

[Activity(Label = "SecondActivity", Icon = "@drawable/icon", MainLauncher = true, NoHistory = true)]
public class SecondActivity : Activity
{
    public SecondActivity() { }

    protected async override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        UsbSerialPage page = new UsbSerialPage();   // This is a ContentPage

        // Don't work because UsbSerialPage is a ContentPage (xaml) and not an axml page
        SetContentView(Resource.Layout.UsbSerialPage);

        // Don't work because page is not a Android.Views.View
        SetContentView(page);
    }
}
SushiHangover
  • 73,120
  • 10
  • 106
  • 165
Stefano
  • 21
  • 3
  • Are you using a standard `Xamarin.Form` solution/project or using `Xamarin.Forms` native embedding? – SushiHangover Feb 08 '18 at 08:54
  • Xamarin.Form CrossPlatform with Visual Studio 2017 – Stefano Feb 08 '18 at 09:08
  • A `Xamarin.Forms` based application lives entirely within ONE Activity (typically `MainActivity` when created via template), you perform all the page navigation within the Forms based code and do not create additional native Android Activities : https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/ – SushiHangover Feb 08 '18 at 09:17
  • I have an application that must be connected to other devices via USB - serial or via Bluetooth or via NFC. My idea was to create a secondary activity for managing communication via USB that would only serve in a part of the application and then I thought of putting it in the MainActivity. I can not use this idea so I have to implement everything in MainActivity? Thank you – Stefano Feb 08 '18 at 09:31
  • Hi, have you solved your problem? – Robbit Feb 12 '18 at 07:45
  • Thank's see below! ;-) – Stefano Feb 14 '18 at 08:44

4 Answers4

1

You can use DependencyService to call the methods, like GetSystemService.

these methods must be in a class inherited from Activity

In Xamarin.Forms, you can use Xamarin.Forms.Forms.Context to achieve it, you can refer to this and this.

Update:

My test codes:

using Android.Content;
using Xamarin.Forms;
using App2.Droid;
using Android.Hardware.Usb;

[assembly:Dependency(typeof(SendImpl))]
namespace App2.Droid
{
    class SendImpl : ISend
    {
        public void Send()
        {
            //Intent intent = new Intent("com.worldgn.connector.HR_MEASUREMENT");
            //intent.PutExtra("HR_MEASUREMENT","value");
            //Forms.Context.SendBroadcast(intent);
            UsbManager usbManager= Forms.Context.GetSystemService(Context.UsbService) as UsbManager;
        }
    }
}
Community
  • 1
  • 1
Robbit
  • 4,300
  • 1
  • 13
  • 29
  • Hi, I have updated my answer, you can refer to it. About `obsolete`, can you show what is your min version and what is your target version? – Robbit Feb 12 '18 at 08:07
  • Sorry I did not understand the question. Version of Android or Xamarin or Visual Studio? – Stefano Feb 14 '18 at 08:45
  • Xamarin.Forms.Forms.Context.GetSystemService(Context.UsbService) is obsolete... :-( I think I solved as I wrote before, do you think it's okay? Thanks – Stefano Feb 14 '18 at 08:49
0

Because you are working with A Xamarin.Forms project you have to work with the portable project to navigate between pages. You are trying to navigate to A ContentPage(which is a portable xaml page) from you Android Project. Instead of this, you have to go to your first XAML page (MainPage.xaml) and the code behind of this (MainPage.xaml.cs) and you can navigate from there to your UsbSerialPage using PushAsync(new UsbSerailPage());.

Athan CB
  • 29
  • 7
  • Thanks for the reply. The "problem" is that UsbSerailPage uses methods to retrieve information on the USB port and these methods must be in a class inherited from Activity so I thought to create another activity, not to use the MainActivity for example: Android.Hardware.Usb.UsbManager usbManager = GetSystemService(Context.UsbService) as UsbManager; var permissionGranted = await usbManager.RequestPermissionAsync(selectedPort.Driver.Device, this); – Stefano Feb 08 '18 at 17:24
0

Thanks for the reply. The "problem" is that UsbSerailPage uses methods to retrieve information on the USB port and these methods must be in a class inherited from Activity so I thought to create another activity, not to use the MainActivity

for example:

Android.Hardware.Usb.UsbManager usbManager = GetSystemService(Context.UsbService) as UsbManager;
var permissionGranted = await usbManager.RequestPermissionAsync(selectedPort.Driver.Device, this);
Stefano
  • 21
  • 3
  • Why not use [DependencyService](https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/dependency-service/introduction/) to design you project? – Robbit Feb 09 '18 at 03:23
  • DependencyService allows you to use methods inherited from Activity such as the GetSystemService (Context.UsbService) as UsbManager method? Thanks – Stefano Feb 09 '18 at 08:14
  • Yes, you can use `Xamarin.Forms.Forms.Context.GetSystemService()` – Robbit Feb 09 '18 at 08:26
  • The `GetSystemService` method belongs to [Context](https://developer.android.com/reference/android/content/Context.html#getSystemService(java.lang.String)), Activity just is one kind of Context, Service and Application also belong to Context. – Robbit Feb 09 '18 at 08:29
  • It is impossible, could you please edit your first question with your codes? – Robbit Feb 12 '18 at 07:47
0

I used the MainViewModel creating various classes passing as MainActivity parameter in order to always have the Activity methods available in any subclass:

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    /// <summary>
    /// Restituisce la MainActivity.
    /// </summary>
    public static MainActivity Instance { get; private set; }

    /// <summary>
    /// Classe per la gestione del device.
    /// </summary>
    public DeviceBase deviceScelto = null;

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        Instance = this;
        // other...
    }
}

public class DeviceService : IDeviceService
{
    /// <summary>
    /// Restituisce il device istanziato.
    /// </summary>
    /// <returns>Device.</returns>
    public IDeviceApp GetDeviceApp()
    {
        switch (App.DeviceScelto)
        {
            case App.EnumDeviceType.UsbSerial:
                MainActivity.Instance.deviceScelto = new UsbSerialDevice(MainActivity.Instance);
                break;

            case App.EnumDeviceType.Bluetooth:
                MainActivity.Instance.deviceScelto = new BluetoothDevice(MainActivity.Instance);
                break;

            default:
            case App.EnumDeviceType.NFC:
                MainActivity.Instance.deviceScelto = new NfcDevice(MainActivity.Instance);
                break;
        }

        return MainActivity.Instance.deviceScelto;
    }
}

public class UsbSerialDevice : DeviceBase, IDeviceApp
{
    public Activity mainActivity;

    /// <summary>
    /// Classe per la gestione del device USB-Seriale ereditata da <see cref="DeviceBase"/> e <see cref="IDeviceApp"/>.
    /// </summary>
    /// <param name="mainActivity">MainActivity.</param>
    public UsbSerialDevice(Activity mainActivity)
    {
        this.mainActivity = mainActivity;
        this.usbManager = this.mainActivity.GetSystemService(Context.UsbService) as UsbManager;
    }
}

Thank you all, if you have any other advice tell me as well! ;-)

Stefano

Stefano
  • 21
  • 3