Xamarin中使用BroadcastReceiver实现通知点击打开自定义弹窗
实现方案(无需额外申请悬浮窗权限,全版本兼容)
核心思路是将身份验证页封装为无界面的Dialog样式Activity,用户点击通知时直接唤起该Activity弹出输入框,全程不会显示应用主界面/启动页,视觉上就是直接弹出了验证窗口。
步骤1:配置Dialog样式的Activity主题
在Resources/values/styles.xml中新增透明弹窗主题:
<style name="AuthDialogTheme" parent="Theme.MaterialComponents.Dialog"> <item name="android:windowNoTitle">true</item> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowIsFloating">true</item> <item name="android:windowCloseOnTouchOutside">false</item> </style>
在AndroidManifest.xml中给AuthActivity绑定主题,同时配置属性避免出现在最近任务列表:
<activity android:name=".AuthActivity" android:theme="@style/AuthDialogTheme" android:excludeFromRecents="true" android:noHistory="true" android:exported="false" />
步骤2:修改AuthActivity代码,直接弹出验证窗口
AuthActivity不需要加载普通页面布局,OnCreate时直接弹出输入框即可:
public class AuthActivity : AppCompatActivity { protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); ShowAuthDialog(); } private void ShowAuthDialog() { // 加载自定义的账号密码输入布局 var dialogView = LayoutInflater.From(this).Inflate(Resource.Layout.auth_input_layout, null); var usernameInput = dialogView.FindViewById<EditText>(Resource.Id.et_username); var passwordInput = dialogView.FindViewById<EditText>(Resource.Id.et_password); new AlertDialog.Builder(this) .SetTitle("服务器身份验证") .SetView(dialogView) .SetCancelable(false) .SetPositiveButton("确认", (s, e) => { var username = usernameInput.Text?.Trim(); var password = passwordInput.Text?.Trim(); if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password)) { Toast.MakeText(this, "请输入完整的账号和密码", ToastLength.Short).Show(); return; } // 1. 将凭据存入SharedPreferences供打印服务读取 var prefs = GetSharedPreferences("PrintServiceConfig", FileCreationMode.Private); prefs.Edit() .PutString("auth_username", username) .PutString("auth_password", password) .Apply(); // 2. 发送本地广播通知服务重试之前失败的请求 var retryIntent = new Intent("AUTH_CREDENTIALS_UPDATED"); LocalBroadcastManager.GetInstance(this).SendBroadcast(retryIntent); // 关闭当前Activity,无残留 Finish(); }) .SetNegativeButton("取消", (s, e) => { Finish(); }) .Show(); } }
自定义输入布局auth_input_layout.axml可自行实现,只需要两个EditText分别输入账号密码即可。
步骤3:适配高版本Android的PendingIntent规则
修改CreateNotification方法中创建PendingIntent的代码,适配Android 12+的权限要求:
PendingIntentFlags flags = PendingIntentFlags.OneShot; // Android 12及以上要求明确指定Immutable/Mutable属性 if (Build.VERSION.SdkInt >= BuildVersionCodes.S) { flags |= PendingIntentFlags.Immutable; } var pendingIntent = PendingIntent.GetActivity(_context, 0, intent, flags);
可选补充:打印服务接收重试通知
在你的打印服务中注册本地广播接收器,监听AUTH_CREDENTIALS_UPDATED广播,收到后读取存储的账号密码,重新发起之前返回401的请求即可。
内容的提问来源于stack exchange,提问作者user9752057
相关产品推荐
相关产品推荐

