目录
- 1、背景说明
 - 1.1 开发环境
 - 1.2 实现效果
 - 1.2.1 推送的界面
 - 1.2.2 推送的设置
 - 1.2.3 推送的功能实现
 - 1.2.3.1、`Activity`的设置【重要】
 - 1.2.3.2、代码的实现
 
- 2、源码下载
 - 3、总结
 - 4、参考资料
 
1、背景说明
在App开发中,通知(或消息)的推送,是必须要有的功能。若在纯互联网的环境中,可以使用第三方的通知推送的功能,例如:小米推送、极光推送等,这个可以参考第三方的使用手册既可。但是在局域网中,例如医院内部的局域网中,则无法使用第三方的通知推送。因此在局域网环境中实现App通知推送的功能,就非常重要和关键。
本文将分为上下两部分。第一部分主要阐述Xamarin.Android的通知推送的功能实现。第二部分阐述如何在局域网环境下实现推送,并借助第一部分消息推送,从而实现整体的通知推送。
1.1 开发环境
使用VS2022社区版17.10.1,其中Xamarin为17.10.0.110
1.2 实现效果
Xamarin.Android中实现通知推送与Android基本一致。实现的效果如下:
 
 图1 为主界面,点击右下角信封按钮,则系统会进行消息推送(主界面为:MainActivity)
 
 图2 系统收到推送后,在状态栏中弹出的推送内容
 
 图3 当点击状态栏中的推送消息时,跳转到该推送的详细说明页面(即后续的NotificationDetailInfoActivity)
 
 图4 当在推送详细页面(NotificationDetailInfoActivity)点击返回按钮后,App返回至第二个Activity(即:SecondActivity)
 
 图5 在图4的界面上(即SecondActivity),点击返回按钮后,App返回至主界面(即MainActivity)
1.2.1 推送的界面
在整个工程中,涉及到3个Activity:MainActivity、SecondActivity、NotificationDetailInfoActivity。如下图6所示
 
 图6 工程涉及到的三个Activity
1.2.2 推送的设置
因为推送是在Activity中发生,所以需要再Activity的OnCreate方法中初始化通知设置(NotificationChannel)
private string CHANNEL_ID = "20000";
protected override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);
    //初始化一个Channel
    CreateNotificationChannel();
}
void CreateNotificationChannel()
{
    if (Build.VERSION.SdkInt < BuildVersionCodes.O)
    {
        // Notification channels are new in API 26 (and not a part of the
        // support library). There is no need to create a notification
        // channel on older versions of Android.
        return;
    }
    var channelName = Resources.GetString(Resource.String.second_channel_name);
    var channelDescription = GetString(Resource.String.second_channel_description);
    var channel = new NotificationChannel(CHANNEL_ID, channelName, NotificationImportance.Default)
    {
        Description = channelDescription
    };
    var notificationManager = (NotificationManager)GetSystemService(NotificationService);
    notificationManager.CreateNotificationChannel(channel);
}
 
其中会涉及到Channel的名称和描述。也就是Resource.String.second_channel_name和Resource.String.second_channel_description。这部分信息在Strings.xml中。具体如下:
<resources>
    <string name="app_name">通知推送Demo</string>
    <string name="action_settings">Settings</string>
	<string name="channel_name">推送测试的名称</string>
	<string name="channel_description">用于说明本推送的具体内容</string>
	<string name="second_channel_name">第二个推送的名称</string>
	<string name="second_channel_description">第二个用于说明推送的说明性文字(例如:本推送用于推送患者的用药服用信息!)</string>
</resources>
 
在MainActivity、SecondActivity中的OnCreate方法中都应用,因此效果如下
 
 图7 在MainActivity、SecondActivity设置通知后,可以在手机的通知界面看到这两个推送的设置
 
 图8 这个是MainActivity中推送设置
 
 图8 这个是SecondActivity中推送设置详细信息界面,可以看到标题和提示的内容
1.2.3 推送的功能实现
1.2.3.1、Activity的设置【重要】
 
若要设置返回时,按指定的顺序返回,则必须要设置Activity的ParentActivity属性。在Android原生开发中,是在AndroidManifest.xml进行设置的。设置一般是这样子的:
<activity android:name=".MessageActivity"  android:parentActivityName=".MainActivity"/>
 
