Android完美的多功能webview

hello,又是我鑫鑫

这次给大家带来的是支持文件上传,图片下载,以及网页标题进步显示的web项目

还是挺好用的,我的工程中也运用了这个项目

以下是具体的效果

文件上传

图片下载

获取标题及加载进度

MainActivity

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ClipData;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.webkit.DownloadListener;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.WebView.xinxin.MainActivity;
import com.WebView.xinxin.DownPicUtil;
import com.WebView.xinxin.R;
import java.io.FileNotFoundException;

public class MainActivity extends Activity {


//声明相应ID
    private WebView webView;

    private Context context;

    private TextView tvTitle;

    private TextView tvProgress;


//这里定义所需要的变量
    private ValueCallback<Uri> uploadMessage;
    private ValueCallback<Uri[]> uploadMessageAboveL;
    private final static int FILE_CHOOSER_RESULT_CODE = 10000;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);//绑定页面ID
        getActionBar().hide();

        //去除导航栏
        Window navigation = getWindow();
        navigation.getDecorView().setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_LOW_PROFILE
            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
            | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);

        context= this;


        getActionBar().hide();//去除标题栏


        //获取标题显示进度显示的布局ID
        final LinearLayout top = findViewById(R.id.top);
        //获得其他控件
        tvTitle = (TextView) findViewById(R.id.tv_title);
        // tvStart = (TextView) findViewById(R.id.tv_start);
        tvProgress = (TextView) findViewById(R.id.tv_progress);
        // tvEnd = (TextView) findViewById(R.id.tv_end);

        webView = (WebView) findViewById(R.id.web);//绑定网页布局ID


        WebSettings settings = webView.getSettings();//web一些设置
        settings.setJavaScriptEnabled(true);

        settings.setJavaScriptCanOpenWindowsAutomatically(true);
//         当网页需要保存数时据,设置下面属性
        settings.setDomStorageEnabled(true);

        //设置页面自适应 窗口大小改变后页面自适应改变
        settings.setUseWideViewPort(true);//设置为使用webview推荐的窗口,主要是为了配合下一个属性
        settings.setLoadWithOverviewMode(true);//设置网页自适应屏幕大小,该属性必须和上一属性配合使用

//        webSettings.setGeolocationEnabled(true); //启用还H5的地理定位服务
//         设置是否允许webview使用缩放的功能
        settings.setSupportZoom(true);
        settings.setBuiltInZoomControls(true);
        settings.setDisplayZoomControls(false); //隐藏webview缩放按钮

        settings.setAllowFileAccess(true);//支持上传文件
