2015-12-16 2 views
0

Я пытаюсь настроить приложение 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> 

ответ

1

Я не испытал эту проблему в моем случае при использовании GCM. Сравнивали мою реализацию с вашим текущим кодом, чтобы узнать, найдется ли что-то релевантное. Попробует попробовать использовать контекст приложения, чтобы получить экземпляры, чтобы убедиться, что все экземпляры находятся в одном контексте.

Для InstanceID:

var instanceId = InstanceID.GetInstance(Android.App.Application.Context)); 

Для GcmPubSub:

GcmPubSub pubSub = GcmPubSub.GetInstance(Android.App.Application.Context); 

Для GcmRegistrationService:

GcmRegistrationService.GetIntent(Android.App.Application.Context, "MyTopic"); 

Позвольте мне знать, если помогает.

+0

OMG Спасибо! Я действительно смог вызвать метод 'Subscribe()', не давая мне исключения по Wi-Fi. Я все еще должен подтвердить получение сообщений, но это определенно было пробкой, которая заставляла меня думать, что я псих! –

+0

К сожалению, когда я иду использовать токен, я получаю Not Registered response –

+0

Получил это! Сообщение, которое я пытался отправить, было искажено. Еще раз спасибо за вашу помощь –

Смежные вопросы