第一次写博客,请多见谅,写的不好,有什么见解可以跟我说。QQ:1398169857
前段时间需要这么个需求,需要本应用打开word,pdf,ppt等,然后查阅资料,发现有三种方法。
一、使用腾讯X5SDK,它提供文件读取能力,自动解析出来,目前只支持本地打开,估计过阵子会支持网上也能打开,而且解析的很好,推荐使用这个。
使用步骤如下:
①前往https://x5.tencent.com/tbs/sdk.html地址下载Android SDK(完整版 + 文件能力)这个版本
②然后将下下来的jar包放入lib里面,添加依赖。
③然后就是代码:
AndroidManifest.xml里加入权限声明:
Application里加入:
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(getApplicationContext(), cb);
xml里加入:
activity里加入:
import com.tencent.smtt.sdk.QbSdk;
import com.tencent.smtt.sdk.ValueCallback;
import com.tencent.smtt.sdk.WebSettings;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewClient;
public class SWFActivity extends AppCompatActivity {
private WebView wbShow;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_swf);
wbShow = (WebView)this.findViewById(R.id.swf);
wbShow.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView webView, String s) {
webView.loadUrl(s);
return true;
}
});
WebSettings webSetting = wbShow.getSettings();
webSetting.setJavaScriptEnabled(true);
webSetting.setJavaScriptCanOpenWindowsAutomatically(true);
webSetting.setAllowFileAccess(true);
webSetting.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
webSetting.setSupportZoom(true);
webSetting.setBuiltInZoomControls(true);
webSetting.setUseWideViewPort(true);
webSetting.setSupportMultipleWindows(true);
webSetting.setAppCacheEnabled(true);
webSetting.setDomStorageEnabled(true);
webSetting.setGeolocationEnabled(true);
webSetting.setAppCacheMaxSize(Long.MAX_VALUE);
webSetting.setPluginState(WebSettings.PluginState.ON_DEMAND);
webSetting.setCacheMode(WebSettings.LOAD_NO_CACHE);
/**
*打开本地word
*打开本地word
*/
*/
QbSdk.openFileReader(this, Environment.getExternalStorageDirectory() + "/xx/6432.doc", null, new ValueCallback() {
@Override
public void onReceiveValue(String s) {
Log.e("state",s);
}
});
}
QbSdk.openFileReader(this, Environment.getExternalStorageDirectory() + "/xx/6432.doc", null, new ValueCallback() {
@Override
public void onReceiveValue(String s) {
Log.e("state",s);
}
});
}
openFileReader第一个参数必须为activity的context不能为application的context;第二个参数是文件所在的地址;
第三个参数是为了设置一些属性的键值对,这里不做多说明,可以去官网查看,第四个参数是打开软件后的回调,可以在这做处理
,具体去看官网。
还是去https://x5.tencent.com/tbs/sdk.html这里找到sdk接入示例下载下来,把lib里面armeabi文件夹考入你的lib下。
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.chiyu.edu.cloudclassroom.util.L;
import com.tencent.smtt.sdk.TbsReaderView;
import java.io.File;
/**
* Created by xxx on 2017/8/29.
*/
public class SuperFileView2 extends FrameLayout implements TbsReaderView.ReaderCallback {
private static String TAG = "SuperFileView";
private TbsReaderView mTbsReaderView;
private int saveTime = -1;
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, this);
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, this);
}
public void displayFile(File mFile) {
// Log.e("mfile",mFile.toString());
if (mFile != null && !TextUtils.isEmpty(mFile.toString())) {
//增加下面一句解决没有TbsReaderTemp文件夹存在导致加载文件失败
String bsReaderTemp = "/storage/emulated/0/TbsReaderTemp";
File bsReaderTempFile =new File(bsReaderTemp);
if (!bsReaderTempFile.exists()) {
L.d("准备创建/storage/emulated/0/TbsReaderTemp!!");
boolean mkdir = bsReaderTempFile.mkdir();
if(!mkdir){
L.e("创建/storage/emulated/0/TbsReaderTemp失败!!!!!");
}
}
//加载文件
Bundle localBundle = new Bundle();
L.d(mFile.toString());
localBundle.putString("filePath", mFile.toString());
localBundle.putString("tempPath", Environment.getExternalStorageDirectory() + "/" + "TbsReaderTemp");
L.e( Environment.getExternalStorageDirectory() + "/" + "TbsReaderTemp");
if (this.mTbsReaderView == null)
this.mTbsReaderView = getTbsReaderView(context);
boolean bool = this.mTbsReaderView.preOpen(getFileType(mFile.toString()), false);
L.e(bool+"");
if (bool) {
this.mTbsReaderView.openFile(localBundle);
}
} else {
L.e("文件路径无效!");
}
}
/***
* 获取文件类型
*
* @param paramString
* @return
*/
private String getFileType(String paramString) {
String str = "";
if (TextUtils.isEmpty(paramString)) {
L.d(TAG, "paramString---->null");
return str;
}
L.d(TAG, "paramString:" + paramString);
int i = paramString.lastIndexOf('.');
if (i <= -1) {
L.d(TAG, "i <= -1");
return str;
}
str = paramString.substring(i + 1);
L.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);
}
@Override
public void onCallBackAction(Integer integer, Object o, Object o1) {
L.e("****************************************************" + integer);
}
public void onStopDisplay() {
if (mTbsReaderView != null) {
mTbsReaderView.onStop();
}
}
}
然后就可以直接用了,直接当成一个控件使用。
xml代码:
java代码:
记得ondestory的时候stop一下。path是文件在你本地的位置,如:
/sdcard/xx.doc
private SuperFileView2 fileShowSfv;
fileShowSfv = (SuperFileView2) findViewById(R.id.fileShow_sfv);
/**
* 初始化数据
*/
private void initSuperFileView() {
final String path = getIntent().getStringExtra("path");
if (!TextUtils.isEmpty(path)) {
final File file = new File(path);
title.setText(getIntent().getStringExtra("title"));
fileShowSfv.setOnGetFilePathListener(new SuperFileView2.OnGetFilePathListener() {
@Override
public void onGetFilePath(SuperFileView2 mSuperFileView2) {
mSuperFileView2.displayFile(file);
}
});
}
fileShowSfv.show();
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("FileDisplayActivity","onDestroy");
if (fileShowSfv != null) {
fileShowSfv.onStopDisplay();
}
}
二、使用第三方的在线预览工具,该方法的解决方法是把想要解析的office文档url地址传递给第三方在线解析,然后使用webview显示即可,此方法对于app端来说确实非常有利,因为app端不需要自己进行任何解析,只是如果将自己文档的url交给第三方,依然存在安全问题
现附上两个在线预览office文档的地址:(浏览器都需要chrome的内核)
1 google:https://docs.google.com/viewer?url=(输入你的文档在服务器中的地址);
2 微软:https://view.officeapps.live.com/op/view.aspx?src=(输入你的文档在服务器中的地址);
如果您对自己的文档完全没有安全方面的考虑,建议使用微软的在线解析,亲测可用,谷歌的在国内被封了(没办法,摊手)
[java] view plain copy
三、发现很多资料都是使用poi去解析office,但是这样很容易造成数据丢失,学习poi成本也高,还会缺失awt的一些类包以及一些方法需要改变,而且文件必须预先下载在本地然后解析。
其中word和ppt使用poi解决的;
pdf我是借用别人的,请看这里:https://github.com/barteksc/AndroidPdfViewer
xml代码:
java代码:
pdfView = (PDFView) findViewById(R.id.pdfView);
// displayFromAsset(SAMPLE_FILE);
Uri uir = Uri.parse(Environment.getExternalStorageState() + "/xx/sample.pdf");
displayFromUri(uir);
private void displayFromAsset(String assetFileName) {
pdfFileName = assetFileName;
pdfView.fromAsset(SAMPLE_FILE)
.defaultPage(pageNumber)
.onPageChange(this)
.enableAnnotationRendering(true)
.onLoad(this)
.scrollHandle(new DefaultScrollHandle(this))
.spacing(10) // in dp
.load();
}
private void displayFromUri(Uri uri) {
pdfFileName = getFileName(uri);
pdfView.fromUri(uri)
.defaultPage(pageNumber)
.onPageChange(this)
.enableAnnotationRendering(true)
.onLoad(this)
.scrollHandle(new DefaultScrollHandle(this))
.spacing(10) // in dp
.load();
}
public String getFileName(Uri uri) {
String result = null;
if (uri.getScheme().equals("content")) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}
} finally {
if (cursor != null) {
cursor.close();
}
}
}
if (result == null) {
result = uri.getLastPathSegment();
}
return result;
}
下面介绍一下poi解析ppt和word:
查看资料http://blog.csdn.net/u011791526/article/details/73250358
查看资料http://download.csdn.net/download/u011239240/9965008
将下面几个文件放入main的java下,由于我项目中这几个文件夹放在我的项目下改了大半天,其实放在java下完全不用改
添加依赖
代码部分:
代码太多,就直接上传文件了。
jar包和那几个文件夹最好用我项目里面的。地址:http://download.csdn.net/download/qq_27378951/10047080