版权声明:本文为HaiyuKing原创文章,转载请注明出处!
前言
按照官网上的说明:可独立下载x5内核,也可共享使用微信或手Q的x5内核。
本Demo在引用腾讯X5内核的基础上进行了封装。参考《MyWebViewDemo【封装Webview常用配置和选择文件、打开相机、录音、打开本地相册的用法】》
使用TbsReaderView预览文件功能,请参考《MyX5TbsPlusDemo【体验腾讯浏览服务Android SDK (TbsPlus 版)】》
效果图
代码分析
X5WebView : 对腾讯X5内核的webview进行了封装;
BrowserActivity:用于展现打开普通网页;
FilechooserActivity : 用于展示在web端<input type=text>的标签被选择之后,文件选择器的制作和生成;
FullScreenActivity : 用于演示X5webview实现视频的全屏播放功能 其中注意 X5的默认全屏方式 与 android 系统的全屏方式
注意:
X5WebView 继承 WebView(指的是X5内核的webview,所以import com.tencent.smtt.sdk.WebView;)
X5WebViewClient 继承 WebViewClient(import com.tencent.smtt.sdk.WebViewClient;)
X5WebChromeClient 继承 WebChromeClient(import com.tencent.smtt.sdk.WebChromeClient;)
使用步骤
一、项目组织结构图
注意事项:
1、 导入类文件后需要change包名以及重新import R文件路径
2、 Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖
二、导入步骤
1、下载sdk
下载地址:https://x5.tencent.com/tbs/sdk.html
下载的文件解压后如下:【接入文档很有用】
2、将jar文件导入项目中
参考《【Android Studio安装部署系列】十七、Android studio引用第三方库、jar、so、arr文件》
3、实现支持64位手机加载X5
将SDK接入示例-Android Studio文件中的demo项目的jniLibs目录复制到项目的main目录下【如果项目的main目录中已经存在jniLibs文件夹,则只需要把so文件复制到相应armeabi目录下】
在build.gradle文件中添加以下代码
apply plugin: 'com.android.application' android {
compileSdkVersion 27
defaultConfig {
applicationId "com.why.project.myx5tbsdemo"
minSdkVersion 16
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" //腾讯浏览服务实现支持64位手机加载X5
// Specifies the ABI configurations of your native
// libraries Gradle should build and package with your APK.
ndk {
abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
} dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
如果配置后编译报错,那么需要在gradle.properties文件中加上Android.useDeprecatedNdk=true;【一般不需要,本demo中没有添加】
4、在AndroidManifest.xml中声明权限
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.why.project.myx5tbsdemo"> <!-- ======================腾讯浏览服务========================== -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- 硬件加速对X5视频播放非常重要,建议开启(如果有网页视频播放的话建议开启) -->
<uses-permission android:name="android.permission.GET_TASKS" /> <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">
<intent-filter>
<action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application> </manifest>
5、在自定义Application里面初始化X5内核
package com.why.project.myx5tbsdemo; import android.app.Application;
import android.content.Context;
import android.util.Log; import com.tencent.smtt.sdk.QbSdk; /**
* Created by HaiyuKing
* Used 在Application里面初始化X5内核
*/ public class MyApplication extends Application { /**系统上下文*/
private static Context mAppContext; @Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
mAppContext = getApplicationContext(); //配置腾讯浏览服务
initQbSdk(); } /**获取系统上下文*/
public static Context getAppContext()
{
return mAppContext;
} private void initQbSdk() {
//搜集本地tbs内核信息并上报服务器,服务器返回结果决定使用哪个内核。
QbSdk.PreInitCallback cb = new QbSdk.PreInitCallback() {
@Override
public void onViewInitFinished(boolean arg0) {
// TODO Auto-generated method stub
//x5內核初始化完成的回调,为true表示x5内核加载成功,否则表示x5内核加载失败,会自动切换到系统内核。
Log.d("app", " onViewInitFinished is " + arg0);
}
@Override
public void onCoreInitFinished() {
// TODO Auto-generated method stub
}
};
//x5内核初始化接口
QbSdk.initX5Environment(mAppContext, cb);
}
}
6、在AndroidManifest.xml文件中声明这个自定义的application
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.why.project.myx5tbsdemo"> <!-- ======================腾讯浏览服务========================== -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- 硬件加速对X5视频播放非常重要,建议开启(如果有网页视频播放的话建议开启) -->
<uses-permission android:name="android.permission.GET_TASKS" /> <application
android:name=".MyApplication"
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">
<intent-filter>
<action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application> </manifest>
到这里,基本上将腾讯浏览服务X5内核引入到项目中了。不过本Demo对X5WebView进行了封装,所以还需要进行下面的操作。
二、下面导入自己封装的X5WebView
1、将customwebview包复制到项目中
2、将x5webview_progress_dialog_img_drawable.xml复制到项目中
<?xml version="1.0" encoding="utf-8"?>
<!-- WebView使用的进度加载对话框进度圆圈 -->
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/x5webview_progress_dialog_img"
android:pivotX="50%"
android:pivotY="50%"
android:fromDegrees="0.0"
android:toDegrees="360.0"
android:repeatMode="restart"
/>
x5webview_progress_dialog_img_drawable.xml
3、将x5webview_progress_dialog_img.png图片复制到项目中
4、将x5webview_dialog_webviewprogress.xml复制到项目中
<?xml version="1.0" encoding="utf-8"?>
<!-- WebView使用的进度加载对话框布局文件 -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dialog_view"
android:layout_width="match_parent"
android:layout_height="match_parent"> <!-- 自定义圆形进度条 -->
<!-- android:indeterminateDrawable自定义动画图标 -->
<ProgressBar
android:id="@+id/loadProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:indeterminateDrawable="@drawable/x5webview_progress_dialog_img_drawable"
/> </RelativeLayout>
x5webview_dialog_webviewprogress.xml
5、在styles.xml文件中添加以下代码
<resources> <!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style> <!-- ==================X5Webview========网页加载时的进度对话框========================== -->
<style name="x5webview_loading_style" parent="android:style/Theme.Dialog">
<!-- Dialog的windowFrame框为无 -->
<item name="android:windowFrame">@null</item>
<!-- 是否显示title -->
<item name="android:windowNoTitle">true</item>
<!-- 是否浮现在activity之上 -->
<item name="android:windowIsFloating">true</item>
<!-- 设置dialog的背景:#00000000透明色 -->
<item name="android:windowBackground">@android:color/transparent</item>
<!-- 半透明 -->
<item name="android:windowIsTranslucent">true</item>
<!-- 背景变灰:整个屏幕变灰,配合setCanceledOnTouchOutside(false) -->
<item name="android:backgroundDimEnabled">false</item>
<!-- 对话框是否有遮盖 -->
<item name="android:windowContentOverlay">@null</item>
</style> </resources>
6、在AndroidManifest.xml中添加以下代码【因为有重复的权限,所以注释掉了】
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.why.project.myx5tbsdemo"> <!-- ======================腾讯浏览服务========================== -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- 硬件加速对X5视频播放非常重要,建议开启(如果有网页视频播放的话建议开启) -->
<uses-permission android:name="android.permission.GET_TASKS" /> <!-- ======================(X5WebView)========================== -->
<!-- 允许程序打开网络套接字 -->
<!--<uses-permission android:name="android.permission.INTERNET"/>-->
<!-- ======================拍照用到的========================== -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- ======================录音用到的========================== -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- 向SD卡写入数据权限 -->
<!--<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />-->
<!--<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />--> <application
android:name=".MyApplication"
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">
<intent-filter>
<action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application> </manifest>
7、将assets文件夹复制到项目中
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type">
<meta http-equiv="keywords" content="测试">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>
webview
</title>
</head> <body>
<p>
<input type="file" value="打开文件" />
</p> <p>
点击下面的按钮,获取的文件路径:
</p>
<p>
<input type="text" id="filePath" value="文件路径" style="width:100%"/>
</p>
<p>
<input type="button" id="openRecord" value="打开录音" onclick="window.androidMethod.openRecord();"/>
</p>
<p>
<input type="button" id="takePicture" value="打开相机" onclick="window.androidMethod.takePicture();"/>
</p>
<p>
<input type="button" id="choosePic" value="打开本地相册" onclick="window.androidMethod.choosePic();"/>
</p>
<p>
<a href='tel:10010'>拨打电话:10010</a>
</p>
</body>
<script>
//打开录音、打开相机、打开本地相册,选择文件后返回的路径
function setInputText(urlPath){
document.getElementById("filePath").value = urlPath;
}
</script> </html>
demo.html
三、因为demo中使用到获取手机本地文件的权限和调用相机功能,所以需要申请运行时权限和适配7.0FIleProvider功能。
0-1、申请运行时权限,参考《Android6.0运行时权限(基于RxPermission开源库)》
0-2、适配Android7.0FileProvider功能,参考《AppUtils【获取手机的信息和应用版本号、安装apk】》
三、使用方法
1、打开普通网页,参考BrowserActivity
package com.why.project.myx5tbsdemo; import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import android.widget.FrameLayout; import com.why.project.myx5tbsdemo.customwebview.x5webview.X5WebView; /**
* Created by HaiyuKing
* Used 用于展现打开普通网页;
*/ public class BrowserActivity extends AppCompatActivity {
private static final String TAG = BrowserActivity.class.getSimpleName(); //内容显示区域
private FrameLayout center_layout;
private X5WebView mX5WebView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_x5webview); initViews();
initDatas();
initEvents();
} @Override
public void onDestroy() {
if (mX5WebView != null) {
mX5WebView.removeAllViews();
mX5WebView.destroy();
} super.onDestroy();
} private void initViews() {
//内容显示区域
center_layout = (FrameLayout) findViewById(R.id.center_layout); mX5WebView = new X5WebView(this, null);
center_layout.addView(mX5WebView, new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT));
} private void initDatas() {
mX5WebView.setCanBackPreviousPage(true, BrowserActivity.this);//设置可返回上一页 mX5WebView.loadUrl("http://www.baidu.com");
} private void initEvents() { } /**
* 截取返回软键事件【在activity中写,不能在自定义的X5Webview中】
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && mX5WebView.canGoBack()) {
mX5WebView.goBack();
return true;
} else {
finish();
return true;
}
}
return super.onKeyDown(keyCode, event);
}
}
布局文件【这三个演示Activity都是使用这个布局文件】
<?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"> <!-- 内容区域 -->
<FrameLayout
android:id="@+id/center_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"> </FrameLayout> </RelativeLayout>
2、展示在web端<input type=text>的标签被选择之后,文件选择器的制作和生成,参考FilechooserActivity
package com.why.project.myx5tbsdemo; import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.FrameLayout;
import android.widget.Toast; import com.tencent.smtt.sdk.ValueCallback;
import com.why.project.myx5tbsdemo.customwebview.utils.GetPathFromUri4kitkat;
import com.why.project.myx5tbsdemo.customwebview.utils.WebviewGlobals;
import com.why.project.myx5tbsdemo.customwebview.x5webview.X5WebView;
import com.why.project.myx5tbsdemo.customwebview.x5webview.X5WebViewJSInterface; import java.io.File; /**
* Created by HaiyuKing
* Used 用于展示在web端<input type=text>的标签被选择之后,文件选择器的制作和生成
*/ public class FilechooserActivity extends AppCompatActivity {
private static final String TAG = FilechooserActivity.class.getSimpleName(); //内容显示区域
private FrameLayout center_layout;
private X5WebView mX5WebView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_x5webview); initViews();
initDatas();
initEvents();
} @Override
public void onDestroy() {
if (mX5WebView != null) {
mX5WebView.removeAllViews();
mX5WebView.destroy();
} super.onDestroy();
} private void initViews() {
//内容显示区域
center_layout = (FrameLayout) findViewById(R.id.center_layout); mX5WebView = new X5WebView(this, null);
center_layout.addView(mX5WebView, new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT));
} private void initDatas() {
mX5WebView.setCanBackPreviousPage(true, FilechooserActivity.this);//设置可返回上一页 mX5WebView.loadLocalUrl("demo.html");
} private void initEvents() { } /**
* 截取返回软键事件【在activity中写,不能在自定义的X5Webview中】
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && mX5WebView.canGoBack()) {
mX5WebView.goBack();
return true;
} else {
finish();
return true;
}
}
return super.onKeyDown(keyCode, event);
} @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
Log.w(TAG, "{onActivityResult}resultCode="+resultCode);
Log.w(TAG, "{onActivityResult}requestCode="+requestCode); if (resultCode == Activity.RESULT_OK) {
//webview界面调用打开本地文件管理器选择文件的回调
if (requestCode == WebviewGlobals.CHOOSE_FILE_REQUEST_CODE ) {
Uri result = data == null ? null : data.getData();
Log.w(TAG,"{onActivityResult}文件路径地址:" + result.toString()); //如果mUploadMessage或者mUploadCallbackAboveL不为空,代表是触发input[type]类型的标签
if (null != mX5WebView.getX5WebChromeClient().getmUploadMessage() || null != mX5WebView.getX5WebChromeClient().getmUploadCallbackAboveL()) {
if (mX5WebView.getX5WebChromeClient().getmUploadCallbackAboveL() != null) {
onActivityResultAboveL(requestCode, data);//5.0++
} else if (mX5WebView.getX5WebChromeClient().getmUploadMessage() != null) {
mX5WebView.getX5WebChromeClient().getmUploadMessage().onReceiveValue(result);//将文件路径返回去,填充到input中
mX5WebView.getX5WebChromeClient().setmUploadMessage(null);
}
}else{
//此处代码是处理通过js方法触发的情况
Log.w(TAG,"{onActivityResult}文件路径地址(js):" + result.toString());
String filePath = GetPathFromUri4kitkat.getPath(FilechooserActivity.this,Uri.parse(result.toString())); //修改网页输入框文本【无法通过evaluateJavascript方式执行js方法,需要特殊处理】
setUrlPathInput(mX5WebView,"打开本地相册:" + filePath);
}
}
//因为拍照指定了路径,所以data值为null
if(requestCode == WebviewGlobals.CAMERA_REQUEST_CODE){
File pictureFile = new File(X5WebViewJSInterface.mCurrentPhotoPath); Uri uri = Uri.fromFile(pictureFile);
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(uri);
FilechooserActivity.this.sendBroadcast(intent); // 这里我们发送广播让MediaScanner 扫描我们制定的文件
// 这样在系统的相册中我们就可以找到我们拍摄的照片了【但是这样一来,就会执行MediaScanner服务中onLoadFinished方法,所以需要注意】 //拍照
// String fileName = FileUtils.getFileName(X5WebViewJSInterface.mCurrentPhotoPath);
Log.e(TAG,"WebViewJSInterface.mCurrentPhotoPath="+X5WebViewJSInterface.mCurrentPhotoPath); //修改网页输入框文本【无法通过evaluateJavascript方式执行js方法,需要特殊处理】
setUrlPathInput(mX5WebView,"打开相机:" + X5WebViewJSInterface.mCurrentPhotoPath);
} //录音
if(requestCode == WebviewGlobals.RECORD_REQUEST_CODE){
Uri result = data == null ? null : data.getData();
Log.w(TAG,"录音文件路径地址:" + result.toString());//录音文件路径地址:content://media/external/audio/media/111 String filePath = GetPathFromUri4kitkat.getPath(FilechooserActivity.this,Uri.parse(result.toString()));
Log.w(TAG,"录音文件路径地址:" + filePath); //修改网页输入框文本【无法通过evaluateJavascript方式执行js方法,需要特殊处理】
setUrlPathInput(mX5WebView,"打开录音:" + filePath);
}
} else if(resultCode == RESULT_CANCELED){//resultCode == RESULT_CANCELED 解决不选择文件,直接返回后无法再次点击的问题
if (mX5WebView.getX5WebChromeClient().getmUploadMessage() != null) {
mX5WebView.getX5WebChromeClient().getmUploadMessage().onReceiveValue(null);
mX5WebView.getX5WebChromeClient().setmUploadMessage(null);
}
if (mX5WebView.getX5WebChromeClient().getmUploadCallbackAboveL() != null) {
mX5WebView.getX5WebChromeClient().getmUploadCallbackAboveL().onReceiveValue(null);
mX5WebView.getX5WebChromeClient().setmUploadCallbackAboveL(null);
}
}
} //5.0以上版本,由于api不一样,要单独处理
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void onActivityResultAboveL(int requestCode, Intent data) { if (mX5WebView.getX5WebChromeClient().getmUploadCallbackAboveL() == null) {
return;
}
Uri result = null;
if (requestCode == WebviewGlobals.CHOOSE_FILE_REQUEST_CODE) {//打开本地文件管理器选择图片
result = data.getData();
} else if (requestCode == WebviewGlobals.CAMERA_REQUEST_CODE) {//调用相机拍照
File pictureFile = new File(X5WebViewJSInterface.mCurrentPhotoPath); Uri uri = Uri.fromFile(pictureFile);
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(uri);
FilechooserActivity.this.sendBroadcast(intent); // 这里我们发送广播让MediaScanner 扫描我们制定的文件
// 这样在系统的相册中我们就可以找到我们拍摄的照片了【但是这样一来,就会执行MediaScanner服务中onLoadFinished方法,所以需要注意】 result = Uri.fromFile(pictureFile);
}
Log.w(TAG,"{onActivityResultAboveL}文件路径地址:"+result.toString());
mX5WebView.getX5WebChromeClient().getmUploadCallbackAboveL().onReceiveValue(new Uri[]{result});//将文件路径返回去,填充到input中
mX5WebView.getX5WebChromeClient().setmUploadCallbackAboveL(null);
return;
} //设置网页上的文件路径输入框文本
private void setUrlPathInput(X5WebView webView, String urlPath) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
webView.evaluateJavascript("setInputText('"+ urlPath +"')", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
Log.i(TAG, "onReceiveValue value=" + value);
}});
}else{
Toast.makeText(FilechooserActivity.this,"当前版本号小于19,无法支持evaluateJavascript,需要使用第三方库JSBridge", Toast.LENGTH_SHORT).show();
}
}
}
3、演示X5webview实现视频的全屏播放功能 ,参考FullScreenActivity
package com.why.project.myx5tbsdemo; import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import android.widget.FrameLayout;
import android.widget.Toast; import com.why.project.myx5tbsdemo.customwebview.x5webview.X5WebView; /**
* Created by HaiyuKing
* Used 用于演示X5webview实现视频的全屏播放功能 其中注意 X5的默认全屏方式 与 android 系统的全屏方式
*/ public class FullScreenActivity extends AppCompatActivity {
private static final String TAG = FullScreenActivity.class.getSimpleName(); //内容显示区域
private FrameLayout center_layout;
private X5WebView mX5WebView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_x5webview); initViews();
initDatas();
initEvents();
} @Override
public void onDestroy() {
if (mX5WebView != null) {
mX5WebView.removeAllViews();
mX5WebView.destroy();
} super.onDestroy();
} private void initViews() {
//内容显示区域
center_layout = (FrameLayout) findViewById(R.id.center_layout); mX5WebView = new X5WebView(this, null);
center_layout.addView(mX5WebView, new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT));
} private void initDatas() {
mX5WebView.setCanBackPreviousPage(true, FullScreenActivity.this);//设置可返回上一页 enablePageVideoFunc();//设置视频播放样式 mX5WebView.loadUrl("http://live.hkstv.hk.lxdns.com/live/hks/playlist.m3u8");
} private void initEvents() { } /**
* 截取返回软键事件【在activity中写,不能在自定义的X5Webview中】
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && mX5WebView.canGoBack()) {
mX5WebView.goBack();
return true;
} else {
finish();
return true;
}
}
return super.onKeyDown(keyCode, event);
} //恢复webkit初始状态
private void disableX5FullscreenFunc() {
if (mX5WebView.getX5WebViewExtension() != null) {
Toast.makeText(this, "恢复webkit初始状态", Toast.LENGTH_LONG).show();
Bundle data = new Bundle();
data.putBoolean("standardFullScreen", true);// true表示标准全屏,会调起onShowCustomView(),false表示X5全屏;不设置默认false,
data.putBoolean("supportLiteWnd", false);// false:关闭小窗;true:开启小窗;不设置默认true,
data.putInt("DefaultVideoScreen", 2);// 1:以页面内开始播放,2:以全屏开始播放;不设置默认:1 mX5WebView.getX5WebViewExtension().invokeMiscMethod("setVideoParams", data);
//设置WebView是否通过手势触发播放媒体,默认是true,需要手势触发。
mX5WebView.getSettings().setMediaPlaybackRequiresUserGesture(false);
//接口禁止(直接或反射)调用,避免视频画面无法显示
mX5WebView.setDrawingCacheEnabled(true);
}
} //开启X5全屏播放模式
private void enableX5FullscreenFunc() { if (mX5WebView.getX5WebViewExtension() != null) {
Toast.makeText(this, "开启X5全屏播放模式", Toast.LENGTH_LONG).show();
Bundle data = new Bundle(); data.putBoolean("standardFullScreen", false);// true表示标准全屏,false表示X5全屏;不设置默认false, data.putBoolean("supportLiteWnd", false);// false:关闭小窗;true:开启小窗;不设置默认true, data.putInt("DefaultVideoScreen", 2);// 1:以页面内开始播放,2:以全屏开始播放;不设置默认:1 mX5WebView.getX5WebViewExtension().invokeMiscMethod("setVideoParams", data);
//设置WebView是否通过手势触发播放媒体,默认是true,需要手势触发。
mX5WebView.getSettings().setMediaPlaybackRequiresUserGesture(false);
//接口禁止(直接或反射)调用,避免视频画面无法显示
mX5WebView.setDrawingCacheEnabled(true);
}
} //开启小窗模式
private void enableLiteWndFunc() {
if (mX5WebView.getX5WebViewExtension() != null) {
Toast.makeText(this, "开启小窗模式", Toast.LENGTH_LONG).show();
Bundle data = new Bundle(); data.putBoolean("standardFullScreen", false);// true表示标准全屏,会调起onShowCustomView(),false表示X5全屏;不设置默认false, data.putBoolean("supportLiteWnd", true);// false:关闭小窗;true:开启小窗;不设置默认true, data.putInt("DefaultVideoScreen", 2);// 1:以页面内开始播放,2:以全屏开始播放;不设置默认:1 mX5WebView.getX5WebViewExtension().invokeMiscMethod("setVideoParams", data);
//设置WebView是否通过手势触发播放媒体,默认是true,需要手势触发。
mX5WebView.getSettings().setMediaPlaybackRequiresUserGesture(false);
//接口禁止(直接或反射)调用,避免视频画面无法显示
mX5WebView.setDrawingCacheEnabled(true);
}
} //页面内全屏播放模式
private void enablePageVideoFunc() {
if (mX5WebView.getX5WebViewExtension() != null) {
Toast.makeText(this, "页面内全屏播放模式", Toast.LENGTH_LONG).show();
Bundle data = new Bundle(); data.putBoolean("standardFullScreen", false);// true表示标准全屏,会调起onShowCustomView(),false表示X5全屏;不设置默认false, data.putBoolean("supportLiteWnd", false);// false:关闭小窗;true:开启小窗;不设置默认true, data.putInt("DefaultVideoScreen", 1);// 1:以页面内开始播放,2:以全屏开始播放;不设置默认:1 mX5WebView.getX5WebViewExtension().invokeMiscMethod("setVideoParams", data);
//设置WebView是否通过手势触发播放媒体,默认是true,需要手势触发。
mX5WebView.getSettings().setMediaPlaybackRequiresUserGesture(false);
//接口禁止(直接或反射)调用,避免视频画面无法显示
mX5WebView.setDrawingCacheEnabled(true);
}
} }
混淆配置
无
参考资料
Android在项目中接入腾讯TBS浏览器WebView的教程与注意的地方
项目demo下载地址
https://github.com/haiyuKing/MyX5TbsDemo
MyX5TbsDemo【体验腾讯浏览服务Android SDK (完整版)】的更多相关文章
-
MyX5TbsPlusDemo【体验腾讯浏览服务Android SDK (TbsPlus 版)】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 按照官网上的说明:只需接入aar文件和调用一个接口即可完成TBS接入,我们会通过全屏Activity展示TBS WebView,适用 ...
-
Android应用内实现视频播放--腾讯浏览服务(TBS)
TBS视频播放 TBS视频播放器可以支持市面上几乎所有的视频格式,包括mp4, flv, avi, 3gp, webm, ts, ogv, m3u8, asf, wmv, rm, rmvb, mov, ...
-
Android使用腾讯浏览服务X5内核
[前期准备] 腾讯X5 jar包下载地址 [点击打开] 本次完整DEMO源码 [打开Github] [集成步骤] 第一步:下载jar包添加到项目 第二步:添加权限 <uses-permissio ...
-
集成TBS(腾讯浏览服务)x5内核的webView
由于公司产品需要展示html5页面,一开始我使用的是android自带webview,一些简单的页面没什么问题,但是碰到比较复杂的页面就让人无语了. 1.Android各大厂商都有自己定制的ROM,导 ...
-
TencentTbs腾讯浏览服务 x5内核使用
Tencent TBS (下简称TBS) 腾讯浏览服务 What is it? 百度百科解释: 腾讯浏览服务(Tencent Browsing Service,以下简称TBS),由腾讯X5浏览服务升级 ...
-
腾讯浏览服务X5内核集成
腾讯浏览服务X5内核集成https://www.jianshu.com/p/8a7224ff371a TBS 腾讯浏览器服务接入文档https://x5.tencent.com/tbs/guide/s ...
-
腾讯微博java(android)sdk新增微博api详细介绍
本文主要介绍腾讯微博android sdk中新增微博有关的8个接口,以及使用的示例代码 注意:以下所有的api示例代码都需要先新建QqTSdkService类对象qqTSdkService并初始化,见 ...
-
Android照片墙完整版,的完美结合LruCache和DiskLruCache
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/34093441 在上一篇文章其中,我们学习了DiskLruCache的概念和基本使用 ...
-
Android照片墙完整版,完美结合LruCache和DiskLruCache
转载地址:http://blog.csdn.net/guolin_blog/article/details/34093441#comments 在上一篇文章当中,我们学习了DiskLruCache的概 ...
随机推荐
-
对AutoIt中控件和窗口的理解
经过尝试,对AutoIt中Control和Window有了新的认识,分享一下 1.Control 现在我想对一个WinForm架构的应用程序进行自动化操作,得到控件Advanced Mode属性为[N ...
-
JavaScript入门
本篇内容是学习慕课网相关课程后,总结出可能未来会忘记的内容 (一)JavaScript入门操作 1.js代码插入位置,以及执行顺序 <head> <script type=" ...
-
JAVASE笔记回顾
第一部分,JAVA基础和面向对象 part01 入门与开发环境搭建 1: 计算机基础知识(了解)(1)计算机(2)计算机硬件(3)计算机软件系统软件:windows,linux,mac应用软件:QQ, ...
-
UITextView打开文字中的URL
1. 背景介绍 UITextView里显示的文字带有url,点击url可以打开对应的网页,可以分两种打开方式:(1)在App内打开url:(2)用safari打开url. 2. 实现代码: (1)声明 ...
-
[Oracle]Oracle数据库任何用户密码都能以sysdba角色登入
* 本文相关环境:Windows 10,64位操作系统:Oracle 11gR2:toad for Oracle12.1 最近在学习Oracle数据库,使用Toad for Oracle来查看数据库的 ...
-
Python学习之路&mdash;&mdash;day05
今日内容:1.可变与不可变类型:可变类型:值可以改变,但是id不变,证明就是在改变原值,是可变类型不可变类型:值改变,但是id也跟着改变,证明是残生了新的值,是不可变类型 2.数字类型2.1整型:记录 ...
-
LinkedQueue的底层实现
package zy813ture; public class MyLinkedQueue1 { private Node head; private Node last = head = new N ...
-
gVim安装vim-template插件后提示Undefined variable vim_template_subtype/Press ENTER or type command to continue
Win7 64位 gVim:version 8.1.1234 vim-template:github链接 安装方式: 直接下载master的zip压缩包,解压后放入本地gVim安装目录的plugin, ...
-
linux下如何使用Mysql
项目需要:Linux下链接数据库,并进行相关的查询操作 mySql的一些常用命令 启动:net start mySql; 进入:mysql -u root -p/mysql -h localhost ...
-
oracle 、server和my sql 语法区别
1.总结Oracle .sqlserver和mysql中查询10-20条记录的写法 一: oracle数据库写法: 1:select * from (select rownum rn ,* from ...