Skip to content

Commit e72b561

Browse files
luffyjetluffyjet
authored andcommitted
Initial commit
0 parents  commit e72b561

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+2726
-0
lines changed

.gitignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
*.iml
2+
.gradle
3+
/local.properties
4+
/.idea/workspace.xml
5+
/.idea/libraries
6+
.DS_Store
7+
/build
8+
/captures
9+
.externalNativeBuild
10+
/app/build
11+
/library/build
12+

.gitlab-ci.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
stages:
2+
- build
3+
- archive
4+
5+
build_project:
6+
stage: build
7+
script:
8+
- gradle clean
9+
10+
archive_project:
11+
stage: archive
12+
script:
13+
- gradle assembleRelease
14+
only:
15+
- master
16+
artifacts:
17+
paths:
18+
- app/build/outputs/apk/

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
## Android与JS通信桥接框架
2+
可以与[IOS版WebViewJavascriptBridge](https://github.com/marcuswestin/WebViewJavascriptBridge)公用一套前端JS代码

app/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

app/build.gradle

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
apply plugin: 'com.android.application'
2+
3+
android {
4+
compileSdkVersion Integer.parseInt(rootProject.android_compileSdkVersion)
5+
buildToolsVersion rootProject.android_buildToolsVersion
6+
7+
defaultConfig {
8+
applicationId rootProject.example_package
9+
minSdkVersion Integer.parseInt(rootProject.android_minSdkVersion)
10+
targetSdkVersion Integer.parseInt(rootProject.android_targetSdkVersion)
11+
versionCode Integer.parseInt(rootProject.android_versionCode)
12+
versionName rootProject.android_versionName
13+
}
14+
15+
16+
signingConfigs {
17+
release {
18+
storeFile file('keystore.jks')
19+
storePassword "123456"
20+
keyAlias "lzcapp"
21+
keyPassword "123456"
22+
v2SigningEnabled false//渠道包工具需要
23+
// MD5: BF:A5:17:1C:32:6C:9E:87:CB:3E:E9:57:11:70:EB:3F
24+
// SHA1: 5C:A3:C5:2C:A1:FA:DA:8C:E9:44:96:7D:79:B7:5B:4D:F8:7E:17:EE
25+
// SHA256: F9:6D:2F:90:F3:C4:1A:B4:C5:6B:87:FD:15:11:CE:EA:AE:65:AD:B5:84:6E:D6:A1:D7:2E:BA:80:FF:FC:ED:71
26+
// 签名算法名称: SHA256withRSA
27+
// 版本: 3
28+
}
29+
}
30+
31+
32+
buildTypes {
33+
release {
34+
// debuggable true
35+
minifyEnabled true
36+
shrinkResources false
37+
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
38+
signingConfig signingConfigs.release
39+
}
40+
}
41+
}
42+
43+
dependencies {
44+
compile fileTree(dir: 'libs', include: ['*.jar'])
45+
compile "com.android.support:appcompat-v7:${android_support}"
46+
compile "com.google.code.gson:gson:${android_gson}"
47+
compile project(':library')
48+
}

app/keystore.jks

2.16 KB
Binary file not shown.

app/proguard-rules.pro

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Add project specific ProGuard rules here.
2+
# By default, the flags in this file are appended to flags specified
3+
# in /Users/luffyjet/Documents/android-sdk/tools/proguard/proguard-android.txt
4+
# You can edit the include path and order by changing the proguardFiles
5+
# directive in build.gradle.
6+
#
7+
# For more details, see
8+
# http://developer.android.com/guide/developing/tools/proguard.html
9+
10+
# Add any project specific keep options here:
11+
12+
# If your project uses WebView with JS, uncomment the following
13+
# and specify the fully qualified class name to the JavaScript interface
14+
# class:
15+
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16+
# public *;
17+
#}

app/src/main/AndroidManifest.xml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest package="com.luffyjet.jsbridgeexample"
3+
xmlns:android="http://schemas.android.com/apk/res/android">
4+
<uses-permission android:name="android.permission.INTERNET"/>
5+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
6+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
7+
8+
9+
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
10+
11+
<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS"/>
12+
13+
<uses-permission android:name="android.permission.ACCESS_GPS"/>
14+
15+
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
16+
17+
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
18+
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
19+
20+
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
21+
22+
<uses-permission android:name="android.permission.BROADCAST_STICKY"/>
23+
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
24+
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
25+
26+
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
27+
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
28+
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
29+
<uses-permission android:name="android.permission.GET_TASKS"/>
30+
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
31+
<uses-permission android:name="android.permission.READ_LOGS"/>
32+
33+
<application
34+
android:allowBackup="true"
35+
android:icon="@mipmap/ic_launcher"
36+
android:label="@string/app_name"
37+
android:supportsRtl="true"
38+
android:theme="@style/AppTheme">
39+
<activity android:name=".MainActivity">
40+
<intent-filter>
41+
<action android:name="android.intent.action.MAIN"/>
42+
43+
<category android:name="android.intent.category.LAUNCHER"/>
44+
</intent-filter>
45+
</activity>
46+
</application>
47+
48+
</manifest>
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<!doctype html>
2+
<html>
3+
4+
<head>
5+
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0">
6+
<style type='text/css'>
7+
html {
8+
font-family: Helvetica;
9+
color: #222;
10+
}
11+
12+
h1 {
13+
color: steelblue;
14+
font-size: 24px;
15+
margin-top: 24px;
16+
}
17+
18+
button {
19+
margin: 0 3px 10px;
20+
font-size: 12px;
21+
}
22+
23+
.logLine {
24+
border-bottom: 1px solid #ccc;
25+
padding: 4px 2px;
26+
font-family: courier;
27+
font-size: 11px;
28+
}
29+
</style>
30+
31+
<script src="js/ccnativeapi.js" type="text/javascript" charset="utf-8"></script>
32+
33+
<script type="text/javascript">
34+
//测试代码----------------------
35+
var uniqueId = 1;
36+
37+
function log(message, data) {
38+
var log = document.getElementById('log');
39+
40+
var el = document.createElement('div');
41+
42+
el.className = 'logLine';
43+
44+
el.innerHTML = uniqueId++ + '. ' + message + ':<br/>' + JSON.stringify(data);
45+
46+
if(log.children.length) {
47+
log.insertBefore(el, log.children[0]);
48+
} else {
49+
log.appendChild(el);
50+
}
51+
}
52+
//--------------------
53+
54+
function scanQr() {
55+
ccapi.scanQRCode({
56+
needResult: 1, // 默认为0,扫描结果由app处理,1则直接返回扫描结果,
57+
58+
scanType: ["qrCode", "barCode"], // 可以指定扫二维码还是一维码,默认二者都有
59+
60+
success: function(res) {
61+
var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
62+
63+
console.log("scan response: " + result);
64+
console.log("scan response: " + JSON.stringify(res));
65+
log('Native responding with ', result);
66+
}
67+
});
68+
}
69+
70+
function chooseImage() {
71+
ccapi.chooseImage({
72+
count: 1, // 默认9
73+
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
74+
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
75+
success: function(res) {
76+
var localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
77+
console.log("chooseImage response: " + localIds.toString());
78+
console.log("chooseImage response all: " + JSON.stringify(res));
79+
var imgTag = document.getElementById("ts_img");
80+
imgTag.src = localIds[0];
81+
log('Native responding with ', res);
82+
}
83+
});
84+
}
85+
86+
87+
function deviceInfo() {
88+
ccapi.deviceInfo({
89+
full: false, // 可以指定全部获取,还是只要基本信息,默认全部
90+
success: function(res) {
91+
// var data = JSON.parse(res);
92+
console.log("appName: " + res.appName);
93+
console.log("appVersion: " + res.appVersion);
94+
console.log("all: " + JSON.stringify(res));
95+
log('Native responding with ', res);
96+
}
97+
});
98+
}
99+
</script>
100+
</head>
101+
102+
<body>
103+
<h1>WebViewJavascriptBridge Demo</h1>
104+
<div id='buttons'></div>
105+
<div id='log'></div>
106+
107+
<input type="button" id="scan" value="扫码" onclick="scanQr()" />
108+
<input type="button" id="chooseimg" value="选图" onclick="chooseImage()" />
109+
<input type="button" id="deviceinfo" value="设备信息" onclick="deviceInfo()" />
110+
111+
<img src="" id="ts_img" width="100%" height="auto"/>
112+
</body>
113+
114+
</html>
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
;(function() {
2+
window.onerror = function(err) {
3+
console.log("page on error:" + err);
4+
};
5+
6+
var browserType = {
7+
types: function() {
8+
var u = window.navigator.userAgent,
9+
app = window.navigator.appVersion;
10+
return { //移动终端浏览器版本信息
11+
trident: u.indexOf('Trident') > -1, //IE内核
12+
presto: u.indexOf('Presto') > -1, //opera内核
13+
webKit: u.indexOf('AppleWebKit') > -1, //苹果、谷歌内核
14+
gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, //火狐内核
15+
mobile: !!u.match(/AppleWebKit.*Mobile.*/) || !!u.match(/AppleWebKit/), //是否为移动终端
16+
mac: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios终端
17+
android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, //android终端或者uc浏览器
18+
iPhone: u.indexOf('iPhone') > -1 || u.indexOf('Mac') > -1, //是否为iPhone或者QQHD浏览器
19+
iPad: u.indexOf('iPad') > -1, //是否iPad
20+
webApp: u.indexOf('Safari') == -1 //是否web应该程序,没有头部与底部
21+
22+
};
23+
}(),
24+
25+
language: (window.navigator.browserLanguage || window.navigator.language).toLowerCase()
26+
};
27+
28+
function setupWebViewJavascriptBridge(callback) {
29+
if(window.WebViewJavascriptBridge) {
30+
return callback(WebViewJavascriptBridge);
31+
}
32+
if(window.WVJBCallbacks) {
33+
return window.WVJBCallbacks.push(callback);
34+
}
35+
window.WVJBCallbacks = [callback];
36+
var WVJBIframe = document.createElement('iframe');
37+
WVJBIframe.style.display = 'none';
38+
if(browserType.types.android) {
39+
WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
40+
} else if(browserType.types.mac || browserType.types.iPhone || browserType.types.iPad) {
41+
WVJBIframe.src = 'https://__bridge_loaded__';
42+
}
43+
document.documentElement.appendChild(WVJBIframe);
44+
setTimeout(function() {
45+
document.documentElement.removeChild(WVJBIframe)
46+
}, 0);
47+
}
48+
49+
function invoke(handlerName, data, callback) {
50+
if(window.WebViewJavascriptBridge) {
51+
window.WebViewJavascriptBridge.callHandler(handlerName, data, callback);
52+
} else {
53+
document.addEventListener(
54+
'WebViewJavascriptBridgeReady',
55+
function() {
56+
window.WebViewJavascriptBridge.callHandler(handlerName, data, callback);
57+
},
58+
false
59+
);
60+
}
61+
}
62+
63+
setupWebViewJavascriptBridge(function(bridge) {
64+
bridge.registerHandler('NativeCallJS', function(data, responseCallback) {
65+
var responseData = {
66+
'Javascript Says': 'Right back atcha!'
67+
};
68+
responseCallback(responseData);
69+
});
70+
71+
var doc = document;
72+
var readyEvent = doc.createEvent('Events');
73+
readyEvent.initEvent('WebViewJavascriptBridgeReady');
74+
readyEvent.bridge = WebViewJavascriptBridge;
75+
doc.dispatchEvent(readyEvent);
76+
});
77+
78+
79+
window.ccapi = {
80+
//设备信息
81+
deviceInfo: function(data) {
82+
invoke("deviceInfo", {
83+
'full': data.full
84+
}, data.success);
85+
},
86+
87+
//扫二维码
88+
scanQRCode: function(data) {
89+
invoke("scanQRCode", {
90+
'needResult': data.needResult,
91+
'scanType': data.scanType
92+
}, data.success);
93+
},
94+
//选择图片
95+
chooseImage: function(data) {
96+
invoke("chooseImage", {
97+
'count': data.count,
98+
'sizeType': data.sizeType,
99+
'sourceType': data.sourceType
100+
}, data.success);
101+
}
102+
103+
};
104+
})();

0 commit comments

Comments
 (0)