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

如何在Android Studio中为WebView开启通知权限

问题描述

我正在使用Android Studio开发一款WebView应用,该应用加载网站https://grillizuae.com。此网站会推送带声音的通知提醒,我需要获取该通知的声音;另外,通常在Chrome等浏览器打开网站时会询问通知权限,但在WebView中该如何开启此权限?

以下是我的实现代码:

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    this.getWindow().getDecorView().setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_FULLSCREEN);

    WebView webView = (WebView) findViewById(R.id.webview);

    webView.getSettings().setUseWideViewPort(true);//setting wide view
    webView.getSettings().setLoadWithOverviewMode(true);//setting default zoomed out view
    webView.setInitialScale(1);

    webView.setWebViewClient(new WebViewClient());
    webView.loadUrl("https://grillizuae.com");

    //webView.getSettings().setUserAgentString("Desktop");

    WebSettings webSettings = webView.getSettings();
    webSettings.setJavaScriptEnabled(true);
}

private class MyWebViewClient extends WebViewClient {
    @Override
    public boolean shouldOverrideUrlLoading(WebView webView, String url) {
        return false;
    }
}
解决方案

一、开启WebView的通知权限

WebView不会自动处理通知权限请求,需要通过WebChromeClient拦截并处理:

  1. 添加Manifest权限(Android 13+)
    在AndroidManifest.xml中添加通知权限:
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
  1. 动态申请权限(Android 13+)
    因为POST_NOTIFICATIONS是危险权限,需要在代码中动态申请:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
        registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
            // 可根据权限申请结果做后续处理
        }).launch(Manifest.permission.POST_NOTIFICATIONS);
    }
}
  1. 通过WebChromeClient处理权限请求
    为WebView设置自定义WebChromeClient,重写onPermissionRequest方法允许通知权限:
webView.setWebChromeClient(new WebChromeClient() {
    @Override
    public void onPermissionRequest(PermissionRequest request) {
        for (String permission : request.getResources()) {
            if (PermissionRequest.RESOURCE_NOTIFICATION.equals(permission)) {
                request.grant(request.getResources());
                return;
            }
        }
        request.deny();
    }
});

二、获取通知声音

网站的通知声音通常通过Web Notification API设置,可通过两种方式获取:

方式1:注入JS拦截通知创建

通过注入JavaScript代码拦截网站的通知构造函数,提取声音URL:

  1. 创建JS接口类
public class NotificationInterface {
    @JavascriptInterface
    public void onNotificationCreated(String soundUrl) {
        // 这里获取到通知声音的URL,可进行下载或播放操作
        Log.d("NotificationSound", "通知声音URL: " + soundUrl);
    }
}
  1. 添加JS接口并注入拦截代码
    在onPageFinished中注入JS代码,替换原生Notification构造函数:
// 添加JS接口
webView.addJavascriptInterface(new NotificationInterface(), "NotificationHandler");

// 设置WebViewClient注入拦截代码
webView.setWebViewClient(new MyWebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
        String js = "window.Notification = function(title, options) {" +
                "if (options && options.sound) {" +
                "NotificationHandler.onNotificationCreated(options.sound);" +
                "}" +
                "return new window.originalNotification(title, options);" +
                "};" +
                "window.originalNotification = window.Notification;";
        view.evaluateJavascript(js, null);
    }
});

方式2:监听系统通知(针对推送类通知)

如果网站使用FCM等推送服务,通知会以系统通知形式到达,可通过NotificationListenerService监听:

  1. 创建NotificationListenerService
public class MyNotificationListener extends NotificationListenerService {
    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {
        super.onNotificationPosted(sbn);
        // 过滤目标应用的通知
        if ("你的应用包名".equals(sbn.getPackageName())) {
            Notification notification = sbn.getNotification();
            Uri soundUri = notification.sound;
            if (soundUri != null) {
                Log.d("NotificationSound", "系统通知声音URI: " + soundUri.toString());
            }
        }
    }
}
  1. 注册服务到Manifest
<service android:name=".MyNotificationListener"
         android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
    <intent-filter>
        <action android:name="android.service.notification.NotificationListenerService" />
    </intent-filter>
</service>
  1. 引导用户开启监听权限
    需要用户在系统设置中开启权限,可通过代码跳转:
Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
startActivity(intent);
完整修改后的MainActivity代码
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        this.getWindow().getDecorView().setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_FULLSCREEN);

        WebView webView = findViewById(R.id.webview);
        WebSettings webSettings = webView.getSettings();

        webSettings.setUseWideViewPort(true);
        webSettings.setLoadWithOverviewMode(true);
        webView.setInitialScale(1);
        webSettings.setJavaScriptEnabled(true);
        webSettings.setDomStorageEnabled(true); // 部分网站通知需要开启DOM存储

        // 动态申请Android 13+通知权限
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
                registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
                    // 权限申请结果处理
                }).launch(Manifest.permission.POST_NOTIFICATIONS);
            }
        }

        // 设置WebChromeClient处理通知权限请求
        webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onPermissionRequest(PermissionRequest request) {
                for (String permission : request.getResources()) {
                    if (PermissionRequest.RESOURCE_NOTIFICATION.equals(permission)) {
                        request.grant(request.getResources());
                        return;
                    }
                }
                request.deny();
            }
        });

        // 添加JS接口拦截通知声音
        webView.addJavascriptInterface(new NotificationInterface(), "NotificationHandler");

        // 设置WebViewClient并注入拦截JS
        webView.setWebViewClient(new MyWebViewClient());
        webView.loadUrl("https://grillizuae.com");
    }

    private class MyWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView webView, String url) {
            return false;
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            String js = "window.Notification = function(title, options) {" +
                    "if (options && options.sound) {" +
                    "NotificationHandler.onNotificationCreated(options.sound);" +
                    "}" +
                    "return new window.originalNotification(title, options);" +
                    "};" +
                    "window.originalNotification = window.Notification;";
            view.evaluateJavascript(js, null);
        }
    }

    public class NotificationInterface {
        @JavascriptInterface
        public void onNotificationCreated(String soundUrl) {
            Log.d("NotificationSound", "获取到通知声音URL: " + soundUrl);
            // 可添加下载或播放声音的逻辑
        }
    }
}

内容的提问来源于stack exchange,提问作者G PAC

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 18:27:53