開發插件
編寫 Android 原生代碼
下載 openinstall SDK 並將 jar 包拷貝到項目的 libs 目錄。創建一個 package
,如 com.wenkiwu.hbuilder.openinstall
;在包中新建一個類繼承自 StandardFeature
,然后對應openinstall的接口定義相應的功能方法。完整代碼如下:
package com.wenkiwu.hbuilder.openinstall;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import com.fm.openinstall.OpenInstall;
import com.fm.openinstall.listener.AppInstallAdapter;
import com.fm.openinstall.listener.AppWakeUpAdapter;
import com.fm.openinstall.model.AppData;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import io.dcloud.common.DHInterface.ISysEventListener;
import io.dcloud.common.DHInterface.IWebview;
import io.dcloud.common.DHInterface.StandardFeature;
import io.dcloud.common.util.JSUtil;
public class OpenInstallApiManager extends StandardFeature {
private static final String TAG = "OpenInstallApiManager";
private IWebview webview = null;
private String wakeupCallBackID = null;
@Override
public void onStart(Context context, Bundle bundle, String[] strings) {
super.onStart(context, bundle, strings);
Log.d(TAG, "init");
OpenInstall.init(context);
}
public void registerWakeUpHandler(final IWebview pWebview, JSONArray array) {
Log.d(TAG, "registerWakeUpHandler");
String callBackID = array.optString(0);
webview = pWebview;
wakeupCallBackID = callBackID;
// 自己注冊監聽並處理 onNewIntent 事件
pWebview.obtainApp().registerSysEventListener(new ISysEventListener() {
@Override
public boolean onExecute(SysEventType sysEventType, Object o) {
if (sysEventType == SysEventType.onNewIntent) {
String dataString = (String) o;
Intent intent = new Intent();
intent.setData(Uri.parse(dataString));
if (webview != null && wakeupCallBackID != null) {
getWakeUp(intent, webview, wakeupCallBackID);
}
}
return false;
}
}, SysEventType.onNewIntent);
Intent intent = pWebview.getActivity().getIntent();
if (intent == null || TextUtils.isEmpty(intent.getDataString())) {
return;
}
getWakeUp(intent, pWebview, callBackID);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
// 5+sdk 的 bug 導致 onNewIntent 未被回調
// if (webview != null && wakeupCallBackID != null) {
// getWakeUp(intent, webview, wakeupCallBackID);
// }
}
private void getWakeUp(Intent intent, final IWebview pWebview, final String callBackID) {
OpenInstall.getWakeUp(intent, new AppWakeUpAdapter() {
@Override
public void onWakeUp(AppData appData) {
JSONObject dataJson = new JSONObject();
try {
dataJson.put("channelCode", appData.getChannel());
dataJson.put("bindData", appData.getData());
} catch (JSONException e) {
e.printStackTrace();
}
JSUtil.execCallback(pWebview, callBackID, dataJson, JSUtil.OK, false);
}
});
}
public void getInstall(final IWebview pWebview, JSONArray array) {
Log.d(TAG, "getInstall");
final String callBackID = array.optString(0);
int timeout = -1;
if (array.isNull(1)) {
timeout = array.optInt(1);
}
OpenInstall.getInstall(new AppInstallAdapter() {
@Override
public void onInstall(AppData appData) {
JSONObject dataJson = new JSONObject();
try {
dataJson.put("channelCode", appData.getChannel());
dataJson.put("bindData", appData.getData());
} catch (JSONException e) {
e.printStackTrace();
}
JSUtil.execCallback(pWebview, callBackID, dataJson, JSUtil.OK, false);
}
}, timeout * 1000);
}
public void reportRegister(IWebview pWebview, JSONArray array) {
Log.d(TAG, "reportRegister");
OpenInstall.reportRegister();
}
public void reportEffectPoint(IWebview pWebview, JSONArray array) {
Log.d(TAG, "reportEffectPoint");
String pointId = array.optString(0);
long pointValue = array.optLong(1);
OpenInstall.reportEffectPoint(pointId, pointValue);
}
}
封裝插件的 JS
在前端代碼的 js 文件夾中,新建 openinstall.js
,編寫代碼,通過 plus.bridge
調用 Native 層的方法
document.addEventListener( "plusready", function(){
var _BARCODE = 'openinstall',
B = window.plus.bridge;
var openinstall = {
//注冊拉起回調
registerWakeUpHandler: function (successCallback) {
var success = typeof successCallback !== 'function' ? null : function(args) {
successCallback(args);
},
callbackID = B.callbackId(success, null);
return B.exec(_BARCODE, "registerWakeUpHandler", [callbackID]);
},
// 獲取安裝來源數據
getInstall : function (successCallback, timeout) {
var success = typeof successCallback !== 'function' ? null : function(args) {
successCallback(args);
},
callbackID = B.callbackId(success, null);
return B.exec(_BARCODE, "getInstall", [callbackID, timeout]);
},
// 注冊上報
reportRegister : function () {
return B.exec(_BARCODE, "reportRegister", []);
},
// 上報渠道效果
reportEffectPoint : function (pointId, pointValue) {
return B.exec(_BARCODE, "reportEffectPoint", [pointId, pointValue]);
}
};
window.plus.openinstall = openinstall;
}, true );
集成插件
關聯 JS 插件名和 Android 原生類
修改項目的 src/main/assets/data/
目錄下的 dcloud_properties.xml
文件,指定 JS 對象名稱和 Android 的類名對應關系,以便 H5+ SDK 根據對應的 JS 名查找並生成相應的 Native 對象執行對應的邏輯
<properties>
<features>
<!-- more feature -->
<!-- openinstall plugin -->
<feature name="openinstall" value="com.wenkiwu.hbuilder.openinstall.OpenInstallApiManager"/>
</features>
<services>
<!-- openinstall需要在程序啟動時初始化 -->
<service name="openinstall" value="com.wenkiwu.hbuilder.openinstall.OpenInstallApiManager"/>
<!-- more service -->
</services>
</properties>
在應用的 manifest.json 文件中還需要添加擴展插件的應用使用權限
{
"@platforms": [
"android",
"iPhone",
"iPad"
],
"id": "H5E1BA598",
"name": "OpenInstallPlugin",
// ...
"permissions": {
"Console": {
"description": "跟蹤調試輸出日志"
},
"Events": {
"description": "應用擴展事件"
},
// openinstall plugin
"openinstall": {
"description": "openinstall插件"
}
},
// ...
}
openinstall 的配置
根據openinstall官方文檔,在 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.INTERNET"/>
配置 AppKey 和 scheme
<application
android:allowBackup="false"
android:allowClearUserData="true"
android:icon="@drawable/icon"
android:label="@string/app_name"
android:largeHeap="true"
android:supportsRtl="true">
<!-- openinstall appkey 配置 -->
<meta-data
android:name="com.openinstall.APP_KEY"
android:value="OPENINSTALL_APPKEY"/>
<activity
android:name="io.dcloud.PandoraEntry"
android:configChanges="orientation|keyboardHidden|screenSize|mcc|mnc|fontScale"
android:hardwareAccelerated="true"
android:screenOrientation="user"
android:theme="@style/TranslucentTheme"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<!-- opeinstall scheme 配置 -->
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="OPENINSTALL_SCHEME"/>
</intent-filter>
</activity>
</application>
網頁中 JS 調用示例
引入 JS 文件
<script type="text/javascript" src="./js/openinstall.js"></script>
獲取 scheme 喚醒數據
在應用啟動時,注冊喚醒回調。這樣當 App 被喚醒時,會回調傳入的方法,並在回調中獲取喚醒數據
document.addEventListener('plusready',function(){
plus.openinstall.registerWakeUpHandler(function(data){
console.log("wakeup : channelCode= "
+ data.channelCode + ", bindData=" + data.bindData);
alert("wakeup : channelCode= " + data.channelCode + ", bindData=" + data.bindData);
});
},false);
獲取安裝來源數據
在需要獲取安裝來源數據時,調用以下代碼,在回調中獲取參數
function getInstall(){
plus.openinstall.getInstall(function(data){
console.log("getInstall : channelCode= "
+ data.channelCode + ", bindData=" + data.bindData);
}, 8);
}
其他統計代碼
用戶注冊成功后,調用以下代碼,上報注冊統計
function reportRegister(){
plus.openinstall.reportRegister();
}
統計終端用戶對某些特殊業務的使用效果,如充值金額,分享次數等等,調用以下代碼
function reportEffectPoint(){
plus.openinstall.reportEffectPoint("effect_test", 1);
}
**openinstall 官方已提供 hbuilder 集成插件 [openinstall-hbuilder-sdk](https://github.com/OpenInstall/openinstall-hbuilder-sdk),包含了iOS和Android兩個平台**