我試圖設置一個Xamarin Forms應用程序來使用Google Cloud Messaging(GCM),我遇到了一個非常奇怪的行爲。我目前在Windows上使用Xamarin Studio並遵循其remote notification walkthrough。Google Cloud Messaging連接問題
由於某些原因,GCMPubSub.Subscribe()
只適用於蜂窩連接而不適用於WiFi。我試過不同的wifi網絡,結果相同。開發場景是否可能使用生產設置不支持的一些不同的端口或網絡行爲?在接收推送通知的這些不同網絡上,我的Android手機從未出現過問題。
有什麼想法?
編輯
我目前接收與「無效參數」的消息的IOException
時Subscribe()
被稱爲GcmRegistrationService
錯誤,但只有當連接到WiFi網絡。我試着比較我做了什麼給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()'方法,而不通過wifi給我一個例外。我仍然必須確認收到的消息,但這絕對是一個讓我覺得我很瘋狂的表演塞! –
不幸的是,當我去使用令牌時,我收到一個未註冊的響應 –
讓它工作!我試圖發送的消息格式不正確。再次感謝您的幫助 –