2013-10-15 48 views
1

我使用Xamarin創建了使用GCM的android應用程序。 我跟着this guide from Xamarin team然後this guide from Google teamSERVICE_NOT_AVAILABLE在使用Xamarin for Android註冊Google Cloud Messaging時

在我實現Xamarin版本的Gcm之後,我根本沒有在我的BroadcaseReceiver.OnReceive上收到任何東西。這裏是清單和廣播接收器

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
      android:installLocation="auto" 
      package="com.pushtest.droid" 
      android:versionCode="1" 
      android:versionName="1"> 

    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" /> 

    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> 
    <uses-permission android:name="android.permission.GET_ACCOUNTS" /> 
    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.WAKE_LOCK" /> 

    <permission android:name="com.pushtest.droid.permission.C2D_MESSAGE" android:protectionLevel="signature"/> 
    <uses-permission android:name="com.pushtest.droid.permission.C2D_MESSAGE" /> 

    <application android:label="push droid"/> 
</manifest> 

廣播接收器:

[BroadcastReceiver(Permission = "com.google.android.c2dm.permission.SEND")] 
    [IntentFilter(new[] {"com.google.android.c2dm.intent.RECEIVE"}, Categories = new[] {"com.pushtest.droid"})] 
    [IntentFilter(new[] {"com.google.android.c2dm.intent.REGISTRATION"}, Categories = new[] {"com.pushtest.droid"})] 
    [IntentFilter(new[] {"com.google.android.gcm.intent.RETRY"}, Categories = new[] {"com.pushtest.droid"})] 
    public class MyGcmBroadcastReceiver : BroadcastReceiver 
    { 
     public override void OnReceive(Context context, Intent intent) 
     { 
      System.Diagnostics.Debug.WriteLine("MyGcmBroadcastReceiver.OnReceive"); 
      if (intent.Action == "com.google.android.c2dm.intent.REGISTRATION") 
      { 
       var registrationId = intent.GetStringExtra("registration_id"); 
       var error = intent.GetStringExtra("error"); 
       var unregistered = intent.GetStringExtra("unregistered"); 
       System.Diagnostics.Debug.WriteLine("!!!! Registration status |R: {0}|E: {1}|U: {2}", registrationId, error, unregistered); 
      } 
      else if (intent.Action == "com.google.android.c2dm.intent.RECEIVE") 
      { 
       System.Diagnostics.Debug.WriteLine("!!!! Push Received: |TBD|"); 
      } 
     } 
    } 

當我開始打算我只是沒有 - 沒有錯誤,沒有調試信息,沒有結果:

private void RegisterForGcm(Context context) 
     { 
      const string SenderId = "PROJECT_ID_FROM_GOOGLE_CONSOLE"; 
      var appExtra = PendingIntent.GetBroadcast(context, 0, new Intent(), 0); 

      var intent = new Intent("com.google.android.c2dm.intent.REGISTER"); 
      intent.PutExtra("app", appExtra); 
      intent.PutExtra("sender", SenderId); 
      context.StartService(intent); 
     } 

然後我去認爲谷歌的指導終於得到了註冊響應error =「SERVICE_NOT_AVAILABLE」

沒有額外的字符串(沒有registraion_id)。調試信息: !!!!註冊狀態| R:| E:SERVICE_NOT_AVAILABLE | U:

這裏是我的清單和廣播接收器(意向開始是相同的):

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
      android:installLocation="auto" 
      package="com.pushtest.droid" 
      android:versionCode="1" 
      android:versionName="1"> 

    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" /> 

    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> 
    <uses-permission android:name="android.permission.GET_ACCOUNTS" /> 
    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.WAKE_LOCK" /> 

    <permission android:name="com.pushtest.droid.permission.C2D_MESSAGE" android:protectionLevel="signature"/> 
    <uses-permission android:name="com.pushtest.droid.permission.C2D_MESSAGE" /> 

    <application android:label="push droid"> 
    <receiver android:name="com.pushtest.droid.MyGcmBroadcastReceiver" 
       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" /> 
     <action android:name="com.google.android.gcm.intent.RETRY" /> 

     <category android:name="com.pushtest.droid" /> 
     </intent-filter> 
    </receiver> 
    </application> 
