android打开office

第一次写博客,请多见谅,写的不好,有什么见解可以跟我说。QQ:1398169857

前段时间需要这么个需求,需要本应用打开word,pdf,ppt等,然后查阅资料,发现有三种方法。

一、使用腾讯X5SDK,它提供文件读取能力,自动解析出来,目前只支持本地打开,估计过阵子会支持网上也能打开,而且解析的很好,推荐使用这个。

使用步骤如下:

①前往https://x5.tencent.com/tbs/sdk.html地址下载Android SDK(完整版 + 文件能力)这个版本

②然后将下下来的jar包放入lib里面,添加依赖。

然后就是代码:

AndroidManifest.xml里加入权限声明:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

<uses-permission android:name="android.permission.INTERNET" />

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

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里加入:
<com.tencent.smtt.sdk.ebView
        android:id="@+id/wb"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>


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<String>() {
            @Override
            public void onReceiveValue(String s) {
                Log.e("state",s);
            }
        });
    }
QbSdk.openFileReader(this,  Environment.getExternalStorageDirectory() + "/xx/6432.doc", null, new ValueCallback<String>() {
            @Override
            public void onReceiveValue(String s) {
                Log.e("state",s);
            }
        });
    }


openFileReader第一个参数必须为activity的context不能为application的context;第二个参数是文件所在的地址;

第三个参数是为了设置一些属性的键值对,这里不做多说明,可以去官网查看,第四个参数是打开软件后的回调,可以在这做处理

,具体去看官网。

注意:如果遇到如下问题dlopen("/data/data/com.tencent.mm/app_tbs/core_share/libgpu-mtt-4.2.so", RTLD_LAZY) failed: dlopen failed: 

"/data/data/com.tencent.mm/app_tbs/core_share/libgpu-mtt-4.2.so" is 32-bit instead of 64-bit

还是去https://x5.tencent.com/tbs/sdk.html这里找到sdk接入示例下载下来,把lib里面armeabi文件夹考入你的lib下。

注意:后来发现这个打开后第一次是需要弹框的,官网也显示无法解决,后来网上找到了

一个tbs阅读内部控件,创建一个SuperFileView继承FrameLayout实现tbs的readercallback接口。

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();
        }
    }
}
 
<com.chiyu.edu.cloudclassroom.widget.SuperFileView2 android:id="@+id/fileShow_sfv" android:layout_width="match_parent" android:layout_height="match_parent" />

然后就可以直接用了,直接当成一个控件使用。

xml代码:

<com.chiyu.edu.cloudclassroom.widget.SuperFileView2
        android:id="@+id/fileShow_sfv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

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

  1. WebView urlWebView = (WebView) findViewById(R.id.containWebView);  
  2.         urlWebView.setVisibility(View.VISIBLE);  
  3.         mLvAttach.setVisibility(View.GONE);  
  4.         urlWebView.setWebViewClient(new AppWebViewClients());  
  5.         urlWebView.getSettings().setJavaScriptEnabled(true);  
  6.         urlWebView.getSettings().setUseWideViewPort(true);  
  7.        // https://view.officeapps.live.com/op/view.aspx?src  
  8.         urlWebView.loadUrl("http://view.officeapps.live.com/op/view.aspx?src=”文档在服务器的地址”);  
  9.    
  10.  public class AppWebViewClients extends WebViewClient {  
  11.   
  12.         @Override  
  13.         public boolean shouldOverrideUrlLoading(WebView view, String url) {  
  14.             // TODO Auto-generated method stub  
  15.             view.loadUrl(url);  
  16.             return true;  
  17.         }  
  18.         @Override  
  19.         public void onPageFinished(WebView view, String url) {  
  20.             // TODO Auto-generated method stub  
  21.             super.onPageFinished(view, url);  
  22.         }  
  23.     }  

三、发现很多资料都是使用poi去解析office,但是这样很容易造成数据丢失,学习poi成本也高,还会缺失awt的一些类包以及一些方法需要改变,而且文件必须预先下载在本地然后解析。

其中word和ppt使用poi解决的;

pdf我是借用别人的,请看这里:https://github.com/barteksc/AndroidPdfViewer

xml代码:

<com.github.barteksc.pdfviewer.PDFView
    android:id="@+id/pdfView"
    android:layout_width="0dp"
    android:layout_height="0dp"
    tools:layout_editor_absoluteY="8dp"
    tools:layout_editor_absoluteX="8dp" />

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

发布了14 篇原创文章 · 获赞 23 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_27378951/article/details/78341179