//         提高网页渲染的优先级
        settings.setRenderPriority(WebSettings.RenderPriority.HIGH);


        //优先使用缓存加载
        settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);

        // 加载指定网页

        //打开外部应用网页
        //webView.loadUrl("https://qm.qq.com/cgi-bin/qm/qr?k=EWYf-_SRrmPF-f4xyYKQfNklEcHMsjVR&noverify=0");


        //普通网页
        webView.loadUrl("https://baidu.com");
        webView.setWebViewClient(new WebViewClient(){
                //跳转第三方应用,缺少判断是否有该APP,这里就不掩饰了,不然会闪退。
               /* @Override
                public boolean shouldOverrideUrlLoading(WebView view, String url) {
                    if (!(url.startsWith("http") || url.startsWith("https"))) {
                        Intent intent = new Intent();
                        intent.setAction(Intent.ACTION_VIEW);
                        intent.setData(Uri.parse(url));
                        startActivity(intent);
                        return true;
                    }
                    view.loadUrl(url);
                    return true;
                }*/


                //显示搜索功能,跳转浏览器搜索
                @Override
                public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
                {
                    if(request.hasGesture()){
                        Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(request.getUrl().toString()));
                        startActivity(browserIntent);
                    }else {
                        webView.loadUrl(request.getUrl().toString());
                    }
                    return true;
                }
            });


        webView.setWebChromeClient(new WebChromeClient() {

                //文件上传

                // For Android < 3.0
                public void openFileChooser(ValueCallback<Uri> valueCallback) {
                    uploadMessage = valueCallback;
                    openImageChooserActivity();
                }

                // For Android  >= 3.0
                public void openFileChooser(ValueCallback valueCallback, String acceptType) {
                    uploadMessage = valueCallback;
                    openImageChooserActivity();
                }

                //For Android  >= 4.1
                public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture) {
                    uploadMessage = valueCallback;
                    openImageChooserActivity();
                }

                // For Android >= 5.0
                @Override
                public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
                    uploadMessageAboveL = filePathCallback;
                    openImageChooserActivity();
                    return true;
                }




                //获取网站标题
                @Override
                public void onReceivedTitle(WebView view, String title) {
                    tvTitle.setText(title);
                }
                //进度显示
                @Override
                public void onProgressChanged(WebView view, int newProgress) {
                    if (newProgress < 100) {
                        tvProgress.setText(newProgress + "%");
                    } else {
                        tvProgress.setText("100%");
                        top.setVisibility(View.GONE);
                    }
                }





            });







        //设置下载监听
        webView.setDownloadListener(new DownloadListener() {



                @Override
                public void onDownloadStart(final String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {

                    new AlertDialog.Builder(MainActivity.this)
                        .setTitle("信息提示")//设置对话框标题
                        .setIcon(R.drawable.ic_launcher)
                        .setMessage("下载将跳转浏览器,是否选择?")
                        .setPositiveButton("是", new DialogInterface.OnClickListener() {//添加确定按钮

                            @Override
                            public void onClick(DialogInterface dialog, int which) {//确定按钮的响应事件

                                Uri uri = Uri.parse(url);
                                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                                startActivity(intent);
                            }
                        }).setNegativeButton("否", new DialogInterface.OnClickListener() {//添加返回按钮

                            @Override
                            public void onClick(DialogInterface dialog, int which) {//响应事件

                            }

                        }).show();//在按键响应事件中显示此对话框
                }
            });



        // 长按点击事件
        webView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View view) {
                    final WebView.HitTestResult hitTestResult = webView.getHitTestResult();
                    // 如果是图片类型或者是带有图片链接的类型
                    if(hitTestResult.getType()== WebView.HitTestResult.IMAGE_TYPE||
                       hitTestResult.getType()== WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE){
                        // 弹出保存图片的对话框
                        AlertDialog.Builder builder = new AlertDialog.Builder(context);
                        builder.setTitle("提示");
                        builder.setMessage("保存图片到本地");
                        builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    String url = hitTestResult.getExtra();
                                    // 下载图片到本地
            
           DownPicUtil.downPic(url, new DownPicUtil.DownFinishListener(){

                                            @Override
                                            public void getDownPath(String s) {
                                                Toast.makeText(context,"下载完成",Toast.LENGTH_LONG).show();
                                                Message msg = Message.obtain();
                                                msg.obj=s;
                                                handler.sendMessage(msg);
                                            }
                                        });

                                }
                            });
                        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                                // 自动dismiss
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                }
                            });
                        AlertDialog dialog = builder.create();
                        dialog.show();
                    }
                    return true;
                }
            });

    }




    /*文件上传*/

    //这里定义具体上传函数
    private void openImageChooserActivity() {
        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
        i.addCategory(Intent.CATEGORY_OPENABLE);
        i.setType("*/*");
        startActivityForResult(Intent.createChooser(i, "选择文件"), FILE_CHOOSER_RESULT_CODE);

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == FILE_CHOOSER_RESULT_CODE) {
            if (null == uploadMessage && null == uploadMessageAboveL) return;
            Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
            if (uploadMessageAboveL != null) {
                onActivityResultAboveL(requestCode, resultCode, data);
            } else if (uploadMessage != null) {
                uploadMessage.onReceiveValue(result);
                uploadMessage = null;
            }
        }
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void onActivityResultAboveL(int requestCode, int resultCode, Intent intent) {
        if (requestCode != FILE_CHOOSER_RESULT_CODE || uploadMessageAboveL == null)
            return;
        Uri[] results = null;
        if (resultCode == Activity.RESULT_OK) {
            if (intent != null) {
                String dataString = intent.getDataString();
                ClipData clipData = intent.getClipData();
                if (clipData != null) {
                    results = new Uri[clipData.getItemCount()];
                    for (int i = 0; i < clipData.getItemCount(); i++) {
                        ClipData.Item item = clipData.getItemAt(i);
                        results[i] = item.getUri();
                    }
                }
                if (dataString != null)
                    results = new Uri[]{Uri.parse(dataString)};
            }
        }
        uploadMessageAboveL.onReceiveValue(results);
        uploadMessageAboveL = null;


    }


    /*图片文件的下载*/

    Handler handler =new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            String picFile = (String) msg.obj;
            String[] split = picFile.split("/");
            String fileName = split[split.length-1];
            try {
                MediaStore.Images.Media.insertImage(getApplicationContext().getContentResolver(), picFile, fileName, null);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            // 最后通知图库更新
            getApplicationContext().sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + picFile)));
            //MyToast("图片保存图库成功", 1100);//这个是自定义toast,联动下面的自定义toast,具体代码请在评论区询问
            Toast.makeText(MainActivity.this, "图片保存成功", Toast.LENGTH_LONG).show();//这是普通的toast。
        }
    };



    /*自定义Toast*/

    //具体见我自定义Toast的文章,这里就不写进去了
