欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android集成腾讯X5实现文档浏览功能

程序员文章站 2023-11-18 19:26:58
android内部没有控件来直接显示文档,跳转wps或其他第三方文档app体验性不好,使用腾讯x5内核能很好的解决的这一问题。 一、下载腾讯x5内核 1.前往下载android的内...

android内部没有控件来直接显示文档,跳转wps或其他第三方文档app体验性不好,使用腾讯x5内核能很好的解决的这一问题。

一、下载腾讯x5内核

1.前往下载android的内核,新版本的腾讯x5可以直接在bulid.gradle集成 api 'com.tencent.tbs.tbssdk:sdk:43697',如果是在app里集成可以把api换成implementation

Android集成腾讯X5实现文档浏览功能

2.androidstudio导入腾讯x5

a.把下载好的jar包导入libs,然后run as,再把jnilibs导入main包下

Android集成腾讯X5实现文档浏览功能

b. module的build.gradle添加cpu适配

Android集成腾讯X5实现文档浏览功能

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实现文档浏览功能

未加载内核打开文件

Android集成腾讯X5实现文档浏览功能

总结

以上所述是小编给大家介绍的android集成腾讯x5实现文档浏览功能,希望对大家有所帮助