Я пытаюсь настроить приложение Xamarin Forms для использования Google Cloud Messaging (GCM), и я столкнулся с очень странным поведением. В настоящее время я использую Xamarin Studio в Windows и следую за их remote notification walkthrough.Проблемы с подключением к облачным сообщениям Google
По какой-то причине GCMPubSub.Subscribe()
работает только по сотовой связи, а не по Wi-Fi. Я пробовал разные Wi-Fi-сети с тем же результатом. Возможно ли, что сценарий разработки использует несколько разных портов или поведение сети, которые нет в настройках производства? С моим телефоном Android в этих разных сетях никогда не возникало проблем с получением push-уведомлений.
Любые мысли?
Редактировать
ошибка, что я в настоящее время приема является IOException
с сообщением «Неверные параметры», когда Subscribe()
вызывается в GcmRegistrationService
, но только тогда, когда в сети Wi-Fi. Я пытался сравнивать то, что я сделал с примерами GCM Android, и они ведут себя подобно
В MainActivity:
[Activity(Label = "MyApp", Icon = "@drawable/icon", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App(DeviceType.Android));
if (IsPlayServicesAvailable())
{
var intent = GcmRegistrationService.GetIntent(this, "MyTopic");
StartService(intent);
}
}
public bool IsPlayServicesAvailable()
{
var resultCode = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.Success)
{
if (GoogleApiAvailability.Instance.IsUserResolvableError(resultCode))
ToastHelper.ShowStatus("Google Play Services error: " + GoogleApiAvailability.Instance.GetErrorString(resultCode));
else
{
ToastHelper.ShowStatus("Sorry, this device is not supported");
Finish();
}
return false;
}
else
{
ToastHelper.ShowStatus("Google Play Services is available.");
return true;
}
}
}
Регистрация GCM Намерение:
/// <summary>
/// The background process that handles retrieving GCM token
/// </summary>
[Service(Exported = false)]
public class GcmRegistrationService : IntentService
{
private static readonly object Locker = new object();
public GcmRegistrationService() : base("GcmRegistrationService") { }
public static Intent GetIntent(Context context, string topic)
{
var valuesForActivity = new Bundle();
valuesForActivity.PutString("topic", topic);
var intent = new Intent(context, typeof(GcmRegistrationService));
intent.PutExtras(valuesForActivity);
return intent;
}
protected override void OnHandleIntent(Intent intent)
{
try
{
// Get the count value passed to us from MainActivity:
var topic = intent.Extras.GetString("topic", "");
if (string.IsNullOrWhiteSpace(topic))
throw new Java.Lang.Exception("Missing topic value");
Log.Info("RegistrationIntentService", "Calling InstanceID.GetToken");
lock (Locker)
{
var instanceId = InstanceID.GetInstance(this);
var projectNumber = Resources.GetString(Resource.String.ProjectNumber);
var token = instanceId.GetToken(projectNumber, GoogleCloudMessaging.InstanceIdScope, null);
Log.Info("RegistrationIntentService", "GCM Registration Token: " + token);
var applicationState = DataCacheService.GetApplicationState();
// Save the token to the server if the user is logged in
if(applicationState.IsAuthenticated)
SendRegistrationToAppServer(applicationState.DeviceId, token);
Subscribe(token, topic);
}
}
catch (SecurityException e)
{
Log.Debug("RegistrationIntentService", "Failed to get a registration token because of a security exception");
Log.Debug ("RegistrationIntentService", "Exception message: " + e.Message);
ToastHelper.ShowStatus("Google Cloud Messaging Security Error");
return;
}
catch (Java.Lang.Exception e)
{
Log.Debug("RegistrationIntentService", "Failed to get a registration token");
Log.Debug ("RegistrationIntentService", "Exception message: " + e.Message);
ToastHelper.ShowStatus("Google Cloud Messaging Error");
return;
}
}
void SendRegistrationToAppServer(Guid deviceId, string token)
{
// Save the Auth Token on the server so messages can be pushed to the device
DeviceService.UpdateCloudMessageToken (deviceId, token);
}
void Subscribe(string token, string topic)
{
var pubSub = GcmPubSub.GetInstance(this);
pubSub.Subscribe(token, "/topics/" + topic, new Bundle());
Log.Debug("RegistrationIntentService", "Successfully subscribed to /topics/" +topic);
DataCacheService.SaveCloudMessageToken(token, topic);
}
}
AndroidManifest.xml:
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
android:installLocation="auto"
package="com.myapp"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="19" />
<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="android.permission.ACCESS_NETWORK_STATE" />
<permission
android:name="com.myapp.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission
android:name="com.myapp.permission.C2D_MESSAGE" />
<application
android:label="My App"
android:icon="@drawable/icon">
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:permission="com.google.android.c2dm.permission.SEND"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.myapp" />
</intent-filter>
</receiver>
<service
android:name="com.myapp.XamarinMobile.Droid.Services.MyGcmListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
</application>
</manifest>
OMG Спасибо! Я действительно смог вызвать метод 'Subscribe()', не давая мне исключения по Wi-Fi. Я все еще должен подтвердить получение сообщений, но это определенно было пробкой, которая заставляла меня думать, что я псих! –
К сожалению, когда я иду использовать токен, я получаю Not Registered response –
Получил это! Сообщение, которое я пытался отправить, было искажено. Еще раз спасибо за вашу помощь –