/*
    public void MyToast(String str, int showTime) {
        View view= LayoutInflater.from(this).inflate(R.layout.view_toast_custom,null);
        TextView tv_msg = (TextView) view.findViewById(R.id.tvToast);
        tv_msg.setText(str);
        Toast toast = new Toast(this);
        toast.setGravity(Gravity.BOTTOM|Gravity.CENTER, 0, 20);
        toast.setDuration(Toast.LENGTH_LONG);
        toast.setView(view);
        toast.show();

    }*/


    /*返回键的监听*/
    // 监听返回键返回网页的上一层
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()){
            if(webView != null){
                webView.goBack();
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }




}


activity_main

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:background="#FFFFFFFF">

    <LinearLayout
        
        android:id="@+id/top"
        android:layout_width="match_parent"
        android:layout_height="95dp"
        android:orientation="vertical"
        android:layout_marginTop="15dp"
        android:layout_weight="1.0"
        android:layout_marginBottom="3dp"
        android:background="@drawable/fill_stroke">

        <TextView
            android:id="@+id/tv_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="获取标题"
            android:gravity="center"
            android:textStyle="bold"
            android:textColor="#FF000000"/>

        <LinearLayout
            android:layout_height="wrap_content"
            android:layout_width="match_parent">

            <TextView
                android:id="@+id/tv_progress"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="获取加载进度"
                android:layout_weight="1.0"
                android:textStyle="bold"
                android:textColor="#FF000000"
                android:gravity="center"/>

        </LinearLayout>

    </LinearLayout>

    <LinearLayout
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_weight="1.0">

        <WebView
            android:id="@+id/web"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

    </LinearLayout>

</LinearLayout>

图片下载工具

import android.os.*;
import android.util.*;
import java.io.*;
import java.net.*;

public  class DownPicUtil
 {

    public static void downPic(String url,DownFinishListener downFinishListener){
        // 获取存储卡的目录
        String filePath = Environment.getExternalStorageDirectory().getPath();
        File file = new File(filePath+File.separator+"Minecraft服务器管理/");
        if(!file.exists()){
            file.mkdir();
        }

        loadPic(file.getPath(),url,downFinishListener);

    }

    private static void loadPic(final String filePath, final String url, final DownFinishListener downFinishListener) {
        Log.e("下载图片的url",url);
        new AsyncTask<Void,Void,String>(){
            String fileName;
            InputStream is;
            OutputStream out;

            @Override
            protected String doInBackground(Void... voids) {

                // 下载文件的名称
                String[] split = url.split("/");
                String newString = split[split.length - 1];
                fileName =newString.substring(newString.length()-20,newString.length()-1) ;
                // 创建目标文件,不是文件夹
                File picFile = new File(filePath + File.separator + fileName);
                if(picFile.exists()){
                    return  picFile.getPath();
                }

                try {
                    URL picUrl = new URL(url);
                    //通过图片的链接打开输入流
                    is = picUrl.openStream();
                    if(is==null){
                        return null;
                    }
                    out = new FileOutputStream(picFile);
                    byte[] b=new byte[1024];
                    int end ;
                    while ((end=is.read(b))!=-1){
                        out.write(b,0,end);
                    }

                    Log.e("OK??","----------");
                    if(is!=null){
                        is.close();
                    }

                    if(out!=null){
                        out.close();
                    }

                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }



                return picFile.getPath();
            }

            @Override
            protected void onPostExecute(String s) {
                super.onPostExecute(s);
                if(s!=null){
                    downFinishListener.getDownPath(s);
                }
            }
        }.execute();
    }
    //下载完成回调的接口
    public interface DownFinishListener{

        void getDownPath(String s);
    }
}

别忘了在AndroidManifest.xml中添加相应的权限

   <!--完全的网络访问权限-->
    <uses-permission android:name="android.permission.INTERNET"/>

    <!--修改或删除您的SD卡中的内容-->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <!--访问SD卡文件系统-->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

文章到这也就结束了,如果有啥问题,请在评论区中提出

代码开源之后会发在评论区的

那我们下篇文章见

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值