但是,在Xamarin.Android中,没法在AndroidManifest.xml设置,需要在Activity.cs中定义。
//在这儿设置******【重要】
[Activity(Label = "SecondActivity", ParentActivity = typeof(MainActivity))]
public class SecondActivity : Activity
{
    private TextView tvTitle;
    private string CHANNEL_ID = "20000";
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        // Create your application here
        CreateNotificationChannel();//设置推送的通知
    }
    ....
 
这个地方是最特殊的地方,一定要注意。
 在本项目中,将NotificationDetailInfoActivity的ParentActivity设为SecondActivity;而SecondActivity的ParentActivity设置为MainActivity。
1.2.3.2、代码的实现
以上设置完成后,便可以在按钮的click方法中,实现消息的推送及实现,代码如下:
private void FabOnClick(object sender, EventArgs eventArgs)
{
    //View view = (View) sender;
    //Snackbar.Make(view, "Replace with your own action", Snackbar.LengthLong)
    //    .SetAction("Action", (View.IOnClickListener)null).Show();
    //第二步,在某个地方触发这个通知(此处是点击按钮)
    //点击推送通知后,要调用起来的Activity
    Intent intent = new Intent(this, typeof(NotificationDetailInfoActivity));
    //传递的数据。也可以使用Bundle,可以搜索Bundle传值
    intent.PutExtra("message", "附加的详细信息,用于展示提示的具体内容!");
    //创建TaskStackBuilder,用于形成任务链,就是点击通知后,后续的返回界面等设置
    Android.App.TaskStackBuilder stackBuilder = Android.App.TaskStackBuilder.Create(this);
    //1、在Activity中设置ParentActivity属性。在Android的原生开发中,是在Manifest中设置,
    //但是在Xamarin中,需要直接在Activity中设置
    //2、直接调用AddNextIntentWithParentStack方法既可
    stackBuilder.AddNextIntentWithParentStack(intent);
    //网络上的设置,但在Xamarin中没有作用
    //stackBuilder.AddParentStack(Java.Lang.Class.FromType(typeof(MainActivity)));
    //stackBuilder.AddParentStack(Java.Lang.Class.FromType(typeof(SecondActivity)));
    //stackBuilder.AddNextIntent(intent);
    //设置PendingIntent
    const int pendingIntentId = 0;
    PendingIntent pendingIntent =stackBuilder.GetPendingIntent(pendingIntentId, PendingIntentFlags.UpdateCurrent);
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .SetContentIntent(pendingIntent)
        .SetContentTitle("推送的标题内容") //1
        .SetContentText("推送的具体内容信息") //2
        .SetAutoCancel(true)  //设置自动取消
        .SetWhen(Java.Lang.JavaSystem.CurrentTimeMillis())
        .SetSmallIcon(Resource.Drawable.zl001);
    
    //调用通知
    Notification notification = builder.Build();
    NotificationManager notificationManager = GetSystemService(Context.NotificationService) as NotificationManager;
    const int notificationId = 1;
    notificationManager.Notify(notificationId, notification);
}
 
代码说明:
 1、网上查找的资料(设置微软的官网上),在设置返回时,是如下面代码设置的。
//stackBuilder.AddParentStack(Java.Lang.Class.FromType(typeof(MainActivity)));
//stackBuilder.AddParentStack(Java.Lang.Class.FromType(typeof(SecondActivity)));
//stackBuilder.AddNextIntent(intent);
 
但在实际使用中,确是不起作用。在NotificationDetailInfoActivity界面,点击返回时,会返回至MainActivity,而不是按照指定的顺序进行。
因此直接使用了stackBuilder.AddNextIntentWithParentStack(intent);这句话。按自身的Stack顺序,进行返回。
2、PendingIntentFlags.UpdateCurrent标识位
 这个标识位有很多,比较简单,使用比较多就是UpdateCurrent,大家可以自行查看资料
2、源码下载
源码已上传,正在审核中。若审核通过,将添加正式的连接地址
3、总结
第一部分主要讲述推送基本设置,推送设置中还有一些样式的设置,大家可以到官网上进行学习。
 下一部分将讲述在局域网内实时实现消息的推送
4、参考资料
主要查看了官网微软官网和这篇博文。



















