直接看代码即可,代码里面注释写的很清楚,这个类拉下来就能用;
写法和命名比较粗暴,但也简单易懂;
public class MainActivity extends AppCompatActivity { private final String TAG = MainActivity.this.getClass().getSimpleName(); private WebView wv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); QbSdk.initX5Environment(this,null); //最好在application中 getWindow().setFormat(PixelFormat.TRANSLUCENT); wv = findViewById(R.id.wv); final ProgressBar pb = findViewById(R.id.pb); wv.loadUrl("https://github.com/CuiChenbo/CcMall"); wv.setWebViewClient(new WebViewClient(){ @Override public boolean shouldOverrideUrlLoading(WebView webView, String url) { //重写此方法 可让webview不跳转到系统的浏览器 webView.loadUrl(url); return super.shouldOverrideUrlLoading(webView, url); } }); wv.setWebChromeClient(new WebChromeClient(){ //WebView进度的回调监听 @Override public void onProgressChanged(WebView webView, int i) { super.onProgressChanged(webView, i); if (i>=100){ pb.setProgress(100); pb.setVisibility(View.GONE); }else { pb.setProgress(i); } } //JS Alert的监听 可用来做和js(H5)的交互 @Override public boolean onJsAlert(WebView webView, String s, String s1, JsResult jsResult) { return super.onJsAlert(webView, s, s1, jsResult); } //JsConfirm的监听 @Override public boolean onJsConfirm(WebView webView, String s, String s1, JsResult jsResult) { return super.onJsConfirm(webView, s, s1, jsResult); } //JsPrompt 的监听 可用来做和js(H5)的交互 @Override public boolean onJsPrompt(WebView webView, String s, String s1, String s2, JsPromptResult jsPromptResult) { return super.onJsPrompt(webView, s, s1, s2, jsPromptResult); } }); //WebView长按的监听 wv.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View view) { WebView.HitTestResult hitTestResult = wv.getHitTestResult(); int type = hitTestResult.getType(); //获取触摸点的类型 final String extra = hitTestResult.getExtra(); //获取触摸点的数据 Log.i(TAG, "type:"+type+"____extra:"+extra); if (type == WebView.HitTestResult.IMAGE_TYPE||type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE){ //说明触摸点的这个类型是图片类 去提示下载图片 AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this); dialog.setTitle("提示") .setMessage("是否保存图片") .setPositiveButton("保存", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { SeveImage(extra); } }) .setNegativeButton("取消",null) .show(); return true; }else { return false; } } }); } //保存图片 private void SeveImage(String extra) { DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); Uri uri = Uri.parse(extra); DownloadManager.Request request = new DownloadManager.Request(uri); //设置允许使用的网络类型,这里是移动网络和wifi都可以 request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI); // 允许媒体扫描,根据下载的文件类型被加入相册、音乐等媒体库 request.allowScanningByMediaScanner(); //禁止发出通知,既后台下载,如果要使用这一句必须声明一个权限:android.permission.DOWNLOAD_WITHOUT_NOTIFICATION request.setShowRunningNotification(false); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); //不显示下载界面 request.setVisibleInDownloadsUi(true); request.setDestinationInExternalFilesDir(MainActivity.this, Environment.DIRECTORY_PICTURES, System.currentTimeMillis() + ".jpg"); //*设置下载后文件存放的位置,如果sdcard不可用,那么设置这个将报错,因此最好不设置如果sdcard可用,下载后的文件 在/mnt/sdcard/Android/data/packageName/files目录下面,如果sdcard不可用,设置了下面这个将报错,不设置,下载后的文件在/cache这个 目录下面*//* //request.setDestinationInExternalFilesDir(this, null, "tar.apk"); long id = downloadManager.enqueue(request); IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE); DownloadMangerReceiver mDownloadMangerReceiver = new DownloadMangerReceiver(); registerReceiver(mDownloadMangerReceiver, intentFilter); } //保存图片的监听 class DownloadMangerReceiver extends BroadcastReceiver { private DownloadManager manager; @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); manager =(DownloadManager)context.getSystemService(Context.DOWNLOAD_SERVICE); if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) { Toast.makeText(context, "文件下载完成", Toast.LENGTH_SHORT).show(); /* * 获取下载完成对应的下载ID, 这里下载完成指的不是下载成功, 下载失败也算是下载完成, * 所以接收到下载完成广播后, 还需要根据 id 手动查询对应下载请求的成功与失败. */ // 根据获取到的ID,使用上面第3步的方法查询是否下载成功 } } } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { //改写物理返回键的逻辑 if(keyCode== KeyEvent.KEYCODE_BACK) { if(wv.canGoBack()) { wv.goBack();//返回上一页面 return true; } else { System.exit(0);//退出程序 } } return super.onKeyDown(keyCode, event); } }
layout布局文件也看一下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_height="match_parent" android:layout_width="match_parent" > <ProgressBar android:id="@+id/pb" android:layout_width="match_parent" android:layout_height="2dp" android:max="100" android:background="@color/colorAccent" style="@style/Base.Widget.AppCompat.ProgressBar.Horizontal" /> <com.tencent.smtt.sdk.WebView xmlns:tools="http://schemas.android.com/tools" android:id="@+id/wv" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.ccb.pactera.x5webview.MainActivity"> </com.tencent.smtt.sdk.WebView> </LinearLayout>com.tencent.smtt.sdk.WebView是我用的X5WebView,有兴趣的可以去看一下: X5WebView