Android 实战 - 个人App乐逗项目(查看网页链接封装,播放视频封装)

来源:互联网 发布:unity3d 路径动画 编辑:程序博客网 时间:2024/05/20 16:10

1.查看网页链接封装
和 Android实战-个人App乐逗项目(第一阶段:微信精选文章完成与总结) 中的webview一样,采用腾讯x5浏览服务sdk调用的.

效果 预览 :

这里写图片描述

所需 工具 :

  1. 腾讯x5浏览服务sdk 或者点击下载 jar

可以到官方下载,或者点击下载 对应jar包即可.

  1. 封装 x5webview , 前提是导入上面的jar

//SecurityJsBridgeBundle.java

package labelnet.cn.ledou.ui;import android.content.Context;import java.util.Map;/** * X5WebView , 应用类 , 提供JSBridge */public abstract class SecurityJsBridgeBundle {    ///////////////////////////////////////////////////////////////////////////////    //add js     private final static String DEFAULT_JS_BRIDGE ="JsBridge";    public static final String METHOD = "method";    public static final String BLOCK = "block";    public static final String CALLBACK = "callback";    public static final String PROMPT_START_OFFSET = "local_js_bridge::";    private Context mContext;    private String mJsBlockName ;    private String mMethodName;    public abstract void onCallMethod();    public SecurityJsBridgeBundle(String JsBlockName, String methodName) throws Exception{        if(methodName == null){            throw new Exception("methodName can not be null!");        }        if(JsBlockName!=null){            this.mJsBlockName=JsBlockName;        }else{            this.mJsBlockName = DEFAULT_JS_BRIDGE;        }    }    public String getMethodName(){        return this.mMethodName;    }    public String getJsBlockName(){        return this.mJsBlockName;    }    private void injectJsMsgPipecode(Map<String,Object> data){        if(data==null){            return ;        }        String injectCode = "javascript:(function JsAddJavascriptInterface_(){ "+             "if (typeof(window.jsInterface)!='undefined') {"+                      "console.log('window.jsInterface_js_interface_name is exist!!');}   "+             "else {"+                 data.get(BLOCK)+data.get(METHOD)+                "window.jsBridge = {"+                               "onButtonClick:function(arg0) {"+                            "return prompt('MyApp:'+JSON.stringify({obj:'jsInterface',func:'onButtonClick',args:[arg0]}));"+                       "},"+                      "onImageClick:function(arg0,arg1,arg2) {"+                            "prompt('MyApp:'+JSON.stringify({obj:'jsInterface',func:'onImageClick',args:[arg0,arg1,arg2]}));"+                      "},"+                   "};"+               "}"+           "}"+           ")()";    }    private static String getStandardMethodSignature(){        return null;    }}

//x5webview.java

package labelnet.cn.ledou.ui;import android.annotation.SuppressLint;import android.app.Activity;import android.app.AlertDialog;import android.app.AlertDialog.Builder;import android.content.Context;import android.content.DialogInterface;import android.content.Intent;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.net.Uri;import android.os.Message;import android.util.AttributeSet;import android.util.Log;import android.view.Gravity;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.widget.FrameLayout;import com.tencent.smtt.export.external.interfaces.IX5WebChromeClient.CustomViewCallback;import com.tencent.smtt.export.external.interfaces.JsPromptResult;import com.tencent.smtt.export.external.interfaces.JsResult;import com.tencent.smtt.export.external.interfaces.WebResourceResponse;import com.tencent.smtt.sdk.ValueCallback;import com.tencent.smtt.sdk.WebChromeClient;import com.tencent.smtt.sdk.WebSettings;import com.tencent.smtt.sdk.WebSettings.LayoutAlgorithm;import com.tencent.smtt.sdk.WebStorage;import com.tencent.smtt.sdk.WebView;import com.tencent.smtt.sdk.WebViewClient;import java.util.HashMap;import java.util.Map;import labelnet.cn.ledou.R;public class X5WebView extends WebView {    ///////////////////////////////////////////////////    //add private object    //////////////////////////////////////////////////    //file chooser result code    public static final int FILE_CHOOSER = 0;    private String resourceUrl = "";    private WebView smallWebView;    private static boolean isSmallWebViewDisplayed = false;    private Map<String, Object> mJsBridges;    @SuppressLint("SetJavaScriptEnabled")    public X5WebView(Context arg0, AttributeSet arg1) {        super(arg0, arg1);        WebStorage webStorage = WebStorage.getInstance();        // TODO Auto-generated constructor stub        WebSettings webSetting = this.getSettings();        webSetting.setJavaScriptEnabled(true);        webSetting.setJavaScriptCanOpenWindowsAutomatically(true);        webSetting.setAllowFileAccess(true);        webSetting.setLayoutAlgorithm(LayoutAlgorithm.NARROW_COLUMNS);        webSetting.setSupportZoom(true);        webSetting.setBuiltInZoomControls(true);        webSetting.setUseWideViewPort(true);        webSetting.setSupportMultipleWindows(true);        webSetting.setLoadWithOverviewMode(true);        webSetting.setAppCacheEnabled(true);        webSetting.setDatabaseEnabled(true);        webSetting.setDomStorageEnabled(true);        webSetting.setGeolocationEnabled(true);        webSetting.setAppCacheMaxSize(Long.MAX_VALUE);        // webSetting.setPageCacheCapacity(IX5WebSettings.DEFAULT_CACHE_CAPACITY);        webSetting.setPluginState(WebSettings.PluginState.ON_DEMAND);        webSetting.setRenderPriority(WebSettings.RenderPriority.HIGH);        webSetting.setCacheMode(WebSettings.LOAD_NO_CACHE);        this.getView().setClickable(true);        this.getView().setOnTouchListener(new OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                // TODO Auto-generated method stub                return false;            }        });        //WebClient settings        this.setWebViewClient(new WebViewClient() {            /**             * 防止加载网页时调起系统浏览器             */            public boolean shouldOverrideUrlLoading(WebView view, String url) {                view.loadUrl(url);                return true;//              return false;            }            public void onReceivedHttpAuthRequest(WebView webview, com.tencent.smtt.export.external.interfaces.HttpAuthHandler httpAuthHandlerhost, String host, String realm) {                boolean flag = httpAuthHandlerhost.useHttpAuthUsernamePassword();                Log.i("yuanhaizhou", "useHttpAuthUsernamePassword is" + flag);                Log.i("yuanhaizhou", "HttpAuth host is" + host);                Log.i("yuanhaizhou", "HttpAuth realm is" + realm);            }            @Override            public void onDetectedBlankScreen(String arg0, int arg1) {                // TODO Auto-generated method stub                super.onDetectedBlankScreen(arg0, arg1);            }            @Override            public WebResourceResponse shouldInterceptRequest(WebView arg0,                                                              String arg1) {                // TODO Auto-generated method stub                return super.shouldInterceptRequest(arg0, arg1);            }        });        //webchromeclient settings        this.setWebChromeClient(new WebChromeClient() {            View myVideoView;            View myNormalView;            CustomViewCallback callback;            ///////////////////////////////////////////////////////////            //            /**             * 全屏播放配置             */            @Override            public void onShowCustomView(View view, CustomViewCallback customViewCallback) {                // TODO Auto-generated method stub                FrameLayout normalView = (FrameLayout) ((Activity) getContext()).findViewById(R.id.web_filechooser);                ViewGroup viewGroup = (ViewGroup) normalView.getParent();                viewGroup.removeView(normalView);                viewGroup.addView(view);                myVideoView = view;                myNormalView = normalView;                callback = customViewCallback;            }            @Override            public void onHideCustomView() {                // TODO Auto-generated method stub                if (callback != null) {                    callback.onCustomViewHidden();                    callback = null;                }                if (myVideoView != null) {                    ViewGroup viewGroup = (ViewGroup) myVideoView.getParent();                    viewGroup.removeView(myVideoView);                    viewGroup.addView(myNormalView);                }            }            @Override            public void onProgressChanged(WebView arg0, int arg1) {                // TODO Auto-generated method stub                super.onProgressChanged(arg0, arg1);            }            @Override            public void openFileChooser(ValueCallback<Uri> uploadFile,                                        String acceptType, String captureType) {                Log.i("ChromeClient", "openFileChooser enter");                Intent i = new Intent(Intent.ACTION_GET_CONTENT);                i.addCategory(Intent.CATEGORY_OPENABLE);                i.setType("*/*");                ((Activity) (X5WebView.this.getContext())).startActivityForResult(                        Intent.createChooser(                                i, "choose files"), X5WebView.FILE_CHOOSER);                super.openFileChooser(uploadFile, acceptType, captureType);            }            @Override            public void onShowCustomView(View arg0, int arg1,                                         CustomViewCallback arg2) {                // TODO Auto-generated method stub                CustomViewCallback callback = new CustomViewCallback() {                    @Override                    public void onCustomViewHidden() {                        // TODO Auto-generated method stub                        Log.i("yuanhaizhou", "video view hidden");                    }                };                super.onShowCustomView(arg0, arg1, arg2);            }            /**             * webview 的窗口转移             */            @Override            public boolean onCreateWindow(WebView arg0, boolean arg1,                                          boolean arg2, Message msg) {                // TODO Auto-generated method stub                Log.i("yuanhaihzou", "onCreateWindow happend!!");                if (X5WebView.isSmallWebViewDisplayed == true) {                    WebView.WebViewTransport webViewTransport = (WebView.WebViewTransport) msg.obj;                    WebView webView = new WebView(X5WebView.this.getContext()) {                        protected void onDraw(Canvas canvas) {                            super.onDraw(canvas);                            Paint paint = new Paint();                            paint.setColor(Color.GREEN);                            paint.setTextSize(15);                            canvas.drawText("新建窗口", 10, 10, paint);                        }                        ;                    };                    webView.setWebViewClient(new WebViewClient() {                        public boolean shouldOverrideUrlLoading(WebView arg0, String arg1) {                            arg0.loadUrl(arg1);                            return true;                        }                        ;                    });                    FrameLayout.LayoutParams lp = new LayoutParams(400, 600);                    lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL;                    X5WebView.this.addView(webView, lp);                    webViewTransport.setWebView(webView);                    msg.sendToTarget();                }                return true;            }            @Override            public boolean onJsAlert(WebView arg0, String arg1, String arg2,                                     JsResult arg3) {                // TODO Auto-generated method stub                AlertDialog.Builder builder = new Builder(getContext());                builder.setTitle("X5内核");                builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {                    @Override                    public void onClick(DialogInterface dialog, int which) {                        // TODO Auto-generated method stub                        dialog.dismiss();                    }                });                builder.show();                arg3.confirm();                return true;            }            /**             *对应js 的通知弹框 ,可以用来实现js 和 android之间的通信             */            @Override            public boolean onJsPrompt(WebView arg0, String arg1, String arg2,                                      String arg3, JsPromptResult arg4) {                // TODO Auto-generated method stub                //在这里可以判定js传过来的数据,用于调起android native 方法                if (X5WebView.this.isMsgPrompt(arg1)) {                    if (X5WebView.this.onJsPrompt(arg2, arg3)) {                        return true;                    } else {                        return false;                    }                }                return super.onJsPrompt(arg0, arg1, arg2, arg3, arg4);            }            @Override            public void onReceivedTitle(WebView arg0, final String arg1) {                // TODO Auto-generated method stub                super.onReceivedTitle(arg0, arg1);                Log.i("yuanhaizhou", "webpage title is " + arg1);            }        });    }    /////////////////////////////////////////////////////////////////////    //绘制webview的标记    @Override    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {        boolean ret = super.drawChild(canvas, child, drawingTime);        canvas.save();        Paint paint = new Paint();        paint.setColor(0x7fff0000);        paint.setTextSize(24.f);        paint.setAntiAlias(true);        /**         * 取消绘制的标识         * 包括内核         * 手机信息         * 手机名称         *///        if (getX5WebViewExtension() != null) {//            //Log.d(TAG, "drawChild--X5 Core");//            canvas.drawText(this.getContext().getPackageName() + "-pid:" + android.os.Process.myPid(), 10, 50, paint);//            canvas.drawText("X5  Core:" + QbSdk.getTbsVersion(this.getContext()), 10, 100, paint);//        } else {//            //Log.d(TAG, "drawChild--Sys Core");//            canvas.drawText(this.getContext().getPackageName() + "-pid:" + android.os.Process.myPid(), 10, 50, paint);//            canvas.drawText("Sys Core", 10, 100, paint);//        }//        canvas.drawText(Build.MANUFACTURER, 10, 150, paint);//        canvas.drawText(Build.MODEL, 10, 200, paint);        canvas.restore();        return ret;    }    public X5WebView(Context arg0) {        super(arg0);        setBackgroundColor(85621);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        // TODO Auto-generated method stub        return super.onTouchEvent(event);    }    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        // TODO Auto-generated method stub        return super.onInterceptTouchEvent(ev);    }    public static void setSmallWebViewEnabled(boolean enabled) {        isSmallWebViewDisplayed = enabled;    }    @Override    protected void onScrollChanged(int l, int t, int oldl, int oldt) {        // TODO Auto-generated method stub//      Log.i("yuanhaizhou","webview scroll y is" +this.getView().getScrollY());//      Log.i("yuanhaizhou","real webview scroll y is" + this.getScrollY());//      Log.i("yuanhaizhou","webview webscroll y is" + this.getWebScrollY());        Log.i("yuanhaizhou", "webview webscroll y is" + this.getWebScrollY());        super.onScrollChanged(l, t, oldl, oldt);    }    public void addJavascriptBridge(SecurityJsBridgeBundle jsBridgeBundle) {        if (this.mJsBridges == null) {            this.mJsBridges = new HashMap<String, Object>(5);        }        if (jsBridgeBundle != null) {            String tag = SecurityJsBridgeBundle.BLOCK + jsBridgeBundle.getJsBlockName()                    + "-"                    + SecurityJsBridgeBundle.METHOD + jsBridgeBundle.getMethodName();            this.mJsBridges.put(tag, jsBridgeBundle);        }    }    /**     * 当webchromeClient收到 web的prompt请求后进行拦截判断,用于调起本地android方法     *     * @param methodName 方法名称     * @param blockName  区块名称     * @return true :调用成功 ; false :调用失败     */    private boolean onJsPrompt(String methodName, String blockName) {        String tag = SecurityJsBridgeBundle.BLOCK + blockName                + "-"                + SecurityJsBridgeBundle.METHOD + methodName;        if (this.mJsBridges != null && this.mJsBridges.containsKey(tag)) {            ((SecurityJsBridgeBundle) this.mJsBridges.get(tag)).onCallMethod();            return true;        } else {            return false;        }    }    /**     * 判定当前的prompt消息是否为用于调用native方法的消息     *     * @param msg 消息名称     * @return true 属于prompt消息方法的调用     */    private boolean isMsgPrompt(String msg) {        if (msg != null && msg.startsWith(SecurityJsBridgeBundle.PROMPT_START_OFFSET)) {            return true;        } else {            return false;        }    }}

布局 实现 :

引入刚才的自定义x5Webview

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@color/zhushen_color">    <labelnet.cn.ledou.ui.X5WebView        android:id="@+id/web_tb_filechooser"        android:layout_width="fill_parent"        android:layout_height="match_parent"        android:layout_marginTop="20dp" /></RelativeLayout>

业务 实现 :

package labelnet.cn.ledou;import android.app.ProgressDialog;import android.graphics.Bitmap;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.widget.Toast;import com.tencent.smtt.sdk.WebView;import com.tencent.smtt.sdk.WebViewClient;import labelnet.cn.ledou.net.NetManager;import labelnet.cn.ledou.net.NetManagerImp;import labelnet.cn.ledou.ui.X5WebView;/** * Created by yuan on 15-11-9. * <p/> * 公共的 Webview ,用来打开网页使用 */public class TbOtherHtmlActivity extends AppCompatActivity {    private NetManager netManager;    private ProgressDialog progressDialog;    private String copy_url = "www.labelnet.cn";    private Bitmap bitmap;    private X5WebView x5WebView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_tbotherhtml);        x5WebView = (X5WebView) findViewById(R.id.web_tb_filechooser);        //一些初始化        initProgressBar();        netManager = new NetManagerImp();        x5WebView.setSmallWebViewEnabled(true);        x5WebView.setWebViewClient(new WebViewClient() {            @Override            public void onPageStarted(WebView webView, String s, Bitmap bitmap) {                progressDialog.show();            }            @Override            public void onPageFinished(WebView webView, String s) {                progressDialog.dismiss();            }        });        initData();    }    private void initData() {        String url = getIntent().getStringExtra("url");        this.copy_url = url;        if (url == null) {            progressDialog.dismiss();            showToast("网络链接失败,请重试!");        } else {            x5WebView.loadUrl(url);        }    }    /**     * 初始化 Progressdialog     */    private void initProgressBar() {        progressDialog = new ProgressDialog(this);        progressDialog.setMessage("小鱼说: 请稍后");        progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);    }    /**     * toast     *     * @param msg     */    private void showToast(String msg) {        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();    }    /**     * 退出按钮     */    @Override    public void onBackPressed() {        progressDialog.dismiss();        finish();    }}

调用 实现 :

这里仅仅是传入了地址链接和title , 其他的可以自定义.

Intent intent = new Intent(MainLeActivity.this, TbMusicActivity.class);                intent.putExtra("url", url);                intent.putExtra("title",title );                startActivity(intent);


2.播放视频封装

说明: 点击播放 - > 全屏加载播放 -> 可以暂停播放控制

这个还没有进行优化,仅仅是可以播放视频,没有自己的,可控制的内容.

效果 预览 :

在模拟器上播放不了,这里就在真机上截屏了

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

所需 工具 :

采用VideoView实现 , 不需要工具类

VideoView 的一些参数 :

方法说明:
getBufferPercentage:得到缓冲的百分比
getCurrentPosition:得到当前播放位置
getDuration:得到视频文件的时间
resolveAdjustedSize:调整视频显示大小
setMediaController:设置播放控制器模式(播放进度条)
setOnCompletionListener:当视频文件播放完时触发事件
setVideoPath:设置视频源路径
setVideoURI:设置视频源地址

布局 实现 :

采用VideoView实现

<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent">    <VideoView        android:id="@+id/tb_videoview"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_gravity="center" />    <ProgressBar        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/tb_video_progress"        android:layout_gravity="center" /></FrameLayout>

业务 实现 :

package labelnet.cn.ledou;import android.app.Activity;import android.content.pm.ActivityInfo;import android.media.MediaPlayer;import android.net.Uri;import android.os.Bundle;import android.view.View;import android.view.Window;import android.view.WindowManager;import android.widget.MediaController;import android.widget.ProgressBar;import android.widget.Toast;import com.gitonway.lee.niftymodaldialogeffects.lib.Effectstype;import com.gitonway.lee.niftymodaldialogeffects.lib.NiftyDialogBuilder;import labelnet.cn.ledou.ui.TbVideoView;/** * Created by yuan on 15-11-6. * 播放视频的Activity */public class TbVideoActivity extends Activity implements View.OnClickListener {    private TbVideoView tb_videoview;    private String url, title;    private ProgressBar tb_video_progress;    private NiftyDialogBuilder dialogBuilder;    @Override    protected void onResume() {        super.onResume();        //设置初始的时候,就横屏和全屏        if (getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);        }    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        //隐藏标题        requestWindowFeature(Window.FEATURE_NO_TITLE);        //设置全屏        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,                WindowManager.LayoutParams.FLAG_FULLSCREEN);        setContentView(R.layout.activity_tbvideo);        initView();        initData();    }    /**     * 准备数据     */    private void initData() {        url = getIntent().getStringExtra("url");        title = getIntent().getStringExtra("title");        videoPlay();    }    /**     * 播放视频     */    private void videoPlay() {        tb_videoview.setVideoURI(Uri.parse(url));        tb_videoview.setMediaController(new MediaController(this));        tb_videoview.requestFocus();        //自动播放        tb_videoview.start();    }    /**     * 初始化     */    private void initView() {        tb_videoview = (TbVideoView) findViewById(R.id.tb_videoview);        tb_videoview.setOnClickListener(this);        tb_video_progress = (ProgressBar) findViewById(R.id.tb_video_progress);        tb_videoview.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {            @Override            public void onPrepared(MediaPlayer mp) {                //onPrepared 加载好,后进度条消失                tb_video_progress.setVisibility(View.GONE);            }        });        /**         * 加载出错的情况下         */        tb_videoview.setOnErrorListener(new MediaPlayer.OnErrorListener() {            @Override            public boolean onError(MediaPlayer mp, int what, int extra) {                showToast("咦,网络打小报告了?");                tb_video_progress.setVisibility(View.GONE);                return false;            }        });        /**         * 播放完毕的监听         */        tb_videoview.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {            @Override            public void onCompletion(MediaPlayer mp) {                showToast("播放完了");                getDialogShow("嘿嘿,播放完了");            }        });    }    private void showToast(String msg) {        Toast.makeText(this, msg, Toast.LENGTH_LONG).show();    }    protected void getDialogShow(String msg) {        dialogBuilder                .withTitle("温馨提示")                .withDividerColor("#808080")                .withMessage(msg)                .withDialogColor("#808080")                .withDuration(700)                .withEffect(Effectstype.Fadein)                .withButton1Text("返回")                .setButton1Click(new View.OnClickListener() {                    @Override                    public void onClick(View v) {                        onBackPressed();                    }                })                .show();    }    /**     * 最大化视频     */    @Override    public void onBackPressed() {        super.onBackPressed();        if (tb_videoview.isPlaying()) {            tb_videoview.clearFocus();        }        finish();    }    @Override    public void onClick(View v) {        //showToast("我是title");    }}

调用 实现 :

        Intent intent = new Intent(MainLeActivity.this, TbMusicActivity.class);                intent.putExtra("url", url);                intent.putExtra("title",title );                startActivity(intent);

3.总结
这几个都是些简单的实现,后续功能 还需要添加和完善.
下篇实现音乐播放器.

0 0
原创粉丝点击