实现浏览word文档,pdf, txt, xls等文件
在app中浏览pdf, xls, ppt,这些文件有可能是存在本地的, 也能是后台数据给返回的;如果是本地的那么没什么好说的, 直接加载就好了, 但是后台给返回的呢?
如果后台以一个列表的形式或者其他等形式出现或者后台给返回;而且这些数据还不是固定的,有可能今天是pdf, 明天就可能是ppt了,这些文件一般来说都会做成活的,比如是后台上传的, 也比如是一些有权限的人员做出的演示文档ppt, 这些会出现在app中是为了实现某种活动或给用户展示用的,那么打开浏览应该怎么办呢?
下面说一下腾讯的浏览服务,直接找到官网,按照文档指示来操作,但下载的SDK有点坑,反正我是没弄明白里面的demo是什么玩意...
下载之后直接拷贝jar包到 libs 文件夹下,还有so文件,页面布局也直接拷贝过来
然后这个类就是主要显示的了
/**
* 此 Activity 使用 TBS (腾讯浏览服务)查看文件
* <br/> 默认支持常见文件类型
* <br/> <b>默认支持类型:</b>
* <li>doc</li>
* <li>docx</li>
* <li>ppt</li>
* <li>pptx</li>
* <li>xls</li>
* <li>xlsx</li>
* <li>txt</li>
* <li>pdf</li>
* <li>epub</li>
* <br/>
* intent参数: filePath - 文件路径
*
* @author hanlyjiang
*/
public class TBSFileViewActivity extends AppCompatActivity implements TbsReaderView.ReaderCallback {
public static final String FILE_PATH = "filePath";
private static final String TAG = "TBSFileViewActivity";
private TbsReaderView mTbsReaderView;
private FrameLayout rootViewParent;
private ViewGroup errorHandleLayout;
private String filePath;
public static void viewFile(Context context, String localPath) {
Intent intent = new Intent(context, TBSFileViewActivity.class);
intent.putExtra(FILE_PATH, localPath);
context.startActivity(intent);
}
public static String getFileName(String filePath) {
if (filePath == null) {
return "";
}
int lastSlashIndex = filePath.lastIndexOf("/") + 1;
if (lastSlashIndex == -1) {
return filePath;
}
int lastDotFromSlashIndex = filePath.indexOf(".", lastSlashIndex);
if (lastDotFromSlashIndex == -1) {
return filePath.substring(lastSlashIndex);
}
return filePath.substring(lastSlashIndex, lastDotFromSlashIndex);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tbs_file_view_layout);
rootViewParent = (FrameLayout) findViewById(R.id.fl_rootview);
errorHandleLayout = (ViewGroup) findViewById(R.id.ll_error_handle);
initErrorHandleLayout(errorHandleLayout);
filePath = handleIntent();
if (TextUtils.isEmpty(filePath) || !new File(filePath).isFile()) {
AndroidUtils.showToast(this, "filePath = " + filePath);
AndroidUtils.showToast(this, getString(R.string.file_not_exist));
finish();
}
getSupportActionBar().setTitle(getString(R.string.view_file) + getFileName(filePath));
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mTbsReaderView = new TbsReaderView(this, this);
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT
);
mTbsReaderView.setLayoutParams(layoutParams);
rootViewParent.addView(mTbsReaderView);
displayFile(filePath);
}
private void initErrorHandleLayout(ViewGroup errorHandleLayout) {
findViewById(R.id.btn_retry_with_tbs).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
displayFile(filePath);
}
});
findViewById(R.id.btn_view_with_other_app).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FileViewerUtils.viewFile4_4(v.getContext(), filePath);
}
});
}
private String handleIntent() {
if (getIntent() != null) {
return getIntent().getStringExtra(FILE_PATH);
}
return null;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onCallBackAction(Integer integer, Object long1, Object long2) {
Log.d(TAG, "onCallBackAction " + integer + "," + long1 + "," + long2);
}
private void displayFile(String fileAbsPath) {
Bundle bundle = new Bundle();
bundle.putString("filePath", fileAbsPath);
bundle.putString("tempPath", Environment.getExternalStorageDirectory().getPath());
// preOpen 需要文件后缀名 用以判断是否支持
boolean result = mTbsReaderView.preOpen(parseFormat(fileAbsPath), true);
if (result) {
mTbsReaderView.openFile(bundle);
mTbsReaderView.setVisibility(View.VISIBLE);
errorHandleLayout.setVisibility(View.GONE);
} else {
mTbsReaderView.setVisibility(View.GONE);
errorHandleLayout.setVisibility(View.VISIBLE);
}
}
private String parseFormat(String fileName) {
return fileName.substring(fileName.lastIndexOf(".") + 1);
}
@Override
protected void onDestroy() {
super.onDestroy();
mTbsReaderView.onStop();
}
}
如果是打开本地的话请看下面
public void initView() {
findViewById(R.id.btn_open_pdf_with_tbs).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 本地打开
openFileWithTbs(getFilePath("TestPDF.pdf"));
}
});
}
private String getFilePath(String fileName) {
return new File(App.FILE_DIR + fileName).getAbsolutePath();
}
private void openFileWithTbs(String filePath) {
LogUtils.e("Open File: " + filePath);
TBSFileViewActivity.viewFile(this, filePath);
}
如果是下载然后打开请看下面
findViewById(R.id.btn_open_pdf_with_tbs).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 本地打开
// openFileWithTbs(getFilePath("TestPDF.pdf"));
// 下载到本地打开
DocumentFileUtils.getInstance(MainActivity.this)
.setDisplayFile(new DocumentFileUtils.OnDisplayFile() {
@Override
public void displayError() {
}
@Override
public void displayImage(String imageUrl) {
// 如果是图片,处理方法
}
@Override
public void displayFile(File file, String filePath) {
openFileWithTbs(filePath);
}
})
.setFileName(DocumentFileUtils.getFileName(url_pdf))
.setLoadUrl(url_pdf)
.start();
}
});
}
在这里我提供一个下载文件的工具类, 里面有几种回调
public interface OnDisplayFile {
//第一个文件出现错误,文件地址不存在,或者网络原因
void displayError();
//第二个下载的地址是图片
void displayImage(String imageUrl);
//正常显示,file: 下载的当前文件, filePath: 文件的路径
void displayFile(File file, String filePath);
}
这样不管是什么样格式的文件,直接交给TBSFileViewActivity就ok了;
代码传送门:
https://github.com/xiaobinAndroid421726260/Android_X5WebView_Demo_2019_7_9.git