</manifest> 

和廣播接收器(沒有任何屬性)

public class MyGcmBroadcastReceiver : BroadcastReceiver 
    { 
     public override void OnReceive(Context context, Intent intent) 
     { 
      System.Diagnostics.Debug.WriteLine("MyGcmBroadcastReceiver.OnReceive"); 
      if (intent.Action == "com.google.android.c2dm.intent.REGISTRATION") 
      { 
       var registrationId = intent.GetStringExtra("registration_id"); 
       var error = intent.GetStringExtra("error"); 
       var unregistered = intent.GetStringExtra("unregistered"); 
       System.Diagnostics.Debug.WriteLine("!!!! Registration status |R: {0}|E: {1}|U: {2}", registrationId, error, unregistered); 
      } 
      else if (intent.Action == "com.google.android.c2dm.intent.RECEIVE") 
      { 
       System.Diagnostics.Debug.WriteLine("!!!! Push Received: |TBD|"); 
      } 
     } 
    } 

測試示例在這裏: https://dl.dropboxusercontent.com/u/19503836/pushtest-issue.zip

我正在嘗試此代碼在我的Android 2.3.6設備 任何幫助非常感謝。

TIA!

+0

你有手機上的谷歌帳戶? – TombMedia

+0

是的,我可以使用此已配置的帳戶訪問Google Play商店 –

+0

並且您已將此應用程序註冊到GCM以獲取API訪問權限嗎?你可以將代碼發佈到你的intentservice嗎? – TombMedia

回答

1

您尚未創建服務[IntentService]類。 啓動服務,但還沒有創建that.BroadCastReceiver看起來象下面這樣:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

using Android.App; 
using Android.Content; 
using Android.OS; 
using Android.Runtime; 
using Android.Views; 
using Android.Widget; 
namespace hellomultiscreen 
{ 

    public class MyGCMBroadcastReceiver : BroadcastReceiver 
    { 

     const string TAG = "PushHandlerBroadcastReceiver"; 
     public override void OnReceive(Context context, Intent intent) 
     { 

      MyIntentService.RunIntentInService(context, intent); 
      SetResult(Result.Ok, null, null); 
      Toast.MakeText(context, "Received Message!", ToastLength.Short).Show(); 
     } 
    } 
} 

和意圖服務會像下面

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

using Android.App; 
using Android.Content; 
using Android.OS; 
using Android.Runtime; 
using Android.Views; 
using Android.Widget; 
using Android.Support.V4.App; 
using Android.Preferences; 
using String = System.String; 
namespace hellomultiscreen 
{ 

    [Service] 
    public class MyIntentService : IntentService 
    { 
     static PowerManager.WakeLock sWakeLock; 
     static object LOCK = new object(); 

     public static void RunIntentInService(Context context, Intent intent) 
     { 
      lock (LOCK) 
      { 
       if (sWakeLock == null) 
       { 
        // This is called from BroadcastReceiver, there is no init. 
        var pm = PowerManager.FromContext(context); 
        sWakeLock = pm.NewWakeLock(
        WakeLockFlags.Partial, "My WakeLock Tag"); 
       } 
      } 

      sWakeLock.Acquire(); 
      intent.SetClass(context, typeof(MyIntentService)); 
      context.StartService(intent); 
     } 

