2015-04-21 2 views
1

Я новичок в xamarin и Android, поэтому этот вопрос может быть простым. Тем не менее, я пытаюсь создать широковещательный приемник и услугу Intent после this articleПриемник Xamarin Broadcast для GCM Удаленные уведомления

Я никогда не сталкиваюсь ни с одной из своих точек отладки в приемнике или службе намерений. Я не уверен, что мне не хватает. Это мой манифест:

<application android:label="gcc"> 
    <receiver android:name=".TrialBR" android:permission="com.google.android.c2dm.permission.SEND"> 
     <intent-filter> 
      <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
      <category android:name="gcc.gcc" /> 
     </intent-filter> 
    </receiver> 
    <service android:name=".MyIntentService" /> 
</application> 
<uses-permission android:name="android.permission.CAMERA" /> 
<uses-permission android:name="android.permission.CALL_PHONE" /> 
<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.WAKE_LOCK" /> 
<uses-permission android:name="android.permission.GET_ACCOUNTS" /> 
<permission android:name="gcc.gcc.permission.C2D_MESSAGE" android:protectionLevel="signature" /> 
<uses-permission android:name="gcc.gcc.permission.C2D_MESSAGE" /> 
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> 
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> 

Я не совсем уверен в имени пакета. Я просто следую за именем пакета в настройках андроида проекта. Это мой приемник:

[BroadcastReceiver] 
[IntentFilter(new[] { Android.Content.Intent.ActionBootCompleted })] 
public class TrialBR : BroadcastReceiver 
{ 
    public override void OnReceive (Context context, Intent intent) 
    { 
     MyIntentService.RunIntentInService(context, intent); 
     SetResult(Result.Ok, null, null); 
     Toast.MakeText (context, "Received intent!", ToastLength.Short).Show(); 
    } 
} 

и это моя цель службы:

[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(context, intent); 
      } 
     } 
     finally 
     { 
      lock (LOCK) 
      { 
       //Sanity check for null as this is a public method 
       if (sWakeLock != null) 
        sWakeLock.Release(); 
      } 
     } 
    } 

    void HandleRegistration (Context context, Intent intent) 
    { 
     string senders = "123456789"; 
     Intent intent1 = new Intent("com.google.android.c2dm.intent.REGISTER"); 
     intent1.SetPackage("com.google.android.gsf"); 
     intent1.PutExtra("app", PendingIntent.GetBroadcast(context, 0, new Intent(), 0)); 
     intent1.PutExtra("sender", senders); 
     context.StartService(intent1); 
    } 

    void HandleMessage (Context context, Intent intent) 
    { 
     string registrationId = intent.GetStringExtra("registration_id"); 
     string error = intent.GetStringExtra("error"); 
     string unregistration = intent.GetStringExtra("unregistered"); 
     Console.WriteLine ("Registration ID: " + registrationId); 
    } 
} 

Я был бы очень признателен, если кто-то может мне точку в правильном направлении, что это то, что я делаю неправильно. Я буду очень признателен.

+0

Вы пробовали мое решение ниже? – IdoT

ответ

0

Я опубликовал ответ по этому вопросу здесь: https://stackoverflow.com/a/29141884/2452682

Но от быстрого взгляда от вашего решения, в первую очередь, вы можете удалить эти определения вручную из файла манифеста, и поместить их в коде. это может быть причиной того, что вы не получаете push-уведомлений, так как я вижу некоторые отличия между моим сгенерированным файлом манифеста и вашим (приемник выглядит совершенно иначе)

В любом случае, я скопировал только часть андроида реализации из моего решение, предложенное в ссылке:

1) в вашем общем проекте, создать интерфейс IPushNotificationRegister

public interface IPushNotificationRegister 
{ 
    void ExtractTokenAndRegister(); 
} 

Этот интерфейс используется для извлечения толкающего маркера, а затем отправить его на сервер. этот токен уникален для каждого устройства.

2) В вашем общем projjct вы должны вызывать ExtractTokenAndRegister (используя ваш любимый IOC, я назвал его сразу после входа в систему).

Android Реализация:

Добавить приемники для прослушивания событий, полученных службой Google GCM:

а) [BroadcastReceiver] [IntentFilter(new[] { Intent.ActionBootCompleted })] public class GCMBootReceiver : BroadcastReceiver { public override void OnReceive(Context context, Intent intent) { MyIntentService.RunIntentInService(context, intent); SetResult(Result.Ok, null, null); } }

б)

[assembly: Permission(Name = "@[email protected]_MESSAGE")] 
    [assembly: UsesPermission(Name = "android.permission.WAKE_LOCK")] 
    [assembly: UsesPermission(Name = "@[email protected]_MESSAGE")] 
    [assembly: UsesPermission(Name = "com.google.android.c2dm.permission.RECEIVE")] 
    [assembly: UsesPermission(Name = "android.permission.GET_ACCOUNTS")] 
    [assembly: UsesPermission(Name = "android.permission.INTERNET")] 

namespace Consumer.Mobile.Droid.PushNotification 
{ 
    [BroadcastReceiver(Permission = "com.google.android.c2dm.permission.SEND")] 
    [IntentFilter(new string[] { "com.google.android.c2dm.intent.RECEIVE" }, Categories = new string[] { "@[email protected]" })] 
    [IntentFilter(new string[] { "com.google.android.c2dm.intent.REGISTRATION" }, Categories = new string[] { "@[email protected]" })] 
    [IntentFilter(new string[] { "com.google.android.gcm.intent.RETRY" }, Categories = new string[] { "@[email protected]" })] 
    [IntentFilter (new[]{ Intent.ActionBootCompleted }, Categories = new[]{ Intent.CategoryDefault })] 
    public class GCMBroadcastReceiver : BroadcastReceiver 
    { 
     public override void OnReceive(Context context, Intent intent) 
     { 
      MyIntentService.RunIntentInService(context, intent); 
      SetResult(Result.Ok, null, null); 
     } 
    } 
} 

