我正在尝试从服务器应用程序向移动应用程序发送简单的发送通知。 我的移动应用程序是使用Xamarin.Android实现的,对于服务器应用程序,我使用的是简单的.NET控制台应用程序,只是为了将通知传递给Google云消息传递。
这是我的服务器应用代码:
class Program
{
public const string API_KEY = "MYAPICODE";
public const string MESSAGE = "Hello world!";
public static void Main(string[] args)
{
var jGcmData = new JObject();
var jData = new JObject();
jData.Add("message", MESSAGE);
jGcmData.Add("to", "/topics/global");
jGcmData.Add("data", jData);
var url = new Uri("https://gcm-http.googleapis.com/gcm/send");
try
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.TryAddWithoutValidation(
"Authorization", "key=" + API_KEY);
Task.WaitAll(client.PostAsync(url,
new StringContent(jGcmData.ToString(), Encoding.GetEncoding(0), "application/json"))
.ContinueWith(response =>
{
Console.WriteLine(response);
}));
}
}
catch (Exception e)
{
Console.WriteLine("Unable to send GCM message:");
}
}
}
在客户端,我在Manifest文件中有这个:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="za.co.beemobile.mylegislature" android:installLocation="auto">
<uses-sdk android:minSdkVersion="14" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<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.WRITE_SECURE_SETTINGS" />
<uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<user-premission android:name="za.co.beemobile.mylegislature.permission.C2D_MESSAGE" />
<permission android:name="za.co.beemobile.mylegislature.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<application android:label="My Legislature" android:icon="@drawable/my_parliament">
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
<receiver android:name="com.google.android.gms.gcm.GcmReceiver" android:exported="true" 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.c2dm.intent.GCM_RECEIVED_ACTION"/>
<category android:name="za.co.beemobile.mylegislature" />
</intent-filter>
</receiver>
</application>
</manifest>
这是我在客户端上使用的代码:
[Service(Exported = false)]
class RegistrationIntentService : IntentService
{
static object locker = new object();
private const string SENDER_ID = "MYSENDERID";
public RegistrationIntentService() : base("RegistrationIntentService") { }
protected override void OnHandleIntent(Intent intent)
{
try
{
Log.Info("RegistrationIntentService", "Calling InstanceID.GetToken");
lock (locker)
{
var instanceID = InstanceID.GetInstance(this);
var token = instanceID.GetToken(
SENDER_ID, GoogleCloudMessaging.InstanceIdScope, null);
Log.Info("RegistrationIntentService", "GCM Registration Token: " + token);
SendRegistrationToAppServer(token);
Subscribe(token);
}
}
catch (Exception e)
{
Log.Debug("RegistrationIntentService", "Failed to get a registration token");
return;
}
}
void SendRegistrationToAppServer(string token)
{
// Add custom implementation here as needed.
}
void Subscribe(string token)
{
var pubSub = GcmPubSub.GetInstance(this);
pubSub.Subscribe(token, "/topics/global", null);
}
}
这是来自MyLegislatureInstanceIDListenerService.cs
class:
[Service(Exported = true), IntentFilter(new[] { "com.google.android.gms.iid.InstanceID" })]
public class MyLegislatureInstanceIDListenerService : InstanceIDListenerService
{
public override void OnTokenRefresh()
{
var intent = new Intent(this, typeof(RegistrationIntentService));
StartService(intent);
}
}
这就是事件代码的地方:
[Service(Exported = false), IntentFilter(new[] { "com.google.android.c2dm.intent.RECEIVE" })]
public class MyGcmListenerService : GcmListenerService
{
public override void OnMessageReceived(string from, Bundle data)
{
var message = data.GetString("message");
SendNotification(message);
}
void SendNotification(string message)
{
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);
var notificationBuilder = new Notification.Builder(this)
.SetSmallIcon(Resource.Drawable.clock)
.SetContentTitle("BEE")
.SetContentText(message)
.SetAutoCancel(true)
.SetContentIntent(pendingIntent);
var notificationManager = (NotificationManager)GetSystemService(Context.NotificationService);
notificationManager.Notify(0, notificationBuilder.Build());
}
}
发生的事情是,当我第一次运行代码时,消息接收事件的断点被点击,我从服务器应用程序发送的通知显示在android模拟器上。 每个下一次尝试向同一个模拟器发送相同的通知都不起作用。即使从服务器向GCM发送消息,事件内的断点也从未被命中。 有人有这个问题吗?我做错了什么?我希望能够多次发送此通知。
注意:即使我运行Android和服务器应用程序的新实例,也不会发送消息。