     protected override void OnHandleIntent(Intent intent) 
     { 
      try 
      { 
       Context context = this.ApplicationContext; 
       string action = intent.Action; 

       if (action.Equals("com.google.android.c2dm.intent.REGISTRATION")) 
       { 
        HandleRegistration(context,intent); 
       } 
       else if (action.Equals("com.google.android.c2dm.intent.RECEIVE")) 
       { 
        HandleMessage(intent); 
       } 
      } 
      finally 
      { 
       lock (LOCK) 
       { 
        //Sanity check for null as this is a public method 
        if (sWakeLock != null) 
         sWakeLock.Release(); 
       } 
      } 
     } 
     private void HandleRegistration(Context context, Intent intent) 
     { 
      String registration = intent.GetStringExtra("registration_id"); 
      if (intent.GetStringExtra("error") != null) 
      { 
       // Registration failed, should try again later. 
      } 
      else if (intent.GetStringExtra("unregistered") != null) 
      { 
       // unregistration done, new messages from the authorized sender will be rejected 
      } 
      else if (registration != null) 
      { 

       string score = "Successful Login To Bullseye Account"; 
       long[] vibraPattern = { 0, 500, 250, 500 }; 

       Bundle valuesForActivity = new Bundle(); 
       valuesForActivity.PutString("score", score); 

       // Create the PendingIntent with the back stack    
       // When the user clicks the notification, SecondActivity will start up. 
       Intent resultIntent = new Intent(this, typeof(NotificationDetails)); 
       resultIntent.PutExtras(valuesForActivity); // Pass some values to SecondActivity. 

       TaskStackBuilder stackBuilder = TaskStackBuilder.Create(this); 
       stackBuilder.AddParentStack(Java.Lang.Class.FromType(typeof(NotificationDetails))); 
       stackBuilder.AddNextIntent(resultIntent); 

       PendingIntent resultPendingIntent = stackBuilder.GetPendingIntent(0, (int)PendingIntentFlags.UpdateCurrent); 

       // Build the notification 
       NotificationCompat.Builder builder = new NotificationCompat.Builder(this) 
        .SetAutoCancel(true) // dismiss the notification from the notification area when the user clicks on it 
        .SetContentIntent(resultPendingIntent) // start up this activity when the user clicks the intent. 
        .SetContentTitle(score) // Set the title 
        .SetNumber(1) // Display the count in the Content Info 
        .SetSmallIcon(Resource.Drawable.alert) // This is the icon to display 
        .SetVibrate(vibraPattern) 

        .SetContentText(score); // the message to display. 

       // Finally publish the notification 
       NotificationManager notificationManager = (NotificationManager)GetSystemService(Context.NotificationService); 
       notificationManager.Notify(1, builder.Build()); 

      } 
     } 
     private void HandleMessage(Intent intent) 
     { 
      try 
      { 
       string score = intent.GetStringExtra("message"); 
       long[] vibraPattern = { 0, 500, 250, 500 }; 

       Bundle valuesForActivity = new Bundle(); 
       valuesForActivity.PutString("score", score); 

       // Create the PendingIntent with the back stack    
       // When the user clicks the notification, SecondActivity will start up. 
       Intent resultIntent = new Intent(this, typeof(NotificationDetails)); 
       resultIntent.PutExtras(valuesForActivity); // Pass some values to SecondActivity. 

       TaskStackBuilder stackBuilder = TaskStackBuilder.Create(this); 
       stackBuilder.AddParentStack(Java.Lang.Class.FromType(typeof(NotificationDetails))); 
       stackBuilder.AddNextIntent(resultIntent); 

       PendingIntent resultPendingIntent = stackBuilder.GetPendingIntent(0, (int)PendingIntentFlags.UpdateCurrent); 

       // Build the notification 
       NotificationCompat.Builder builder = new NotificationCompat.Builder(this) 
        .SetAutoCancel(true) // dismiss the notification from the notification area when the user clicks on it 
        .SetContentIntent(resultPendingIntent) // start up this activity when the user clicks the intent. 
        .SetContentTitle(score) // Set the title 
        .SetNumber(1) // Display the count in the Content Info 
        .SetSmallIcon(Resource.Drawable.alert) // This is the icon to display 
        .SetContentText(score); // the message to display. 

       // Finally publish the notification 
       NotificationManager notificationManager = (NotificationManager)GetSystemService(Context.NotificationService); 
       notificationManager.Notify(1, builder.Build()); 

       // 
      } 
      catch 
      { 

      } 
     } 
    } 
} 
0

我從來沒有打算試圖建立自己的推技術,因爲PushSharp工作得很好。他有工作代碼的monodroid和單點觸摸示例。我們一直在使用這個工具,而不是已經修復過的一些舊bug,這個庫已經很穩定。

我已經看過了我的應用程序生成的清單,並在其中獲得了一些你不知道的東西。如果你堅持建立自己的服務,至少要看看他的代碼,看看他是如何做的。

Link to GitHub project

相關問題