Google Play Services Rev 12 Register problem

Hi!
I am using xamarin android 4.10.1 and GooglePlayServices Rev. 12 from xamarin component store. It is mvvmcross application, so I have Core and Android projects. I need push notifications support in my app. So I start with GooglePlayServices component. I write this code:

var gcm = GoogleCloudMessaging.GetInstance(this);
var key = gcm.Register(new[] { "senderId" });

and it doesn't work, I fount that I need to run it on async thread, one solution I found here: http://forums.xamarin.com/discussion/8420/error-calling-googlecloudmessaging-register

ThreadPool.QueueUserWorkItem(o =>
{
    var gcm = GoogleCloudMessaging.GetInstance(this);
    var key = gcm.Register(new[] { Settings.GmcSenderId });
});

This code works, my service handle registration message, but I need this registration key in my mvvmcross ViewModel. So I start to register with Task approach:

var task = Task.Factory.Startnew(() =>
{
    var gcm = GoogleCloudMessaging.GetInstance(this);
    return gcm.Register(new[] { Settings.GmcSenderId });
});
var key = task.Result; // wait for result
// key is needed to execute code here
// ViewModel.Key = key;

But every time I receive SERVICE_NOT_AVAILABLE Exception, also I have try to sync with ManualResetEvent object, but still have exceptions.

Maybe some one know solution, how to bring registration Id to ViewModel class from View (activity). Or maybe you have some example with mvvmcross and receiving registration Id in view model...

Posts

  • public string Register(string senderId)
    {
        var task = Task.Factory.StartNew(() =>
        {
            var context = Mvx.Resolve<IMvxAndroidCurrentTopActivity>().Activity;
            var gcm = GoogleCloudMessaging.GetInstance(context);
            return gcm.Register(senderId);
        });
        return task.Result;
    }
    

    Detailed exception:

    InnerException  {Java.IO.IOException: Exception of type 'Java.IO.IOException' was thrown.
    at Android.Runtime.JNIEnv.CallObjectMethod (IntPtr jobject, IntPtr jmethod, Android.Runtime.JValue[] parms) [0x00064] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.10.1-branch/d23a19bf/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:194 
    at Android.Gms.Gcm.GoogleCloudMessaging.Register (System.String[] p0) [0x00000] in <filename unknown>:0 
    at Fiocx.Android.Code.NotificationService+<>c__DisplayClass1.<Register>b__0 () [0x00013] in d:\ASUS\Work\Programming\.NET\Fiocx.CloudApp\mobile_src\Fiocx.Mobile\Fiocx.Android\Code\NotificationService.cs:33 
    at System.Threading.Tasks.TaskActionInvoker+FuncInvoke`1[System.String].Invoke (System.Threading.Tasks.Task owner, System.Object state, System.Threading.Tasks.Task context) [0x00000] in <filename unknown>:0 
    at System.Threading.Tasks.Task.InnerInvoke () [0x00000] in <filename unknown>:0 
    at System.Threading.Tasks.Task.ThreadStart () [0x00000] in <filename unknown>:0 
    --- End of managed exception stack trace ---
    java.io.IOException: SERVICE_NOT_AVAILABLE
    at com.google.android.gms.gcm.GoogleCloudMessaging.register(Unknown Source)
    at dalvik.system.NativeStart.run(Native Method)
    }   Java.IO.IOException
    
  • CheesebaronCheesebaron DKInsider, University mod

    Are you testing on an Emulator?

  • Using phone with android 4.2.2. In project used API 16

  • AlexSotoAlexSoto MXXamarin Team Xamurai

    Hello

    We have new Google Play Services libraries available at

    Google Play Services

    Google Play Services (Gingerbread)

    Google Play Services (Froyo)

    Please note that Google stopped supporting Froyo on latest Rev 13 so Froyo flavour of the library is Rev 12 based

    Alex

  • sachoksachok UAMember

    Hi!
    Still have same issue with registration. My main goal is to know registration id returned from google server. And I can't do this ( Now I am using google play services v15 (JB) library from xamarin components store. Same exceptions occurs.
    One of the last codes:

    public class GcmNotificationIdService : INotificationService
    {
        public class ThreadHolder
        {
            public ThreadHolder(GoogleCloudMessaging gcm, ManualResetEvent reset)
            {
                GoogleCloudMessaging = gcm;
                ManualResetEvent = reset;
            }
    
            public GoogleCloudMessaging GoogleCloudMessaging { get; set; }
    
            public ManualResetEvent ManualResetEvent { get; set; }
    
            public string Key { get; set; }
        }
    
        private void RegisterAsync(object reset)
        {
            var threadHolder = (reset as ThreadHolder);
            var key = threadHolder.GoogleCloudMessaging.Register(new[]
            {
                Settings.GcmSenderId
            });
            threadHolder.ManualResetEvent.Set();
            threadHolder.Key = key ?? "";
        }
    
        public void Register(string senderId)
        {
            var context = Mvx.Resolve<IMvxAndroidCurrentTopActivity>().Activity;
            var threadHolder = new ThreadHolder(GoogleCloudMessaging.GetInstance(context), new ManualResetEvent(false));
            ThreadPool.QueueUserWorkItem(new WaitCallback(RegisterAsync), threadHolder);
            threadHolder.ManualResetEvent.WaitOne();
            // key needed here!
        }
    }
    

    The same exception Java.IO.IOException - SERVICE_NOT_AVAILABLE.

    Spent 2 days on this... Will be glad for any suggestion

  • kizanlikkizanlik TRMember ✭✭

    Hi @sachok‌,

    I have the same issue. I found a workaround. It works but I feel it is totally wrong. Here is my solution:

    • Create a static WrapperClass and a inner ValuesClass class for sharing values:

      public static class WrapperClass {
      
          private ValuesClass _ValuesClass = new ValuesClass ();
      
          public class ValuesClass {
      
              private String _RegistrationID = null;
      
              public ValuesClass () {
                  // Do Nothing
              }
      
              public String RegistrationID {
                  get { return _RegistrationID; }
                  set { _RegistrationID = value; }
              }
      
          }
      
          public ValuesClass Values {
              get { return _ValuesClass; }
          }
      
      }
      
    • Create a static HelperClass for registering devices to GCM service:

      public static class HelperClass {
      
          public static void Register(Android.App.Activity Activity) {
      
              Task.Run(() => {
                              new Thread (
                                  new ThreadStart (() => {
                                      WrapperClass.Values.RegistrationID = GoogleCloudMessaging.GetInstance (Activity).Register("SenderID");
                                  })).Start ();
      
                  ... do some job here ...
      
              }).wait();
          }
      
      }
      

    Actually this logic has a bug. The Thread in the Task needs to be checked whether it has finished it's job or not.

    This approach could be done by a single static variable but I believe that the WrapperClass logic is more flexible for data processing.

    By the way either GCM's Register or Unregister methods needs to be run in a Thread. System.Threading.Tasks.Task causes Java.IO.Exception exception (inner message is SERVICE_NOT_AVAILABLE) exception.

    This approach works on either emulator or real device.

    I know this thread is old but it seems that the issue is still here (or I am doing something wrong).

    I hope XT or somebody will show the right way.

Sign In or Register to comment.