Android集成腾讯X5实现文档浏览功能
android内部没有控件来直接显示文档,跳转wps或其他第三方文档app体验性不好,使用腾讯x5内核能很好的解决的这一问题。
一、下载腾讯x5内核
1.前往下载android的内核,新版本的腾讯x5可以直接在bulid.gradle集成 api 'com.tencent.tbs.tbssdk:sdk:43697',如果是在app里集成可以把api换成implementation
2.androidstudio导入腾讯x5
a.把下载好的jar包导入libs,然后run as,再把jnilibs导入main包下
b. module的build.gradle添加cpu适配
3.application中腾讯x5初始化,在oncreate()方法调用init方法
qbsdk.initx5environment(this, new qbsdk.preinitcallback() { @override public void oncoreinitfinished() { } @override public void onviewinitfinished(boolean b) { log.e("xxx","hasload"+b); //此处将内核加载是否成功的状态保存到本地,sharepreference工具类可换为自己的 sharedpreferenceutils.saveboolean(getapplicationcontext(),"hasload",b); } });
4.应用内调用,无论是否加载内核,都是把在线的文档下载到本地然后打开,不同的是,未加载内核会借助qq浏览器或其他app的文件浏览功能类似微信(这个调用,腾讯x5已自动处理,我们无需关心),而加载内核后,使用x5的tbsreaderview来打开文件,接下来就是具体代码。
a.bulid.gradle中集成retrofit,rxjava和进度管理器progressmanager
implementation 'io.reactivex:rxandroid:1.2.1' implementation 'com.squareup.retrofit2:converter-gson:2.3.0' implementation 'com.squareup.retrofit2:adapter-rxjava:2.1.0' implementation 'com.squareup.retrofit2:retrofit:2.3.0' implementation 'io.reactivex:rxjava:1.2.6' implementation 'me.jessyan:progressmanager:1.5.0'
写网络下载工具
public interface loadfileapi { @get call<responsebody> loadpdffile(@url string fileurl); } public class loadfilemodel { //使用该方法来下载文件 public static void loadpdffile(string url, callback<responsebody> callback) { retrofit retrofit = new retrofit.builder() .baseurl("https://www.baidu.com/") .client(progressmanager.getinstance().with(new okhttpclient.builder()) .build()) .addconverterfactory(gsonconverterfactory.create()) .build(); loadfileapi mloadfileapi = retrofit.create(loadfileapi.class); if (!textutils.isempty(url)) { call<responsebody> call = mloadfileapi.loadpdffile(url); call.enqueue(callback); } } }
b.具体调用
首先注册文件进度下载监听
private progressdialog commonprogressdialog;//切换为自己的进度控件 private progressinfo mlastdownloadinginfo; progressmanager.getinstance().addresponselistener(url, new progresslistener() { @override public void onprogress(progressinfo progressinfo) { if (mlastdownloadinginfo == null) { mlastdownloadinginfo = progressinfo; } //因为是以请求开始时的时间作为 id ,所以值越大,说明该请求越新 if (progressinfo.getid() < mlastdownloadinginfo.getid()) { return; } else if (progressinfo.getid() > mlastdownloadinginfo.getid()) { mlastdownloadinginfo = progressinfo; } int progress = mlastdownloadinginfo.getpercent(); commonprogressdialog.setprogress(progress); log.d("xxx", "--download-- " + progress + " % " + mlastdownloadinginfo.getspeed() + " byte/s " + mlastdownloadinginfo.tostring()); if (mlastdownloadinginfo.isfinish()) { //说明已经下载完成 commonprogressdialog.dismiss(); log.d("xxx", "--download-- finish"); } } @override public void onerror(long id, exception e) { e.printstacktrace(); new handler().post(new runnable() { @override public void run() { commonprogressdialog.dismiss(); } }); } }); }
然后打开文件
private static final string down_dir = environment.getexternalstoragedirectory() + file.separator+"download"; //文件下载的路径,可以自定义 //打开文件 private void openfile(string filepath,string filename) { boolean hasload = sharedpreferenceutils.getboolean(mcontext, "hasload");//是否记载内核 if (hasload){ //展示文件的activity intent intentdoc = new intent(this,filedisplayactivity.class); intentdoc.putextra("path",filepath); intentdoc.putextra("filename",filename); startactivity(intentdoc); }else { if(!environment.getexternalstoragestate().equals(environment.media_mounted)){ toast.maketext(this,"当前sd不可用",toast.length_long).show(); return; } try { file file = new file(down_dir, filename); if (file.exists()){ qbsdk.openfilereader(this, file.getabsolutepath(), null, new valuecallback<string>() { @override public void onreceivevalue(string s) { log.e("xxx",s); } }); } else { downloadfile(filepath,filename); } } catch (exception e) { e.printstacktrace(); toastutils.showshorttoast(mcontext, "已下载过了"); } } } private void downloadfile(final string url, final string filename) { commonprogressdialog.show(); loadfilemodel.loadpdffile(url, new callback<responsebody>() { @override public void onresponse(@nonnull call<responsebody> call, @nonnull response<responsebody> response) { inputstream is = null; byte[] buf = new byte[2048]; int len; fileoutputstream fos = null; try { responsebody responsebody = response.body(); if (responsebody != null) { is = responsebody.bytestream(); final file file = new file(down_dir, filename); fos = new fileoutputstream(file); while ((len = is.read(buf)) != -1) { fos.write(buf, 0, len); } fos.flush(); //未加载内核调用方法 qbsdk.openfilereader(mcontext, file.getabsolutepath(), null, new valuecallback<string>() { @override public void onreceivevalue(string s) { log.e("xxx",s); } }); toastutils.showlongtoast(meetingdetailactivity.this, "下载成功,保存在download文件夹下"); } } catch (exception e) { commonprogressdialog.dismiss(); progressmanager.getinstance().notifyonerorr(url,e); toastutils.showlongtoast(meetingdetailactivity.this, "下载失败"); } finally { try { if (is != null) is.close(); } catch (ioexception e) { e.printstacktrace(); } try { if (fos != null) fos.close(); } catch (ioexception e) { e.printstacktrace(); } } } @override public void onfailure(@nonnull call<responsebody> call, @nonnull throwable t) { t.printstacktrace(); toastutils.showshorttoast(meetingdetailactivity.this, "下载失败"); commonprogressdialog.dismiss(); } }); }
filedisplayactivity代码,对于一些包名可以切换为自己的包名,还有一些第三方库像进度展示,也可以切换为自己的进度控件
import android.content.intent; import android.os.bundle; import android.os.environment; import android.os.handler; import android.os.message; import android.support.annotation.nonnull; import android.support.annotation.nullable; import android.support.v7.app.appcompatactivity; import android.text.textutils; import android.util.log; import android.view.view; import android.view.windowmanager; import android.widget.textview; import com.anshi.oatencentschool.r; import com.anshi.oatencentschool.utils.dialogbuild; import com.anshi.oatencentschool.utils.statusbarutils; import com.anshi.oatencentschool.utils.toastutils; import com.anshi.oatencentschool.utils.weakhandler; import com.anshi.oatencentschool.utils.filetool.loadfilemodel; import com.anshi.oatencentschool.utils.filetool.superfileview2; import com.kaopiz.kprogresshud.kprogresshud; import java.io.file; import java.io.fileoutputstream; import java.io.ioexception; import java.io.inputstream; import me.jessyan.progressmanager.progresslistener; import me.jessyan.progressmanager.progressmanager; import me.jessyan.progressmanager.body.progressinfo; import okhttp3.responsebody; import retrofit2.call; import retrofit2.callback; import retrofit2.response; public class filedisplayactivity extends appcompatactivity { private string tag = "filedisplayactivity"; //tencent 提供的tbs阅读浏览功能,不借助第三方软件打开office和pdf文件 private superfileview2 msuperfileview; private string filepath; private textview mtextview; private static final string down_dir = environment.getexternalstoragedirectory() + file.separator+"download"; private string filename; private kprogresshud commonprogressdialog; private weakhandler weakhandler = new weakhandler(new handler.callback() { @override public boolean handlemessage(message msg) { int progress = msg.arg1; if (progress==100){ commonprogressdialog.setprogress(progress); commonprogressdialog.dismiss(); }else { commonprogressdialog.setprogress(progress); } return true; } }); @override protected void oncreate(@nullable bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_file_display); getwindow().addflags(windowmanager.layoutparams.flag_keep_screen_on|windowmanager.layoutparams.flag_fullscreen); commonprogressdialog = dialogbuild.getbuild().createcommonprogressdialog(this, "下载中"); init(); } /** * 初始化 */ public void init() { mtextview = (textview) findviewbyid(r.id.file_album_name); filename = getintent().getstringextra("filename"); int lastindexof = filename.lastindexof("."); string substring = filename.substring(0, lastindexof); mtextview.settext(substring); msuperfileview = (superfileview2) findviewbyid(r.id.msuperfileview); msuperfileview.setongetfilepathlistener(new superfileview2.ongetfilepathlistener() { @override public void ongetfilepath(superfileview2 msuperfileview2) { getfilepathandshowfile(msuperfileview); } }); intent intent = this.getintent(); string path = (string) intent.getserializableextra("path"); if (!textutils.isempty(path)) { log.d(tag, "文件path:" + path); setfilepath(path); } msuperfileview.show(); progressmanager.getinstance().addresponselistener(path, new progresslistener() { @override public void onprogress(progressinfo progressinfo) { int percent = progressinfo.getpercent(); message obtain = message.obtain(); obtain.arg1 = percent; weakhandler.sendmessage(obtain); } @override public void onerror(long id, exception e) { } }); } @override protected void onresume() { super.onresume(); statusbarutils.setwindowstatusbarcolor(this,r.color.color_main); } /** * 显示文件 * @param msuperfileview2 控件 */ private void getfilepathandshowfile(superfileview2 msuperfileview2) { if (getfilepath().contains("http")&&!new file(down_dir, filename).exists()) {//网络地址要先下载 downloadfile(getfilepath(),filename,msuperfileview2); } else { try { msuperfileview2.displayfile(new file(down_dir, filename)); }catch (exception e){ e.printstacktrace(); } } } public void setfilepath(string fileurl) { this.filepath = fileurl; } private string getfilepath() { return filepath; } /** * 回退上一级菜单 * @param view 控件 */ public void onclick(view view) { finish(); } private void downloadfile(final string url, final string filename,final superfileview2 msuperfileview2) { commonprogressdialog.show(); loadfilemodel.loadpdffile(url, new callback<responsebody>() { @override public void onresponse(@nonnull call<responsebody> call, @nonnull response<responsebody> response) { inputstream is = null; byte[] buf = new byte[2048]; int len; fileoutputstream fos = null; try { responsebody responsebody = response.body(); is = responsebody.bytestream(); final file file = new file(down_dir, filename); fos = new fileoutputstream(file); while ((len = is.read(buf)) != -1) { fos.write(buf, 0, len); } fos.flush(); msuperfileview2.displayfile(file); toastutils.showlongtoast(filedisplayactivity.this, "下载成功,保存在download文件夹下"); } catch (exception e) { commonprogressdialog.dismiss(); toastutils.showlongtoast(filedisplayactivity.this, "下载失败"); } finally { try { if (is != null) is.close(); } catch (ioexception e) { e.printstacktrace(); } try { if (fos != null) fos.close(); } catch (ioexception e) { e.printstacktrace(); } } } @override public void onfailure(@nonnull call<responsebody> call, @nonnull throwable t) { t.printstacktrace(); toastutils.showshorttoast(filedisplayactivity.this, "下载失败"); commonprogressdialog.dismiss(); } }); } }
布局layout:
<?xml version="1.0" encoding="utf-8"?> <relativelayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/activity_file_display" android:layout_width="match_parent" android:fitssystemwindows="true" android:layout_height="match_parent"> <android.support.v7.widget.toolbar android:layout_width="match_parent" android:layout_height="46dp" android:background="@color/color_main" android:id="@+id/file_toolbar" > <textview android:layout_width="wrap_content" android:layout_height="match_parent" android:id="@+id/file_album_name" android:layout_gravity="center" android:gravity="center" android:maxlines="2" android:ellipsize="end" android:textsize="14sp" android:textcolor="#fff" /> </android.support.v7.widget.toolbar> <framelayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/file_toolbar" > <com.anshi.oatencentschool.utils.filetool.superfileview2 android:id="@+id/msuperfileview" android:layout_width="match_parent" android:layout_height="match_parent"/> <relativelayout android:layout_width="wrap_content" android:layout_gravity="center|start" android:layout_height="wrap_content"> <radiobutton android:layout_width="wrap_content" android:layout_height="wrap_content" android:button="@null" android:onclick="onclick" android:id="@+id/back_icon" android:drawablestart="@drawable/svg_left_back_blur" android:layout_marginstart="10dp" /> </relativelayout> <!--<radiobutton--> <!--android:layout_width="wrap_content"--> <!--android:layout_height="wrap_content"--> <!--android:button="@null"--> <!--android:visibility="gone"--> <!--android:layout_gravity="end|bottom"--> <!--android:onclick="savelocal"--> <!--android:layout_marginbottom="10dp"--> <!--android:layout_marginend="10dp"--> <!--android:drawablestart="@drawable/vector_drawable_down_load"--> <!--android:layout_marginstart="10dp"--> <!--/>--> </framelayout> </relativelayout>
superfileview2代码,这个自定义的类是从https://github.com/zhongxiaohong/superfileview导入
import android.content.context; import android.os.bundle; import android.os.environment; import android.text.textutils; import android.util.attributeset; import android.util.log; import android.widget.framelayout; import android.widget.linearlayout; import com.tencent.smtt.sdk.tbsreaderview; import java.io.file; /** * * created by 12457 on 2017/8/29. */ public class superfileview2 extends framelayout { private static string tag = "superfileview"; private tbsreaderview mtbsreaderview; private context context; public superfileview2(context context) { this(context, null, 0); } public superfileview2(context context, attributeset attrs) { this(context, attrs, 0); } public superfileview2(context context, attributeset attrs, int defstyleattr) { super(context, attrs, defstyleattr); mtbsreaderview = new tbsreaderview(context, new tbsreaderview.readercallback() { @override public void oncallbackaction(integer integer, object o, object o1) { } }); this.addview(mtbsreaderview, new linearlayout.layoutparams(-1, -1)); this.context = context; } private ongetfilepathlistener mongetfilepathlistener; public void setongetfilepathlistener(ongetfilepathlistener mongetfilepathlistener) { this.mongetfilepathlistener = mongetfilepathlistener; } private tbsreaderview gettbsreaderview(context context) { return new tbsreaderview(context, new tbsreaderview.readercallback() { @override public void oncallbackaction(integer integer, object o, object o1) { } }); } public void displayfile(file mfile) { if (mfile != null && !textutils.isempty(mfile.tostring())) { //增加下面一句解决没有tbsreadertemp文件夹存在导致加载文件失败 string bsreadertemp = environment.getexternalstoragedirectory()+ file.separator+"tbsreadertemp"; file bsreadertempfile =new file(bsreadertemp); if (!bsreadertempfile.exists()) { log.d("xxx","准备创建/storage/emulated/0/tbsreadertemp!!"); boolean mkdir = bsreadertempfile.mkdir(); if(!mkdir){ log.d("xxx","创建/storage/emulated/0/tbsreadertemp失败!!!!!"); } } //加载文件 bundle localbundle = new bundle(); log.d("xxx",mfile.tostring()); localbundle.putstring("filepath", mfile.tostring()); localbundle.putstring("temppath", bsreadertemp); if (mtbsreaderview == null){ mtbsreaderview = gettbsreaderview(context.getapplicationcontext()); string filetype = getfiletype(mfile.tostring()); boolean bool = mtbsreaderview.preopen(filetype,false); if (bool) { try { mtbsreaderview.openfile(localbundle); }catch (exception e){ e.printstacktrace(); } } }else { string filetype = getfiletype(mfile.tostring()); boolean bool = mtbsreaderview.preopen(filetype,false); if (bool) { try { mtbsreaderview.openfile(localbundle); }catch (exception e){ e.printstacktrace(); } } } } else { log.d("xxx","文件路径无效!"); } } /*** * 获取文件类型 * * @param paramstring * @return */ private string getfiletype(string paramstring) { string str = ""; if (textutils.isempty(paramstring)) { log.d(tag, "paramstring---->null"); return str; } log.d(tag, "paramstring:" + paramstring); int i = paramstring.lastindexof('.'); if (i <= -1) { log.d(tag, "i <= -1"); return str; } str = paramstring.substring(i + 1); log.d(tag, "paramstring.substring(i + 1)------>" + str); return str; } public void show() { if(mongetfilepathlistener!=null){ mongetfilepathlistener.ongetfilepath(this); } } /*** * 将获取file路径的工作,“外包”出去 */ public interface ongetfilepathlistener { void ongetfilepath(superfileview2 msuperfileview2); } public void onstopdisplay() { if (mtbsreaderview != null) { mtbsreaderview.onstop(); } } }
加载内核后打开文件
未加载内核打开文件
总结
以上所述是小编给大家介绍的android集成腾讯x5实现文档浏览功能,希望对大家有所帮助
上一篇: 什么叫地沟油危害人体健康罪不可逃
下一篇: 左棻是什么人?她为什么一生不得宠