I am currently adding notifications to my Android app. I am using VS2015 and Xamarin. I figured I'd create a side project to test it first. I used the documentation from Xamarin and Firebase.
When my app launches, it tries to create a new token, but I get an error instead:
Java.Lang.IncompatibleClassChangeError: The method 'java.io.File android.support.v4.content.ContextCompat.getNoBackupFilesDir(android.content.Context)' was expected to be of type virtual but instead was found to be of type direct
My code for fetching the token is
MainActivity
namespace ClientApp
{
[Activity(Label = "ClientApp", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
TextView msgText;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
msgText = FindViewById<TextView>(Resource.Id.msgText);
if (IsPlayServicesAvailable())
{
var intent = new Intent(this, typeof(RegistrationIntentService3));
StartService(intent);
}
}
public bool IsPlayServicesAvailable()
{
int resultCode = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.Success)
{
if (GoogleApiAvailability.Instance.IsUserResolvableError(resultCode))
msgText.Text = GoogleApiAvailability.Instance.GetErrorString(resultCode);
else
{
msgText.Text = "Sorry, this device is not supported";
Finish();
}
return false;
}
else
{
msgText.Text = "Google Play Services is available.";
return true;
}
}
}
}
RegistrationIntentService.cs
using System;
using Android.App;
using Android.Content;
using Android.Util;
using Android.Gms.Gcm;
using Android.Gms.Gcm.Iid;
using Android.Support.V4.Content;
namespace ClientApp
{
[Service(Exported = false)]
class RegistrationIntentService : IntentService
{
static object locker = new object();
public RegistrationIntentService() : base("RegistrationIntentService") { }
protected override void OnHandleIntent(Intent intent)
{
try
{
Log.Info("RegistrationIntentService", "Calling InstanceID.GetToken");
lock (locker)
{
var token = InstanceID.GetInstance(this).GetToken("My_Sender_ID", GoogleCloudMessaging.InstanceIdScope, null);
Log.Info("RegistrationIntentService", "GCM Registration Token: " + token);
SendRegistrationToAppServer(token);
Subscribe(token);
}
}
catch (Exception e)
{
Log.Debug("RegistrationIntentService", "Failed to get a registration token");
return;
}
}
void SendRegistrationToAppServer(string token)
{
// Add custom implementation here as needed.
}
void Subscribe(string token)
{
var pubSub = GcmPubSub.GetInstance(this);
pubSub.Subscribe(token, "/topics/global", null);
}
}
}
My Manifest looks like this
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="MY_PACKAGE" android:versionCode="1" android:versionName="1.0" android:installLocation="auto">
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="MY_PACKAGE.permission.C2D_MESSAGE" />
<permission android:name="MY_PACKAGE.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<application android:label="RemoteNotifications" android:icon="@drawable/Icon">
<receiver android:name="com.google.android.gms.gcm.GcmReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="MY_PACKAGE" />
</intent-filter>
</receiver>
</application>
<uses-sdk />
</manifest>
All my packages are up to date and using the latest stable:
- Xamarin.GooglePlayServices.Gcm Version 9.0.0.2 with all its dependencies
- Xamarin.Android.Support.v4 Version 24.2.1