с) Добавить Intent услуги для обработки уведомления

using Android.App; 
using Android.Content; 
using Android.Graphics; 
using Android.Media; 
using Android.OS; 
using Android.Support.V4.App; 
using Consumer.Mobile.Infra; 
using Consumer.Mobile.Services.PushNotification; 
using Java.Lang; 
using XLabs.Ioc; 
using TaskStackBuilder = Android.Support.V4.App.TaskStackBuilder; 

namespace Consumer.Mobile.Droid.PushNotification 
{ 
    [Service] 
    public class MyIntentService : IntentService 
    { 
     private readonly ILogger _logger; 
     private readonly IPushNotificationService _notificationService; 
     private readonly IPushNotificationRegister _pushNotificationRegister; 

     public MyIntentService() 
     { 
      _logger = Resolver.Resolve<ILogger>(); 
      _notificationService = Resolver.Resolve<IPushNotificationService>(); 
      _pushNotificationRegister = Resolver.Resolve<IPushNotificationRegister>(); 
     } 

     static PowerManager.WakeLock _sWakeLock; 
     static readonly 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(context, intent); 
       } 
      } 
      finally 
      { 
       lock (Lock) 
       { 
        //Sanity check for null as this is a public method 
        if (_sWakeLock != null) 
         _sWakeLock.Release(); 
       } 
      } 
     } 

     private void HandleMessage(Context context, Intent intent) 
     { 

      Intent resultIntent = new Intent(this, typeof(MainActivity)); 


      TaskStackBuilder stackBuilder = TaskStackBuilder.Create(this); 

      var c = Class.FromType(typeof(MainActivity)); 
      stackBuilder.AddParentStack(c); 
      stackBuilder.AddNextIntent(resultIntent); 

      string alert = intent.GetStringExtra("Alert"); 
      int number = intent.GetIntExtra("Badge", 0); 

      var imageUrl = intent.GetStringExtra("ImageUrl"); 
      var title = intent.GetStringExtra("Title"); 

      Bitmap bitmap = GetBitmap(imageUrl); 

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

      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(title) // Set the title 
       .SetNumber(number) // Display the count in the Content Info 
       .SetSmallIcon(Resource.Drawable.Icon) // This is the icon to display 
       .SetLargeIcon(bitmap) 
       .SetSound(RingtoneManager.GetDefaultUri(RingtoneType.Notification)) 
       .SetContentText(alert); // the message to display. 

      // Build the notification: 
      Notification notification = builder.Build(); 

      // Get the notification manager: 
      NotificationManager notificationManager = 
       GetSystemService(Context.NotificationService) as NotificationManager; 

      // Publish the notification: 
      const int notificationId = 0; 
      notificationManager.Notify(notificationId, notification); 
     } 

     private void HandleRegistration(Context context, Intent intent) 
     { 
      var token = intent.GetStringExtra("registration_id"); 
      _logger.Info(this.Class.SimpleName, "Received Token : " + token); 

      if (_pushNotificationRegister.ShouldSendToken(token)) 
      { 
       var uid = Android.Provider.Settings.Secure.GetString(MainActivity.Context.ContentResolver, Android.Provider.Settings.Secure.AndroidId); 
       _notificationService.AddPushToken(token, DeviceUtils.GetDeviceType(), uid); 
      } 
     } 


     private Bitmap GetBitmap(string url) 
     { 

      try 
      { 
       System.Net.WebRequest request = 
        System.Net.WebRequest.Create(url); 
       System.Net.WebResponse response = request.GetResponse(); 
       System.IO.Stream responseStream = 
        response.GetResponseStream(); 
       return BitmapFactory.DecodeStream(responseStream); 


      } 
      catch (System.Net.WebException) 
      { 
       return null; 
      } 

     } 

    } 
} 

d) Внедрение интерфейса IPushNotificationRegister: с использованием Android.App; с использованием Android.Content; с использованием Consumer.Mobile.Services; с использованием Consumer.Mobile.Services.PushNotification;

[assembly: Permission(Name = "@[email protected]_MESSAGE")] 
[assembly: UsesPermission(Name = "@[email protected]_MESSAGE")] 

// Gives the app permission to register and receive messages. 
[assembly: UsesPermission(Name = "com.google.android.c2dm.permission.RECEIVE")] 

// Needed to keep the processor from sleeping when a message arrives 
[assembly: UsesPermission(Name = "android.permission.WAKE_LOCK")] 
[assembly: UsesPermission(Name = "android.permission.RECEIVE_BOOT_COMPLETED")] 
namespace Consumer.Mobile.Droid.PushNotification 
{ 
    public class PushNotificationRegister : IPushNotificationRegister 
    {   
     public override void ExtractTokenAndRegister() 
     { 
      string senders = AndroidConfig.GCMSenderId; 
      Intent intent = new Intent("com.google.android.c2dm.intent.REGISTER"); 
      intent.SetPackage("com.google.android.gsf"); 
      intent.PutExtra("app", PendingIntent.GetBroadcast(MainActivity.Context, 0, new Intent(), 0)); 
      intent.PutExtra("sender", senders); 
      MainActivity.Context.StartService(intent); 
     } 


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