You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 17:15:03