Android WebView支持网站推送通知时无法触发权限申请问题求助
实现Android WebView网页通知权限功能方案
核心问题说明
默认WebView未开启网页权限请求处理逻辑,仅配置WebViewClient无法响应网页的通知权限申请,需补充WebChromeClient实现、系统权限申请、通知展示三部分逻辑。
具体修改步骤
1. 修改AndroidManifest.xml添加权限
在原有基础上添加通知相关权限,适配不同安卓版本:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.neurofinance"> <uses-permission android:name="android.permission.INTERNET"/> <!-- 新增通知权限 --> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <uses-permission android:name="android.permission.VIBRATE" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:configChanges="orientation|keyboardHidden|screenSize"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
2. 修改MainActivity.java补充逻辑
需要补充三个核心逻辑:动态申请系统通知权限、配置WebChromeClient响应网页权限申请、实现通知弹出功能。修改后的完整代码如下:
package com.example.neurofinance; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.app.NotificationCompat; import androidx.core.content.ContextCompat; import android.annotation.TargetApi; import android.app.NotificationChannel; import android.app.NotificationManager; import android.content.Context; import android.content.pm.PackageManager; import android.net.http.SslError; import android.os.Build; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.webkit.JavascriptInterface; import android.webkit.PermissionRequest; import android.webkit.SslErrorHandler; import android.webkit.WebChromeClient; import android.webkit.WebResourceRequest; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private static final int NOTIFICATION_PERMISSION_CODE = 1001; private static final String CHANNEL_ID = "web_notification_channel"; private WebView webView; public class WebAppInterface { Context mContext; NotificationManager notificationManager; WebAppInterface(Context c) { mContext = c; notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); createNotificationChannel(); } // 供网页调用弹出通知 @JavascriptInterface public void showNotification(String title, String content) { NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, CHANNEL_ID) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle(title) .setContentText(content) .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setAutoCancel(true); if (ActivityCompat.checkSelfPermission(mContext, android.Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED) { notificationManager.notify((int) System.currentTimeMillis(), builder.build()); } } @JavascriptInterface public void showToast(String toast) { Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show(); } // 创建安卓8及以上所需的通知渠道 private void createNotificationChannel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { CharSequence name = "网页通知"; String description = "展示网页推送的通知"; int importance = NotificationManager.IMPORTANCE_DEFAULT; NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance); channel.setDescription(description); notificationManager.createNotificationChannel(channel); } } } @Override public boolean onCreateOptionsMenu(Menu menu) { return true; } @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); // 先申请系统层面的通知权限 checkNotificationPermission(); webView = findViewById(R.id.webView); webView.addJavascriptInterface(new WebAppInterface(this), "Android"); webView.getSettings().setDomStorageEnabled(true); webView.getSettings().setJavaScriptEnabled(true); webView.getSettings().setUseWideViewPort(true); webView.getSettings().setLoadWithOverviewMode(true); webView.setInitialScale(1); webView.getSettings().setBuiltInZoomControls(true); webView.loadUrl("www.URL.com"); WebViewClient webViewClient = new WebViewClient() { @SuppressWarnings("deprecation") @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { handler.proceed(); } @TargetApi(Build.VERSION_CODES.N) @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { view.loadUrl(request.getUrl().toString()); return true; } }; webView.setWebViewClient(webViewClient); // 新增WebChromeClient处理网页权限请求 webView.setWebChromeClient(new WebChromeClient() { @Override public void onPermissionRequest(PermissionRequest request) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // 允许网页的通知权限申请 for (String res : request.getResources()) { if (res.equals(PermissionRequest.RESOURCE_NOTIFICATION)) { request.grant(new String[]{PermissionRequest.RESOURCE_NOTIFICATION}); return; } } super.onPermissionRequest(request); } } }); if (Build.VERSION.SDK_INT >= 21) webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); } // 动态申请系统通知权限 private void checkNotificationPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.POST_NOTIFICATIONS}, NOTIFICATION_PERMISSION_CODE); } } } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == NOTIFICATION_PERMISSION_CODE) { if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) { Toast.makeText(this, "未授予通知权限,无法接收网页推送", Toast.LENGTH_SHORT).show(); } } } }
适配说明
如果网页使用的是标准的JS通知API(Notification),完成上述配置后即可正常触发权限申请弹窗;若网页有自定义的通知逻辑,可直接调用暴露的Android.showNotification(title, content)方法弹出系统通知。
内容的提问来源于stack exchange,提问作者ElonMuskofBadIdeas
相关产品推荐
相关产品推荐

