一、TBS簡介:(TBS官網:https://x5.tencent.com/tbs/index.html)
騰訊瀏覽服務(TBS,Tencent Browsing Service)整合騰訊底層瀏覽技術和騰訊平臺資源及能力,提供整體瀏覽服務解決方案。TBS在文件打開方面,目前支持42種文件格式,包括20種文檔、12種音樂、6種圖片和4種壓縮包。幫助應用實現應用內文檔瀏覽,無需跳轉調用其他應用。
二、TBS的讀取本地pdf、doc等文件的使用
1、下載並導入TBS相關的sdk
2、新建jniLibs\armeabi文件夾,並將 liblbs.so文件導入
3、新建assets文件夾,將需要加載html相關文件放入本地文件夾內
4、在AndroidManifest.xml中添加對應的權限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_SETTINGS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- 硬件加速對X5視頻播放非常重要,建議開啓 -->
<uses-permission android:name="android.permission.GET_TASKS" />
5、在 build.gradle中的defaultConfig添加支持的ndk
ndk {
abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
}
6、xml中添加頁面佈局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="@+id/frame_web_video"></FrameLayout>
<com.tencent.smtt.sdk.WebView
android:layout_width="match_parent"
android:layout_height="200px"
android:id="@+id/web_filechooser">
</com.tencent.smtt.sdk.WebView>
<FrameLayout
android:layout_below="@id/web_filechooser"
android:layout_width="match_parent"
android:layout_height="500px"
android:id="@+id/redFile" >
</FrameLayout>
</RelativeLayout>
注意: webview是用來加載html頁面的,並且webview需要使用TBS提供的webview組件
FrameLayout使用來顯示讀取的文檔的位置
7、Activity中具體實現代碼
public class DocBrower extends AppCompatActivity {
// @InjectView(R.id.test_webView)
WebView mTestView;
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE" };
private ValueCallback<Uri> uploadFile;
private ValueCallback<Uri[]> uploadFiles;
private FrameLayout mReadFile;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_doc_brower);
ButterKnife.inject(this);
verifyStoragePermissions(DocBrower.this);
mTestView=(WebView)findViewById(R.id.web_filechooser);
mReadFile = (FrameLayout) findViewById(R.id.show_doc);
//設置webview相關屬性
WebSettings webSetting = mTestView.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);
//設置html頁面監聽
mTestView.setWebChromeClient(new WebChromeClient(){
// For Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
Log.i("test", "openFileChooser 1");
DocBrower.this.uploadFile = uploadFile;
openFileChooseProcess();
}
// For Android < 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsgs) {
Log.i("test", "openFileChooser 2");
DocBrower.this.uploadFile = uploadFile;
openFileChooseProcess();
}
// For Android > 4.1.1
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
Log.i("test", "openFileChooser 3");
DocBrower.this.uploadFile = uploadFile;
openFileChooseProcess();
}
// For Android >= 5.0
public boolean onShowFileChooser(com.tencent.smtt.sdk.WebView webView,
ValueCallback<Uri[]> filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams) {
Log.i("test", "openFileChooser 4:" + filePathCallback.toString());
DocBrower.this.uploadFiles = filePathCallback;
openFileChooseProcess();
return true;
}
});
//將html加載到webview上
mTestView.loadUrl("file:///android_asset/webpage/fileChooser.html");
CookieManager.getInstance();
CookieSyncManager.createInstance(this);
CookieSyncManager.getInstance().sync();
}
//動態申請文件讀寫權限
public static void verifyStoragePermissions(Activity activity) {
try {
//檢測是否有寫的權限
int permission = ActivityCompat.checkSelfPermission(activity,
"android.permission.WRITE_EXTERNAL_STORAGE");
if (permission != PackageManager.PERMISSION_GRANTED) {
// 沒有寫的權限,去申請寫的權限,會彈出對話框
ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE,REQUEST_EXTERNAL_STORAGE);
}
} catch (Exception e) {
e.printStackTrace();
}
}
//打開本地文件,進行選擇
private void openFileChooseProcess() {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
startActivityForResult(Intent.createChooser(i, "test"), 0);
}
//選擇完成後的回調
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case 0:
if (null != uploadFile) {
Uri result = data == null || resultCode != RESULT_OK ? null
: data.getData();
uploadFile.onReceiveValue(result);
uploadFile = null;
Log.e("文件路徑:",result+"");
getFileType(getRealPathFromURI(result));
openFile(getRealPathFromURI(result));
}
if (null != uploadFiles) {
Uri result = data == null || resultCode != RESULT_OK ? null
: data.getData();
uploadFiles.onReceiveValue(new Uri[]{result});
uploadFiles = null;
Log.e("文件路徑:",result+"");
getFileType(getRealPathFromURI(result));
openFile(getRealPathFromURI(result));
}
break;
default:
break;
}
} else if (resultCode == RESULT_CANCELED) {
if (null != uploadFile) {
uploadFile.onReceiveValue(null);
uploadFile = null;
}
}
}
//uri轉成真實路徑
private String getRealPathFromURI(Uri contentURI) {
String result;
Cursor cursor = null;
try {
cursor = getContentResolver().query(contentURI, null, null, null, null);
} catch (Throwable e) {
e.printStackTrace();
}
if (cursor == null) {
result = contentURI.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
result = cursor.getString(idx);
cursor.close();
}
return result;
}
//打開doc相關文件的方法
private void openFile(String path) {
//通過bundle把文件傳給x5,打開的事情交由x5處理
Bundle bundle = new Bundle();
//傳遞文件路徑
bundle.putString("filePath", path);
//臨時的路徑
bundle.putString("tempPath", Environment.getExternalStorageDirectory() + File.separator + "temp");
TbsReaderView readerView = new TbsReaderView(this, new TbsReaderView.ReaderCallback() {
@Override
public void onCallBackAction(Integer integer, Object o, Object o1) {
}
});
//加載文件前的初始化工作,加載支持不同格式的插件
boolean b = readerView.preOpen(getFileType(path), false);
if (b) {
readerView.openFile(bundle);
}
// 往容器裏添加TbsReaderView控件
mReadFile.addView(readerView);
}
/***
* 獲取文件類型
*
* @param path 文件路徑
* @return 文件的格式
*/
private String getFileType(String path) {
String str = "";
if (TextUtils.isEmpty(path)) {
return str;
}
int i = path.lastIndexOf('.');
if (i <= -1) {
return str;
}
str = path.substring(i + 1);
return str;
}
/**
* 確保註銷配置能夠被釋放
*/
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
if (this.mTestView != null) {
mTestView.destroy();
}
super.onDestroy();
}
}
注意:WebView 、ValueCallback、TbsReaderView 等組件或方法都需要選擇TBS包下
8、在APPAplication中初始化TBS服務
//蒐集本地tbs內核信息並上報服務器,服務器返回結果決定使用哪個內核。
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);
使用TBS實現doc、pdf等多格式文檔在線閱讀 源碼