如果仅仅是PDF的预览,github上有作者提供了一个PDF的预览框架。不支持在线预览,需要先将文件从服务器下载保存。==》 android-pdfview,需要的可以去看看。
如果想使用WPS office进行office文档的预览,可以参考如下两个博客。
1、Android 实现 调用 WPS Office手机版接口
2、Android调用WPS
dependencies {
classpath 'com.android.tools.build:gradle:3.1.2'
//解决导入第三方包报错,包没找到的问题
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
}
/**
* 判断是否安装了某个应用
* @param context
* @param appPackageName
* @return true 安装 false 未安装
*/
public static boolean isApplicationAvilible(Context context, String appPackageName) {
// 获取packagemanager
PackageManager packageManager = context.getPackageManager();
// 获取所有已安装程序的包信息
List pinfo = packageManager.getInstalledPackages(0);
if(!pinfo.isEmpty()){
for (int i = 0; i < pinfo.size(); i++) {
String name = pinfo.get(i).packageName;
if(appPackageName.equals(name)){
return true;
}
}
}
/*if (pinfo != null) {
for (int i = 0; i < pinfo.size(); i++) {
String pn = pinfo.get(i).packageName;
if (appPackageName.equals(pn)) {
return true;
}
}
}*/
return false;
}
下载TBS的SDK
然后在app module中src==》main包下创建jniLibs文件夹,然后将TBS的demo中jniLibs中的文件复制到这个文件夹中。准备工作就做好了。
public class APPAplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//x5内核初始化接口
QbSdk.initX5Environment(getApplicationContext(), cb);
}
/**
* 搜集本地tbs内核信息并上报服务器,服务器返回结果决定使用哪个内核。
*/
QbSdk.PreInitCallback cb = new QbSdk.PreInitCallback() {
@Override
public void onViewInitFinished(boolean arg0) {
//x5內核初始化完成的回调,为true表示x5内核加载成功,否则表示x5内核加载失败,会自动切换到系统内核。
Log.e("APPAplication", " onViewInitFinished is " + arg0);
}
@Override
public void onCoreInitFinished() {
Log.e("APPAplication", " onCoreInitFinished");
}
};
}
我们在使用腾讯TBS的WebView的情况下,在整个应用中不能出现系统的WebView,好像有冲突。
public class Main3Activity extends AppCompatActivity {
@BindView(R.id.wb_content)
X5WebView wbContent;
@BindView(R.id.progress)
ProgressBar progress;
@BindView(R.id.bt_back)
Button btBack;
@BindView(R.id.tv_title)
TextView tvTitle;
private Unbinder unbinder;
private String mHomeUrl = "https://www.baidu.com/?tn=39042058_30_oem_dg";
//private String mHomeUrl = "https://www.panda.tv/";
//private String mHomeUrl = "https://www.vip.com/";
private URL mIntentUrl;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFormat(PixelFormat.TRANSLUCENT);
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
}
} catch (Exception e) {
e.printStackTrace();
}
Intent intent = getIntent();
if (intent != null) {
try {
mIntentUrl = new URL(intent.getData().toString());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
setContentView(R.layout.activity_main3);
unbinder = ButterKnife.bind(this);
initWeb();
btBack.setOnClickListener(onClickListener);
}
private void initWeb() {
WebSettings webSetting = wbContent.getSettings();
webSetting.setAllowFileAccess(true);
webSetting.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
webSetting.setSupportZoom(true);
webSetting.setBuiltInZoomControls(true);
webSetting.setUseWideViewPort(true);
webSetting.setSupportMultipleWindows(false);
// webSetting.setLoadWithOverviewMode(true);
webSetting.setAppCacheEnabled(true);
// webSetting.setDatabaseEnabled(true);
webSetting.setDomStorageEnabled(true);
webSetting.setJavaScriptEnabled(true);
webSetting.setGeolocationEnabled(true);
webSetting.setAppCacheMaxSize(Long.MAX_VALUE);
webSetting.setAppCachePath(this.getDir("appcache", 0).getPath());
webSetting.setDatabasePath(this.getDir("databases", 0).getPath());
webSetting.setGeolocationDatabasePath(this.getDir("geolocation", 0)
.getPath());
// webSetting.setPageCacheCapacity(IX5WebSettings.DEFAULT_CACHE_CAPACITY);
webSetting.setPluginState(WebSettings.PluginState.ON_DEMAND);
// webSetting.setRenderPriority(WebSettings.RenderPriority.HIGH);
// webSetting.setPreFectch(true);
wbContent.setWebViewClient(webViewClient);
wbContent.setWebChromeClient(webChromeClient);
if (mIntentUrl == null) {
wbContent.loadUrl(mHomeUrl);
} else {
wbContent.loadUrl(mIntentUrl.toString());
}
CookieSyncManager.createInstance(this);
CookieSyncManager.getInstance().sync();
}
WebViewClient webViewClient = new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView webView, String url) {
//此处不能像使用系统的WebView的写法一样,强行显示在WebView中,不调用系统浏览器
//要参考demo中BrowserActivity中这里的写法,直接返回false,否则会出现网页中某得页面加载不出来的情况,别问我为什么知道,^_^,踩过坑。
/*if (!TextUtils.isEmpty(url)) {
webView.loadUrl(url);
}
return super.shouldOverrideUrlLoading(webView, url);*/
return false;
}
@Override
public void onPageFinished(WebView webView, String s) {
super.onPageFinished(webView, s);
}
};
WebChromeClient webChromeClient = new WebChromeClient() {
@Override
public void onProgressChanged(WebView webView, int i) {
try {
progress.setProgress(i);
} catch (Exception e) {
e.printStackTrace();
}
super.onProgressChanged(webView, i);
}
@Override
public void onReceivedTitle(WebView webView, String s) {
super.onReceivedTitle(webView, s);
tvTitle.setText(s);
}
@Override
public boolean onJsConfirm(WebView webView, String s, String s1, JsResult jsResult) {
return super.onJsConfirm(webView, s, s1, jsResult);
}
};
View.OnClickListener onClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.bt_back:
if(wbContent != null && wbContent.canGoBack()){
wbContent.goBack();
return;
}
finish();
break;
default:
break;
}
}
};
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent == null || wbContent == null || intent.getData() == null){
return;
}
finish();
wbContent.loadUrl(intent.getData().toString());
}
@Override
protected void onDestroy() {
if (unbinder != null) {
unbinder.unbind();
}
//一定要调用WebView的销毁
if (null != wbContent) {
wbContent.destroy();
}
super.onDestroy();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
//监听返回键
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
//判断webView是否还有需要返回的页面
if(wbContent != null && wbContent.canGoBack()){
wbContent.goBack();
return true;
}else{
return super.onKeyDown(keyCode, event);
}
}
return super.onKeyDown(keyCode, event);
}
}
我在使用的过程中,还遇到了一个问题,就是在一个Activity中选择一个本地文件进行预览,可以看到文件显示出来,然后不退出当前Activity继续选择一个文件进行浏览,就会一直都在加载中,如果后面遇到了解决方法,告诉楼主一生,不胜感激。
//实例化TbsReaderView,然后将它装入我们准备的容器
tbsReaderView = new TbsReaderView(activity,readerCallback);
rlContent.addView(tbsReaderView,new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
//下面的回调必须要实现,暂时没找到此回调的用处
TbsReaderView.ReaderCallback readerCallback = new TbsReaderView.ReaderCallback() {
@Override
public void onCallBackAction(Integer integer, Object o, Object o1) {
}
};
private void openFile(String path) {
Bundle bundle = new Bundle();
//文件路径
bundle.putString("filePath", path);
//临时文件的路径,必须设置,否则会报错
bundle.putString("tempPath", Environment.getExternalStorageDirectory().getAbsolutePath()+"腾讯文件TBS");
//准备
boolean result = tbsReaderView.preOpen(getFileType(path), false);
if (result) {
//预览文件
tbsReaderView.openFile(bundle);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//需要将预览服务停止,一定不要忘了
if(tbsReaderView != null){
tbsReaderView.onStop();
}
}
使用这个方式预览,我们需要下载的TBS后面标注为(完整+文件)的SDK
1、public static int openFileReader(Context context, String filePath, HashMap<String, String>
extraParams,ValueCallback<String> callback)
【接口说明】
1、此方法在Qbsdk 类下
2、调用之后,优先调起QQ 浏览器打开文件。如果没有安装QQ 浏览器,在X5 内核下调起简版QB 打开文
件。如果使用的系统内核,则调起文件阅读器弹框。
3、此方法暂时只支持本地文件打开,在线文件后期完善
【参数定义】
context:调起miniqb 的Activity 的context。此参数只能是activity 类型的context,不能设置为Application
的context。
filePath:文件路径。格式为android 本地存储路径格式,例如:/sdcard/Download/xxx.doc. 不支持file:///
格式。暂不支持在线文件。
extraParams:miniqb 的扩展功能。为非必填项,可传入null 使用默认设置。
其格式是一个key 对应一个value。在文件查看器的产品形态中,当前支持的key 包括:
local: “true”表示是进入文件查看器,如果不设置或设置为“false”,则进入miniqb 浏览器模式。不是必
须设置项。
style: “0”表示文件查看器使用默认的UI 样式。“1”表示文件查看器使用微信的UI 样式。不设置此key
或设置错误值,则为默认UI 样式。
topBarBgColor: 定制文件查看器的顶部栏背景色。格式为“#xxxxxx”,例“#2CFC47”;不设置此key 或设置
错误值,则为默认UI 样式。
menuData: 该参数用来定制文件右上角弹出菜单,可传入菜单项的icon 的文本,用户点击菜单项后,sdk
会通过startActivity+intent 的方式回调。menuData 是jsonObject 类型,结构格式如下:
public static final String jsondata =
"{
pkgName:\"com.example.thirdfile\", "
+ "className:\"com.example.thirdfile.IntentActivity\","
+ "thirdCtx: {pp:123},"
+ "menuItems:"
+ "["
+ "{id:0,iconResId:"+ R.drawable.ic_launcher +",text:\"menu0\"},
{id:1,iconResId:" + R.drawable.bookmark_edit_icon + ",text:\"menu1\"},
{id:2,iconResId:"+ R.drawable.bookmark_folder_icon +",text:\"菜单2\"}"
+ "]"
+ "
}";
pkgName 和className 是回调时的包名和类名。
thirdCtx 是三方参数,需要是jsonObject 类型,sdk 不会处理该参数,只是在菜单点击事件发生的时候原样
回传给调用方。
menuItems 是json 数组,表示菜单中的每一项。
ValueCallback:提供miniqb 打开/关闭时给调用方回调通知,以便应用层做相应处理。
在单独进程打开文件的场景中,回调参数出现如下字符时,表示可以关闭当前进程,避免内存占用。
openFileReader open in QB
filepath error
TbsReaderDialogClosed
default browser:
filepath error
fileReaderClosed
【返回说明】
1:用QQ 浏览器打开
2:用MiniQB 打开
3:调起阅读器弹框
-1:filePath 为空打开失败
【使用实例】
//params 为定制参数非必须选项可以传null 为默认设置
public static final Stringjsondata = "{
pkgName:\"com.example.thirdfile\", "
+ "className:\"com.example.thirdfile.IntentActivity\","
+ "thirdCtx: {pp:123},"
+ "menuItems:"
+ "["
+ "{id:0,iconResId:"+ R.drawable.ic_launcher +",text:\"menu0\"},
{id:1,iconResId:" + R.drawable.bookmark_edit_icon + ",text:\"menu1\"},
{id:2,iconResId:"+ R.drawable.bookmark_folder_icon +",text:\"菜单2\"}"
+ "]"
+ " }";
HashMap<String, String> params = new HashMap<String, String>();
params.put("style", "1");
params.put("local", "true");
params.put("memuData", jsondata);
QbSdk.openFileReader(ctx,”/sdcard/xxx.doc”, params,callback);
private void openOtherFile(String path) {
/*QbSdk.canOpenFile(activity, path, new ValueCallback() {
@Override
public void onReceiveValue(Boolean aBoolean) {
Log.e(TAG,"文件是否能够打开:"+aBoolean);
}
});*/
HashMap<String,String> params = new HashMap<>();
//“0”表示文件查看器使用默认的UI 样式。“1”表示文件查看器使用微信的UI 样式。不设置此key或设置错误值,则为默认UI 样式。
params.put("style","1");
//“true”表示是进入文件查看器,如果不设置或设置为“false”,则进入miniqb 浏览器模式。不是必须设置项
params.put("local","true");
//定制文件查看器的顶部栏背景色。格式为“#xxxxxx”,例“#2CFC47”;不设置此key 或设置错误值,则为默认UI 样式。
params.put("topBarBgColor","#ff8b3d");
QbSdk.openFileReader(activity, path, params, new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
}
});
}