callback);
51 | }
52 |
53 |
54 | }
55 |
56 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/just/agentweb/sample/activity/WebActivity.java:
--------------------------------------------------------------------------------
1 | package com.just.agentweb.sample.activity;
2 |
3 | /**
4 | * Created by cenxiaozhong on 2017/5/22.
5 | *
6 | *
7 | */
8 |
9 | public class WebActivity extends BaseWebActivity {
10 |
11 | @Override
12 | public String getUrl() {
13 | return super.getUrl();
14 | }
15 |
16 | @Override
17 | protected void onStart() {
18 | super.onStart();
19 | }
20 |
21 | @Override
22 | protected void onResume() {
23 | super.onResume();
24 |
25 | //测试Cookies
26 | /*try {
27 |
28 | String targetUrl="";
29 | Log.i("Info","cookies:"+ AgentWebConfig.getCookiesByUrl(targetUrl="http://www.jd.com"));
30 | AgentWebConfig.removeAllCookies(new ValueCallback() {
31 | @Override
32 | public void onReceiveValue(Boolean value) {
33 | Log.i("Info","onResume():"+value);
34 | }
35 | });
36 |
37 | String tagInfo=AgentWebConfig.getCookiesByUrl(targetUrl);
38 | Log.i("Info","tag:"+tagInfo);
39 | AgentWebConfig.syncCookie("http://www.jd.com","ID=IDHl3NVU0N3ltZm9OWHhubHVQZW1BRThLdGhLaFc5TnVtQWd1S2g1REcwNVhTS3RXQVFBQEBFDA984906B62C444931EA0");
40 | String tag=AgentWebConfig.getCookiesByUrl(targetUrl);
41 | Log.i("Info","tag:"+tag);
42 | AgentWebConfig.removeSessionCookies();
43 | Log.i("Info","removeSessionCookies:"+AgentWebConfig.getCookiesByUrl(targetUrl));
44 | } catch (Exception e){
45 | e.printStackTrace();
46 | }*/
47 |
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/sample/src/main/assets/sms/sms.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | 电话短信邮件
9 |
10 |
32 |
33 |
34 |
35 | 电话短信邮件跳转
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
54 | 电话
55 | 短信
56 | 邮件
57 | 打开应用内部页面
58 | 打开微信
59 |
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/agentweb-core/src/main/java/com/just/agentweb/WebSecurityControllerImpl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) Justson(https://github.com/Justson/AgentWeb)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.just.agentweb;
18 |
19 | import android.os.Build;
20 | import androidx.collection.ArrayMap;
21 | import android.webkit.WebView;
22 |
23 |
24 | /**
25 | * @author cenxiaozhong
26 | */
27 | public class WebSecurityControllerImpl implements WebSecurityController {
28 |
29 | private WebView mWebView;
30 | private ArrayMap mMap;
31 | private AgentWeb.SecurityType mSecurityType;
32 |
33 | public WebSecurityControllerImpl(WebView view, ArrayMap map, AgentWeb.SecurityType securityType) {
34 | this.mWebView = view;
35 | this.mMap = map;
36 | this.mSecurityType = securityType;
37 | }
38 |
39 | @Override
40 | public void check(WebSecurityCheckLogic webSecurityCheckLogic) {
41 | if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
42 | webSecurityCheckLogic.dealHoneyComb(mWebView);
43 | }
44 | if (mMap != null && mSecurityType == AgentWeb.SecurityType.STRICT_CHECK && !mMap.isEmpty()) {
45 | webSecurityCheckLogic.dealJsInterface(mMap, mSecurityType);
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/agentweb-core/src/main/java/com/just/agentweb/BaseIndicatorView.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) Justson(https://github.com/Justson/AgentWeb)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.just.agentweb;
18 |
19 | import android.content.Context;
20 | import androidx.annotation.Nullable;
21 | import android.util.AttributeSet;
22 | import android.widget.FrameLayout;
23 |
24 |
25 | /**
26 | * @author cenxiaozhong
27 | * @date 2017/5/12
28 | * @since 1.0.0
29 | */
30 | public abstract class BaseIndicatorView extends FrameLayout implements BaseIndicatorSpec,LayoutParamsOffer{
31 | public BaseIndicatorView(Context context) {
32 | super(context);
33 | }
34 |
35 | public BaseIndicatorView(Context context, @Nullable AttributeSet attrs) {
36 | super(context, attrs);
37 | }
38 |
39 | public BaseIndicatorView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
40 | super(context, attrs, defStyleAttr);
41 | }
42 |
43 | @Override
44 | public void reset() {
45 | }
46 |
47 | @Override
48 | public void setProgress(int newProgress) {
49 | }
50 |
51 | @Override
52 | public void show() {
53 | }
54 |
55 | @Override
56 | public void hide() {
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/agentweb-core/src/main/java/com/just/agentweb/MiddlewareWebChromeBase.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) Justson(https://github.com/Justson/AgentWeb)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.just.agentweb;
18 |
19 | import android.webkit.WebChromeClient;
20 |
21 | /**
22 | * @author cenxiaozhong
23 | * @date 2017/12/16
24 | * @since 3.0.0
25 | */
26 | public class MiddlewareWebChromeBase extends WebChromeClientDelegate {
27 |
28 | private MiddlewareWebChromeBase mMiddlewareWebChromeBase;
29 |
30 | protected MiddlewareWebChromeBase(WebChromeClient webChromeClient) {
31 | super(webChromeClient);
32 | }
33 |
34 | protected MiddlewareWebChromeBase() {
35 | super(null);
36 | }
37 |
38 | @Override
39 | final void setDelegate(WebChromeClient delegate) {
40 | super.setDelegate(delegate);
41 | }
42 |
43 | final MiddlewareWebChromeBase enq(MiddlewareWebChromeBase middlewareWebChromeBase) {
44 | setDelegate(middlewareWebChromeBase);
45 | this.mMiddlewareWebChromeBase = middlewareWebChromeBase;
46 | return this.mMiddlewareWebChromeBase;
47 | }
48 |
49 |
50 | final MiddlewareWebChromeBase next() {
51 | return this.mMiddlewareWebChromeBase;
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/agentweb-core/src/main/java/com/just/agentweb/LollipopFixedWebView.java:
--------------------------------------------------------------------------------
1 | package com.just.agentweb;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.Context;
5 | import android.content.res.Configuration;
6 | import android.os.Build;
7 | import android.util.AttributeSet;
8 | import android.webkit.WebView;
9 |
10 | /**
11 | * 修复 Android 5.0 & 5.1 打开 WebView 闪退问题:
12 | * 参阅 https://stackoverflow.com/questions/41025200/android-view-inflateexception-error-inflating-class-android-webkit-webview
13 | */
14 | @SuppressWarnings("unused")
15 | public class LollipopFixedWebView extends WebView {
16 | public LollipopFixedWebView(Context context) {
17 | super(getFixedContext(context));
18 | }
19 |
20 | public LollipopFixedWebView(Context context, AttributeSet attrs) {
21 | super(getFixedContext(context), attrs);
22 | }
23 |
24 | public LollipopFixedWebView(Context context, AttributeSet attrs, int defStyleAttr) {
25 | super(getFixedContext(context), attrs, defStyleAttr);
26 | }
27 |
28 | @TargetApi(Build.VERSION_CODES.LOLLIPOP)
29 | public LollipopFixedWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
30 | super(getFixedContext(context), attrs, defStyleAttr, defStyleRes);
31 | }
32 |
33 | public LollipopFixedWebView(Context context, AttributeSet attrs, int defStyleAttr, boolean privateBrowsing) {
34 | super(getFixedContext(context), attrs, defStyleAttr, privateBrowsing);
35 | }
36 |
37 | public static Context getFixedContext(Context context) {
38 | if (Build.VERSION.SDK_INT >= 21 && Build.VERSION.SDK_INT < 23) {
39 | // Avoid crashing on Android 5 and 6 (API level 21 to 23)
40 | return context.createConfigurationContext(new Configuration());
41 | }
42 | return context;
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/agentweb-filechooser/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'maven-publish'
3 |
4 | android {
5 | compileSdk COMPILE_SDK_VERSION.toInteger()
6 |
7 | defaultConfig {
8 | minSdkVersion 14
9 | namespace 'com.just.agentweb.filechooser'
10 | targetSdkVersion TARGET_SDK_VERSION.toInteger()
11 | versionCode 2
12 | versionName VERSION_NAME
13 |
14 | testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
15 |
16 | }
17 |
18 | compileOptions {
19 | sourceCompatibility JavaVersion.VERSION_1_8
20 | targetCompatibility JavaVersion.VERSION_1_8
21 | }
22 |
23 | buildTypes {
24 | release {
25 | minifyEnabled false
26 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
27 | }
28 | }
29 | lintOptions{
30 | abortOnError false
31 | }
32 |
33 | }
34 |
35 | dependencies {
36 | implementation fileTree(include: ['*.jar'], dir: 'libs')
37 | testImplementation 'junit:junit:4.12'
38 | androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', {
39 | exclude group: 'com.android.support', module: 'support-annotations'
40 | })
41 | testImplementation 'junit:junit:4.12'
42 | compileOnly 'com.google.android.material:material:1.0.0'
43 | compileOnly 'androidx.legacy:legacy-support-v4:1.0.0'
44 | implementation project(':agentweb-core')
45 | }
46 |
47 | afterEvaluate {
48 | publishing {
49 | publications {
50 | // Creates a Maven publication called "release".
51 | release(MavenPublication) {
52 | groupId = 'com.github.Justson.AgentWeb'
53 | artifactId = 'agentweb-filechooser'
54 | version = 'v5.0.7-androidx'
55 | }
56 | }
57 | }
58 | }
--------------------------------------------------------------------------------
/agentweb-core/src/main/res/values-zh/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 该任务已经存在 , 请勿重复点击下载!
3 | 提示
4 | 您正在使用手机流量 , 继续下载该文件吗?
5 | 下载
6 | 取消
7 | 下载失败!
8 | 当前进度:%s
9 | 已下载:%s
10 | 您有一条新通知
11 | 文件下载
12 | 点击打开
13 | 即将开始下载文件
14 | 相机
15 | 文件
16 | 加载中 ...
17 | 您需要离开%s前往其他应用吗?
18 | 离开
19 | 证书颁发机构不受信任,
20 | 选择的文件不能大于%sMB
21 | 出错啦! 点击空白处刷新 ~
22 | 证书已过期,
23 | 证书主机名不匹配,
24 | 该证书尚未生效,
25 | SSL 认证错误,
26 | 你确定要访问该网页吗?
27 | SSL 认证错误
28 | 确定
29 |
30 |
--------------------------------------------------------------------------------
/agentweb-core/src/main/java/com/just/agentweb/DefaultWebLifeCycleImpl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) Justson(https://github.com/Justson/AgentWeb)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.just.agentweb;
18 |
19 | import android.os.Build;
20 | import android.webkit.WebView;
21 |
22 | /**
23 | * @author cenxiaozhong
24 | * @date 2017/6/3
25 | * @since 2.0.0
26 | */
27 | public class DefaultWebLifeCycleImpl implements WebLifeCycle {
28 | private WebView mWebView;
29 | DefaultWebLifeCycleImpl(WebView webView) {
30 | this.mWebView = webView;
31 | }
32 |
33 | @Override
34 | public void onResume() {
35 | if (this.mWebView != null) {
36 | if (Build.VERSION.SDK_INT >= 11){
37 | this.mWebView.onResume();
38 | }
39 | this.mWebView.resumeTimers();
40 | }
41 | }
42 |
43 | @Override
44 | public void onPause() {
45 | if (this.mWebView != null) {
46 | if (Build.VERSION.SDK_INT >= 11){
47 | this.mWebView.onPause();
48 | }
49 | this.mWebView.pauseTimers();
50 | }
51 | }
52 |
53 | @Override
54 | public void onDestroy() {
55 | if(this.mWebView!=null){
56 | this.mWebView.resumeTimers();
57 | }
58 | AgentWebUtils.clearWebView(this.mWebView);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/just/agentweb/sample/client/MiddlewareWebViewClient.java:
--------------------------------------------------------------------------------
1 | package com.just.agentweb.sample.client;
2 |
3 | import android.util.Log;
4 | import android.webkit.WebResourceRequest;
5 | import android.webkit.WebView;
6 |
7 | import com.just.agentweb.MiddlewareWebClientBase;
8 |
9 | /**
10 | * Created by cenxiaozhong on 2017/12/16.
11 | *
12 | *
13 | * 方法的执行顺序,例如下面用了7个中间件一个 WebViewClient
14 | *
15 | * .useMiddlewareWebClient(getMiddlewareWebClient()) // 1
16 | * .useMiddlewareWebClient(getMiddlewareWebClient()) // 2
17 | * .useMiddlewareWebClient(getMiddlewareWebClient()) // 3
18 | * .useMiddlewareWebClient(getMiddlewareWebClient()) // 4
19 | * .useMiddlewareWebClient(getMiddlewareWebClient()) // 5
20 | * .useMiddlewareWebClient(getMiddlewareWebClient()) // 6
21 | * .useMiddlewareWebClient(getMiddlewareWebClient()) // 7
22 | * DefaultWebClient // 8
23 | * .setWebViewClient(mWebViewClient) // 9
24 | *
25 | *
26 | * 典型的洋葱模型
27 | * 对象内部的方法执行顺序: 1->2->3->4->5->6->7->8->9->8->7->6->5->4->3->2->1
28 | *
29 | *
30 | * 中断中间件的执行, 删除super.methodName(...) 这行即可
31 | *
32 | */
33 |
34 | public class MiddlewareWebViewClient extends MiddlewareWebClientBase {
35 |
36 | public MiddlewareWebViewClient() {
37 | }
38 |
39 | private static int count = 1;
40 |
41 | @Override
42 | public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
43 | Log.i("Info", "MiddlewareWebViewClient -- > shouldOverrideUrlLoading:" + request.getUrl().toString() + " c:" + (count++));
44 | return super.shouldOverrideUrlLoading(view, request);
45 |
46 | }
47 |
48 | @Override
49 | public boolean shouldOverrideUrlLoading(WebView view, String url) {
50 | Log.i("Info", "MiddlewareWebViewClient -- > shouldOverrideUrlLoading:" + url + " c:" + (count++));
51 | return super.shouldOverrideUrlLoading(view, url);
52 |
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/just/agentweb/sample/app/App.java:
--------------------------------------------------------------------------------
1 | package com.just.agentweb.sample.app;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 | import android.content.Intent;
6 |
7 | import com.just.agentweb.AgentWebCompat;
8 | import com.just.agentweb.sample.service.WebService;
9 | import com.queue.library.GlobalQueue;
10 |
11 | /**
12 | * Created by cenxiaozhong on 2017/5/23.
13 | * source code https://github.com/Justson/AgentWeb
14 | */
15 |
16 | public class App extends Application {
17 |
18 | @Override
19 | public void onCreate() {
20 | super.onCreate();
21 |
22 | /**
23 | * 说明, WebView 初处初始化耗时 250ms 左右。
24 | * 提前初始化WebView ,好处可以提升页面初始化速度,减少白屏时间,
25 | * 坏处,拖慢了App 冷启动速度,如果 WebView 配合 VasSonic 使用,
26 | * 建议不要在此处提前初始化 WebView 。
27 | */
28 | // WebView mWebView=new WebView(new MutableContextWrapper(this));
29 |
30 | // if (LeakCanary.isInAnalyzerProcess(this)) {
31 | // // This process is dedicated to LeakCanary for heap analysis.
32 | // // You should not init your app in this process.
33 | // return;
34 | // }
35 | // LeakCanary.install(this);
36 | // Normal app init code...
37 |
38 | //implementation 'com.github.Justson:dispatch-queue:v1.0.5'
39 | GlobalQueue.getMainQueue().postRunnableInIdleRunning(new Runnable() {
40 | @Override
41 | public void run() {
42 | try {
43 | startService(new Intent(App.this, WebService.class));
44 | } catch (Throwable throwable) {
45 |
46 | }
47 | }
48 | });
49 | }
50 |
51 | public static Context mContext;
52 |
53 | @Override
54 | protected void attachBaseContext(Context base) {
55 | super.attachBaseContext(base);
56 | mContext = base;
57 | AgentWebCompat.setDataDirectorySuffix(base);
58 | }
59 |
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/agentweb-core/src/main/java/com/just/agentweb/LogUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) Justson(https://github.com/Justson/AgentWeb)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.just.agentweb;
18 |
19 | import android.util.Log;
20 |
21 | /**
22 | * @author cenxiaozhong
23 | * @date 2017/5/28
24 | * @since 1.0.0
25 | */
26 | class LogUtils {
27 |
28 | private static final String PREFIX = "agentweb-";
29 |
30 | static boolean isDebug() {
31 | return AgentWebConfig.DEBUG;
32 | }
33 |
34 | static void i(String tag, String message) {
35 |
36 | if (isDebug()) {
37 | Log.i(PREFIX.concat(tag), message);
38 | }
39 | }
40 |
41 | static void v(String tag, String message) {
42 |
43 | if (isDebug()) {
44 | Log.v(PREFIX.concat(tag), message);
45 | }
46 |
47 | }
48 |
49 | static void safeCheckCrash(String tag, String msg, Throwable tr) {
50 | if (isDebug()) {
51 | throw new RuntimeException(PREFIX.concat(tag) + " " + msg, tr);
52 | } else {
53 | Log.e(PREFIX.concat(tag), msg, tr);
54 | }
55 | }
56 |
57 | static void e(String tag, String msg, Throwable tr) {
58 | Log.e(tag, msg, tr);
59 | }
60 |
61 | static void e(String tag, String message) {
62 |
63 | if (isDebug()) {
64 | Log.e(PREFIX.concat(tag), message);
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/sample/src/main/assets/js_interaction/button.css:
--------------------------------------------------------------------------------
1 |
2 | .button {
3 | color: #666;
4 | background-color: #EEE;
5 | border-color: #EEE;
6 | font-weight: 300;
7 | font-size: 16px;
8 | font-family: "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
9 | text-decoration: none;
10 | text-align: center;
11 | line-height: 40px;
12 | height: 40px;
13 | padding: 0 40px;
14 | margin: 0;
15 | display: inline-block;
16 | appearance: none;
17 | cursor: pointer;
18 | border: none;
19 | -webkit-box-sizing: border-box;
20 | -moz-box-sizing: border-box;
21 | box-sizing: border-box;
22 | -webkit-transition-property: all;
23 | transition-property: all;
24 | -webkit-transition-duration: .3s;
25 | transition-duration: .3s;
26 | /*
27 | * Disabled State
28 | *
29 | * The disabled state uses the class .disabled, is-disabled,
30 | * and the form attribute disabled="disabled".
31 | * The use of !important is only added because this is a state
32 | * that must be applied to all buttons when in a disabled state.
33 | */ }
34 |
35 | .button-glow {
36 | -webkit-animation-duration: 3s;
37 | animation-duration: 3s;
38 | -webkit-animation-iteration-count: infinite;
39 | animation-iteration-count: infinite;
40 | -webkit-animation-name: glowing;
41 | animation-name: glowing; }
42 |
43 | .button-rounded {
44 | border-radius: 4px; }
45 |
46 | /*
47 | * Base Colors
48 | *
49 | * Create colors for buttons
50 | * (.button-primary, .button-secondary, etc.)
51 | */
52 | .button-primary,
53 | .button-primary-flat {
54 | background-color: #1B9AF7;
55 | border-color: #1B9AF7;
56 | color: #FFF; }
57 |
58 | /*
59 | * Border Buttons
60 | *
61 | * These buttons have no fill they only have a
62 | * border to define their hit target.
63 | */
64 | .button-border, .button-border-thin, .button-border-thick {
65 | background: none;
66 | border-width: 2px;
67 | border-style: solid;
68 | line-height: 36px; }
69 |
70 |
--------------------------------------------------------------------------------
/agentweb-core/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'maven-publish'
3 |
4 | android {
5 | compileSdk COMPILE_SDK_VERSION.toInteger()
6 |
7 |
8 | defaultConfig {
9 | minSdkVersion 14
10 | targetSdkVersion TARGET_SDK_VERSION.toInteger()
11 | namespace 'com.just.agentweb'
12 | versionCode 3
13 | versionName VERSION_NAME
14 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
15 | testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
16 |
17 | }
18 |
19 | buildTypes {
20 | release {
21 | minifyEnabled true
22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 | lintOptions {
26 | abortOnError false
27 | }
28 | repositories {
29 | flatDir {
30 | dirs 'libs', 'providedLibs'
31 | }
32 | }
33 | compileOptions {
34 | sourceCompatibility JavaVersion.VERSION_1_8
35 | targetCompatibility JavaVersion.VERSION_1_8
36 | }
37 | // defaultPublishConfig "debug"
38 | }
39 |
40 | dependencies {
41 | compileOnly fileTree(include: ['*.jar'], dir: 'libs')
42 | androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', {
43 | exclude group: 'com.android.support', module: 'support-annotations'
44 | })
45 | testImplementation 'junit:junit:4.12'
46 | compileOnly 'com.github.Justson:Downloader:v5.0.4-androidx'
47 | compileOnly 'com.google.android.material:material:1.0.0'
48 | compileOnly 'androidx.legacy:legacy-support-v4:1.0.0'
49 | compileOnly fileTree(include: ['*.jar'], dir: 'providedLibs')
50 | }
51 |
52 | publishing {
53 | publications {
54 | // Creates a Maven publication called "release".
55 | release(MavenPublication) {
56 | groupId = 'com.github.Justson.AgentWeb'
57 | artifactId = 'agentweb-core'
58 | version = 'v5.0.7-androidx'
59 | }
60 | }
61 | }
--------------------------------------------------------------------------------
/agentweb-core/src/main/java/com/just/agentweb/MiddlewareWebClientBase.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) Justson(https://github.com/Justson/AgentWeb)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.just.agentweb;
18 |
19 | import android.webkit.WebViewClient;
20 |
21 | /**
22 | * @author cenxiaozhong
23 | * @date 2017/12/15
24 | * @since 3.0.0
25 | */
26 | public class MiddlewareWebClientBase extends WebViewClientDelegate {
27 | private MiddlewareWebClientBase mMiddleWrareWebClientBase;
28 | private static String TAG = MiddlewareWebClientBase.class.getSimpleName();
29 |
30 | MiddlewareWebClientBase(MiddlewareWebClientBase client) {
31 | super(client);
32 | this.mMiddleWrareWebClientBase = client;
33 | }
34 |
35 | protected MiddlewareWebClientBase(WebViewClient client) {
36 | super(client);
37 | }
38 |
39 | protected MiddlewareWebClientBase() {
40 | super(null);
41 | }
42 |
43 | final MiddlewareWebClientBase next() {
44 | return this.mMiddleWrareWebClientBase;
45 | }
46 |
47 | @Override
48 | final void setDelegate(WebViewClient delegate) {
49 | super.setDelegate(delegate);
50 |
51 | }
52 |
53 | final MiddlewareWebClientBase enq(MiddlewareWebClientBase middleWrareWebClientBase) {
54 | setDelegate(middleWrareWebClientBase);
55 | this.mMiddleWrareWebClientBase = middleWrareWebClientBase;
56 | return middleWrareWebClientBase;
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/agentweb-core/src/main/java/com/just/agentweb/EventHandlerImpl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) Justson(https://github.com/Justson/AgentWeb)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.just.agentweb;
18 |
19 | import android.view.KeyEvent;
20 | import android.webkit.WebView;
21 |
22 | /**
23 | * IEventHandler 对事件的处理,主要是针对
24 | * 视屏状态进行了处理 , 如果当前状态为 视频状态
25 | * 则先退出视频。
26 | *
27 | * @author cenxiaozhong
28 | * @date 2017/6/3
29 | * @since 2.0.0
30 | */
31 | public class EventHandlerImpl implements IEventHandler {
32 | private WebView mWebView;
33 | private EventInterceptor mEventInterceptor;
34 |
35 | public static final EventHandlerImpl getInstantce(WebView view, EventInterceptor eventInterceptor) {
36 | return new EventHandlerImpl(view, eventInterceptor);
37 | }
38 |
39 | public EventHandlerImpl(WebView webView, EventInterceptor eventInterceptor) {
40 | this.mWebView = webView;
41 | this.mEventInterceptor = eventInterceptor;
42 | }
43 |
44 | @Override
45 | public boolean onKeyDown(int keyCode, KeyEvent event) {
46 | if (keyCode == KeyEvent.KEYCODE_BACK) {
47 | return back();
48 | }
49 | return false;
50 | }
51 |
52 | @Override
53 | public boolean back() {
54 | if (this.mEventInterceptor != null && this.mEventInterceptor.event()) {
55 | return true;
56 | }
57 | if (mWebView != null && mWebView.canGoBack()) {
58 | mWebView.goBack();
59 | return true;
60 | }
61 | return false;
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/agentweb-core/src/main/java/com/just/agentweb/JsAccessEntraceImpl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) Justson(https://github.com/Justson/AgentWeb)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.just.agentweb;
18 |
19 | import android.os.Handler;
20 | import android.os.Looper;
21 | import android.webkit.ValueCallback;
22 | import android.webkit.WebView;
23 |
24 |
25 | /**
26 | * @author cenxiaozhong
27 | * @date 2017/6/3
28 | * @since 1.0.0
29 | */
30 | public class JsAccessEntraceImpl extends BaseJsAccessEntrace {
31 |
32 | private WebView mWebView;
33 | private Handler mHandler = new Handler(Looper.getMainLooper());
34 |
35 | public static JsAccessEntraceImpl getInstance(WebView webView) {
36 | return new JsAccessEntraceImpl(webView);
37 | }
38 |
39 | private JsAccessEntraceImpl(WebView webView) {
40 | super(webView);
41 | this.mWebView = webView;
42 | }
43 |
44 | private void safeCallJs(final String s, final ValueCallback valueCallback) {
45 | mHandler.post(new Runnable() {
46 | @Override
47 | public void run() {
48 | callJs(s, valueCallback);
49 | }
50 | });
51 | }
52 |
53 | @Override
54 | public void callJs(String params, final ValueCallback callback) {
55 | if (Thread.currentThread() != Looper.getMainLooper().getThread()) {
56 | safeCallJs(params, callback);
57 | return;
58 | }
59 | super.callJs(params,callback);
60 | }
61 |
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/recyclerview_item_download.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
18 |
26 |
27 |
35 |
36 |
46 |
47 |
48 |
49 |
57 |
58 |
--------------------------------------------------------------------------------
/releasenote.md:
--------------------------------------------------------------------------------
1 | * v_5.0.0 更新
2 | * ActionActivity 重构, 使用Fragment 替代 Activity,解决多进程使用问题
3 | * 新增 WebRTC Sample
4 | * 新增 FileCompressor ,允许选择文件后对文件进行操作,如文件压缩,图片方向调整等
5 | * DefaultWebClient#onReceivedSslError 添加默认处理
6 | * 文件选择器开放多选
7 | * fix #777 ,FileChooserParams.createIntent() 导致AcceptTypes丢失问题
8 | * androidx Grade version upgrade to 7.0.2
9 | * 新增 AgentWebCompat.setDataDirectorySuffix(context) 修复 Using WebView from more than one process 崩溃
10 |
11 | * v_4.1.1 更新
12 | * [#587](https://github.com/Justson/AgentWeb/pull/587) input 支持视屏拍摄
13 | * [#614](https://github.com/Justson/AgentWeb/pull/614)修复上传文件选择的兼容性bug
14 | * 重构了Download
15 | * 最小SDK提升到了 14
16 |
17 | * v_4.0.3 更新
18 | * 部分手机下载过程中~声音一直响 [#523](https://github.com/Justson/AgentWeb/issues/523)
19 | * 抽离[Downloader](https://github.com/Justson/Downloader)
20 | * 放弃反射回调WebViewClient#methods,使用洋葱模型的Middleware代替
21 |
22 | * v_4.0.2 更新
23 | * 修复断点续传时进度计算错误
24 | * 修复无法通过`Extra`关闭进度通知
25 |
26 | * v_4.0.0 更新
27 | * `AgentWeb` 拆分出 `AgentWeb-Download` 、 `AgentWeb-FileChooser` 、`AgentWeb-core` 三个库,用户可以按需选择
28 | * 重新设计了 `AgentWeb-Download`
29 | * 删除了 `DownloadListener` 、`DefaultMsgConfig` 以及相关API
30 | * 旧废弃的API,4.0.0 直接删除,不在提供兼容
31 | * 部分类和API重命名
32 | * `Fragment`和`Activity`构建一致。[#227](https://github.com/Justson/AgentWeb/issues/227)
33 | * 从AgentWeb-core删除 `BaseAgentWebFragment`和`BaseAgentWebActivity` ,于Sample形式提供参考
34 | * v_3.1.0 更新
35 | * `WebProgress` 进度条动画更细腻
36 | * 修复部分机型拍照文件大小为0情况
37 | * 更新了`FileUpLoadChooserImpl`
38 | * v_3.0.0 更新
39 | * 加入 `MiddlewareWebChromeBase` 中间件 ,支持多个 `WebChromeClient`
40 | * 加入 `MiddlewareWebClientBase`中间件 , 支持多个 `WebViewClient`
41 | * 加入了默认的错误页,并支持自定义错误页
42 | * 加入 `AgentWebUIController` ,统一控制UI
43 | * 支持拦截未知的页面
44 | * 支持调起其他应用
45 | * v_2.0.1 更新
46 | * 支持并行下载 , 修复 #114 #109
47 | * v_2.0.0 更新
48 | * 加入动态权限
49 | * 拍照
50 | * v_1.2.6 更新
51 | * 修复Android 4.4以下布局错乱
52 | * v_1.2.5 提示信息支持配置
53 | * 提示信息支持配置
54 | * v_1.2.4 更新
55 | * 支持传入 IWebLayout ,支持下拉回弹,下拉刷新效果
56 | * v_1.2.3 更新
57 | * 新增下载结果回调
58 | * v_1.2.2 更新
59 | * 修复已知 Bug
60 | * v_1.2.1 更新
61 | * 支持调起支付宝 , 微信支付
62 | * v_1.2.0 更新
63 | * 全面支持全屏视频
64 | * v_1.1.2 更新
65 | * 完善功能
66 |
67 |
--------------------------------------------------------------------------------
/agentweb-core/src/main/java/com/just/agentweb/AgentWebSettingsImpl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) Justson(https://github.com/Justson/AgentWeb)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.just.agentweb;
18 |
19 | import android.app.Activity;
20 | import android.content.Context;
21 | import android.content.ContextWrapper;
22 | import android.webkit.DownloadListener;
23 | import android.webkit.WebView;
24 |
25 |
26 | /**
27 | * @author cenxiaozhong
28 | * @since 1.0.0
29 | */
30 | public class AgentWebSettingsImpl extends AbsAgentWebSettings {
31 | private AgentWeb mAgentWeb;
32 |
33 | @Override
34 | protected void bindAgentWebSupport(AgentWeb agentWeb) {
35 | this.mAgentWeb = agentWeb;
36 | }
37 |
38 | @Override
39 | public WebListenerManager setDownloader(WebView webView, DownloadListener downloadListener) {
40 | if (downloadListener == null) {
41 | downloadListener = DefaultDownloadImpl.create(mAgentWeb.getActivity(), webView, mAgentWeb.getPermissionInterceptor());
42 | }
43 | return super.setDownloader(webView, downloadListener);
44 | }
45 |
46 | /**
47 | * Copy from com.blankj.utilcode.util.ActivityUtils#getActivityByView
48 | */
49 | private Activity getActivityByContext(Context context) {
50 | if (context instanceof Activity) return (Activity) context;
51 | while (context instanceof ContextWrapper) {
52 | if (context instanceof Activity) {
53 | return (Activity) context;
54 | }
55 | context = ((ContextWrapper) context).getBaseContext();
56 | }
57 | return null;
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/agentweb-core/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | The task already exists, do not repeat click to download!
3 | Note
4 | Wi-Fi disconnected. Continue the download via mobile data network?
5 | Download
6 | Cancel
7 | Download failed!
8 | Downloading:%s
9 | downloaded:%s
10 | You have a new notice
11 | Download
12 | Tap to continue
13 | Coming soon to download the file
14 | Camera
15 | Files
16 | Loading ...
17 | leaving %s and opening another app?
18 | Go away
19 | The selected file can not be larger than %s MB
20 | error~
21 | The certificate authority is not trusted.
22 | The certificate has expired.
23 | The certificate Hostname mismatch.
24 | The certificate is not yet valid.
25 | SSL Certificate error.
26 | Do you want to continue anyway?
27 | SSL Certificate Error
28 | Continue
29 |
30 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/just/agentweb/sample/sonic/SonicSessionClientImpl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Tencent is pleased to support the open source community by making VasSonic available.
3 | *
4 | * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
5 | * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * https://opensource.org/licenses/BSD-3-Clause
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
10 | *
11 | *
12 | */
13 |
14 | package com.just.agentweb.sample.sonic;
15 |
16 | import android.os.Bundle;
17 | import android.webkit.WebView;
18 |
19 | import com.just.agentweb.AgentWeb;
20 | import com.tencent.sonic.sdk.SonicSessionClient;
21 |
22 | import java.util.HashMap;
23 |
24 | /**
25 | * a implement of SonicSessionClient which need to connect webview and content data.
26 | */
27 |
28 | public class SonicSessionClientImpl extends SonicSessionClient {
29 |
30 |
31 | private AgentWeb mAgentWeb;
32 | public void bindWebView(AgentWeb agentWeb) {
33 | this.mAgentWeb = agentWeb;
34 | }
35 |
36 | public WebView getWebView() {
37 | return this.mAgentWeb.getWebCreator().getWebView();
38 | }
39 |
40 | @Override
41 | public void loadUrl(String url, Bundle extraData) {
42 | this.mAgentWeb.getUrlLoader().loadUrl(url);
43 |
44 | }
45 |
46 | @Override
47 | public void loadDataWithBaseUrl(String baseUrl, String data, String mimeType, String encoding, String historyUrl) {
48 | this.mAgentWeb.getUrlLoader().loadDataWithBaseURL(baseUrl,data,mimeType,encoding,historyUrl);
49 |
50 | }
51 |
52 |
53 | @Override
54 | public void loadDataWithBaseUrlAndHeader(String baseUrl, String data, String mimeType, String encoding, String historyUrl, HashMap headers) {
55 | loadDataWithBaseUrl(baseUrl, data, mimeType, encoding, historyUrl);
56 | }
57 |
58 |
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/agentweb-core/src/main/java/com/just/agentweb/AgentWebPermissions.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) Justson(https://github.com/Justson/AgentWeb)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.just.agentweb;
18 |
19 | import android.Manifest;
20 | import android.os.Build;
21 |
22 |
23 | /**
24 | * @author cenxiaozhong
25 | * @since 1.0.0
26 | */
27 | public class AgentWebPermissions {
28 | public static String[] CAMERA;
29 | public static String[] LOCATION;
30 | public static String[] MEDIA;
31 | public static final String ACTION_CAMERA = "Camera";
32 | public static final String ACTION_LOCATION = "Location";
33 | public static final String ACTION_MEDIA = "Media";
34 |
35 | static {
36 | CAMERA = new String[]{
37 | Manifest.permission.CAMERA};
38 |
39 | LOCATION = new String[]{
40 | Manifest.permission.ACCESS_FINE_LOCATION,
41 | Manifest.permission.ACCESS_COARSE_LOCATION};
42 |
43 | if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
44 | MEDIA = new String[]{
45 | Manifest.permission.READ_MEDIA_VIDEO,
46 | Manifest.permission.READ_MEDIA_AUDIO,
47 | Manifest.permission.READ_MEDIA_IMAGES,
48 | };
49 | } else {
50 | MEDIA = new String[]{
51 | Manifest.permission.READ_EXTERNAL_STORAGE,
52 | Manifest.permission.WRITE_EXTERNAL_STORAGE
53 | };
54 | }
55 | }
56 |
57 | private static void emptyMediaPermission() {
58 | MEDIA = new String[]{};
59 | }
60 |
61 | private static void emptyCameraPermission() {
62 | CAMERA = new String[]{};
63 | }
64 |
65 | public static void dontAskUnnecessaryPermissions() {
66 | if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
67 | emptyMediaPermission();
68 | emptyCameraPermission();
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/just/agentweb/sample/fragment/CustomIndicatorFragment.java:
--------------------------------------------------------------------------------
1 | package com.just.agentweb.sample.fragment;
2 |
3 | import android.os.Bundle;
4 | import androidx.annotation.Nullable;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.LinearLayout;
8 |
9 | import com.just.agentweb.AgentWeb;
10 | import com.just.agentweb.AgentWebSettingsImpl;
11 | import com.just.agentweb.DefaultWebClient;
12 | import com.just.agentweb.sample.widget.CoolIndicatorLayout;
13 |
14 | /**
15 | * Created by cenxiaozhong on 2017/5/26.
16 | * source code https://github.com/Justson/AgentWeb
17 | */
18 |
19 | public class CustomIndicatorFragment extends AgentWebFragment {
20 | public static CustomIndicatorFragment getInstance(Bundle bundle) {
21 | CustomIndicatorFragment mCustomIndicatorFragment = new CustomIndicatorFragment();
22 | if (bundle != null){
23 | mCustomIndicatorFragment.setArguments(bundle);
24 | }
25 | return mCustomIndicatorFragment;
26 | }
27 |
28 | @Override
29 | public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
30 |
31 | // CommonIndicator mCommonIndicator=new CommonIndicator(this.getActivity());
32 | // FrameLayout.LayoutParams lp=new FrameLayout.LayoutParams(-2,-2);
33 | // lp.gravity= Gravity.CENTER;
34 | // ProgressBar mProgressBar=new ProgressBar(this.getActivity());
35 | // mProgressBar.setBackground(this.getResources().getDrawable(R.drawable.indicator_shape));
36 | // mCommonIndicator.addView(mProgressBar,lp);
37 |
38 |
39 | CoolIndicatorLayout mCoolIndicatorLayout = new CoolIndicatorLayout(this.getActivity());
40 | this.mAgentWeb = AgentWeb.with(this)//
41 | .setAgentWebParent((ViewGroup) view, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT))
42 | .setCustomIndicator(mCoolIndicatorLayout)
43 | .setAgentWebWebSettings(AgentWebSettingsImpl.getInstance())
44 | .setWebViewClient(mWebViewClient)
45 | .setPermissionInterceptor(mPermissionInterceptor)
46 | .setSecurityType(AgentWeb.SecurityType.STRICT_CHECK)
47 | .interceptUnkownUrl()
48 | .setOpenOtherPageWays(DefaultWebClient.OpenOtherPageWays.ASK)
49 | .createAgentWeb()//
50 | .ready()//
51 | .go(getUrl());
52 |
53 |
54 | initView(view);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/just/agentweb/sample/activity/RemoteWebViewlActivity.java:
--------------------------------------------------------------------------------
1 | package com.just.agentweb.sample.activity;
2 |
3 | import android.os.Bundle;
4 | import androidx.annotation.Nullable;
5 | import android.util.Log;
6 |
7 | import com.flyingpigeon.library.Pigeon;
8 | import com.flyingpigeon.library.ServiceManager;
9 | import com.flyingpigeon.library.annotations.Route;
10 | import com.flyingpigeon.library.annotations.thread.MainThread;
11 | import com.just.agentweb.sample.api.Api;
12 | import com.just.agentweb.sample.provider.ServiceProvider;
13 | import com.queue.library.GlobalQueue;
14 |
15 |
16 | /**
17 | * @author cenxiaozhong
18 | * @since 1.0.0
19 | */
20 | public class RemoteWebViewlActivity extends WebActivity {
21 |
22 | public static final String TAG = RemoteWebViewlActivity.class.getSimpleName();
23 |
24 | @Override
25 | protected void onCreate(@Nullable Bundle savedInstanceState) {
26 | super.onCreate(savedInstanceState);
27 | ServiceManager.getInstance().publish(this);
28 | GlobalQueue.getMainQueue().postRunnable(new Runnable() {
29 | @Override
30 | public void run() {
31 | sayYes();
32 | }
33 | }, 500);
34 | }
35 |
36 | private void sayYes() {
37 | Pigeon pigeon = Pigeon.newBuilder(this.getApplicationContext()).setAuthority(ServiceProvider.class).build();
38 | Api api = pigeon.create(Api.class);
39 | api.onReady();
40 | }
41 |
42 | @Override
43 | public String getUrl() {
44 | String url = getIntent().getStringExtra("url_key");
45 | Log.e(TAG, " url:" + url);
46 | return url;
47 | }
48 |
49 | /**
50 | * follow this , you could invoke this method anywhere
51 | *
52 | * Pigeon pigeon = Pigeon.newBuilder(this.getApplicationContext()).setAuthority("WebServiceProvider.class").build();
53 | * pigeon.route("/load/newUrl").withString("url_key", "http://baidu.com").fly();
54 | * @param in
55 | */
56 | @Route("/load/newUrl")
57 | @MainThread
58 | public void loadNewUrl(Bundle in) {
59 | mAgentWeb.getUrlLoader().loadUrl(in.getString("url_key"));
60 | }
61 |
62 |
63 | @Override
64 | protected void onDestroy() {
65 | super.onDestroy();
66 | ServiceManager.getInstance().unpublish(this);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/sample/src/main/assets/js_interaction/hello.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
17 |
18 |
70 |
71 |
72 |
73 |
75 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/agentweb-core/src/main/java/com/just/agentweb/IndicatorHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) Justson(https://github.com/Justson/AgentWeb)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.just.agentweb;
18 |
19 | import android.webkit.WebView;
20 |
21 |
22 | /**
23 | * @author cenxiaozhong
24 | * @since 1.0.0
25 | */
26 | public class IndicatorHandler implements IndicatorController {
27 | private BaseIndicatorSpec mBaseIndicatorSpec;
28 |
29 | @Override
30 | public void progress(WebView v, int newProgress) {
31 |
32 | if (newProgress == 0) {
33 | reset();
34 | } else if (newProgress > 0 && newProgress <= 10) {
35 | showIndicator();
36 | } else if (newProgress > 10 && newProgress < 95) {
37 | setProgress(newProgress);
38 | } else {
39 | setProgress(newProgress);
40 | finish();
41 | }
42 |
43 | }
44 |
45 | @Override
46 | public BaseIndicatorSpec offerIndicator() {
47 | return this.mBaseIndicatorSpec;
48 | }
49 |
50 | public void reset() {
51 |
52 | if (mBaseIndicatorSpec != null) {
53 | mBaseIndicatorSpec.reset();
54 | }
55 | }
56 |
57 | @Override
58 | public void finish() {
59 | if (mBaseIndicatorSpec != null) {
60 | mBaseIndicatorSpec.hide();
61 | }
62 | }
63 |
64 | @Override
65 | public void setProgress(int n) {
66 | if (mBaseIndicatorSpec != null) {
67 | mBaseIndicatorSpec.setProgress(n);
68 | }
69 | }
70 |
71 | @Override
72 | public void showIndicator() {
73 |
74 | if (mBaseIndicatorSpec != null) {
75 | mBaseIndicatorSpec.show();
76 | }
77 | }
78 |
79 | static IndicatorHandler getInstance() {
80 | return new IndicatorHandler();
81 | }
82 |
83 |
84 | IndicatorHandler inJectIndicator(BaseIndicatorSpec baseIndicatorSpec) {
85 | this.mBaseIndicatorSpec = baseIndicatorSpec;
86 | return this;
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/agentweb-core/src/main/java/com/just/agentweb/WebSecurityLogicImpl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) Justson(https://github.com/Justson/AgentWeb)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.just.agentweb;
18 |
19 | import android.annotation.TargetApi;
20 | import android.os.Build;
21 | import androidx.collection.ArrayMap;
22 | import android.webkit.WebView;
23 |
24 |
25 | /**
26 | * @author cenxiaozhong
27 | */
28 | public class WebSecurityLogicImpl implements WebSecurityCheckLogic {
29 | private String TAG = this.getClass().getSimpleName();
30 | private int webviewType;
31 |
32 | public static WebSecurityLogicImpl getInstance(int webViewType) {
33 | return new WebSecurityLogicImpl(webViewType);
34 | }
35 |
36 | public WebSecurityLogicImpl(int webViewType) {
37 | this.webviewType = webViewType;
38 | }
39 |
40 | @TargetApi(Build.VERSION_CODES.HONEYCOMB)
41 | @Override
42 | public void dealHoneyComb(WebView view) {
43 | if (Build.VERSION_CODES.HONEYCOMB > Build.VERSION.SDK_INT || Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR1) {
44 | return;
45 | }
46 | view.removeJavascriptInterface("searchBoxJavaBridge_");
47 | view.removeJavascriptInterface("accessibility");
48 | view.removeJavascriptInterface("accessibilityTraversal");
49 | }
50 |
51 | @Override
52 | public void dealJsInterface(ArrayMap objects, AgentWeb.SecurityType securityType) {
53 | if (securityType == AgentWeb.SecurityType.STRICT_CHECK
54 | && this.webviewType != AgentWebConfig.WEBVIEW_AGENTWEB_SAFE_TYPE
55 | && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
56 | LogUtils.e(TAG, "Give up all inject objects");
57 | objects.clear();
58 | objects = null;
59 | System.gc();
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/just/agentweb/sample/common/CustomSettings.java:
--------------------------------------------------------------------------------
1 | package com.just.agentweb.sample.common;
2 |
3 | import android.app.Activity;
4 | import android.os.Build;
5 | import android.webkit.DownloadListener;
6 | import android.webkit.WebView;
7 |
8 | import com.just.agentweb.AbsAgentWebSettings;
9 | import com.just.agentweb.AgentWeb;
10 | import com.just.agentweb.DefaultDownloadImpl;
11 | import com.just.agentweb.IAgentWebSettings;
12 | import com.just.agentweb.WebListenerManager;
13 |
14 | /**
15 | * Created by cenxiaozhong on 2017/5/26.
16 | * source code https://github.com/Justson/AgentWeb
17 | */
18 | public class CustomSettings extends AbsAgentWebSettings {
19 |
20 | public CustomSettings(Activity activity) {
21 | super();
22 | this.mActivity = activity;
23 | }
24 |
25 | private AgentWeb mAgentWeb;
26 | private Activity mActivity;
27 |
28 | @Override
29 | protected void bindAgentWebSupport(AgentWeb agentWeb) {
30 | this.mAgentWeb = agentWeb;
31 | }
32 |
33 |
34 | @Override
35 | public IAgentWebSettings toSetting(WebView webView) {
36 | super.toSetting(webView);
37 |
38 | getWebSettings().setBlockNetworkImage(false);//是否阻塞加载网络图片 协议http or https
39 | getWebSettings().setAllowFileAccess(false); //允许加载本地文件html file协议, 这可能会造成不安全 , 建议重写关闭
40 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
41 | getWebSettings().setAllowFileAccessFromFileURLs(false); //通过 file mUrl 加载的 Javascript 读取其他的本地文件 .建议关闭
42 | getWebSettings().setAllowUniversalAccessFromFileURLs(false);//允许通过 file mUrl 加载的 Javascript 可以访问其他的源,包括其他的文件和 http,https 等其他的源
43 | }
44 | getWebSettings().setNeedInitialFocus(true);
45 | getWebSettings().setDefaultTextEncodingName("gb2312");//设置编码格式
46 | getWebSettings().setDefaultFontSize(16);
47 | getWebSettings().setMinimumFontSize(12);//设置 WebView 支持的最小字体大小,默认为 8
48 | getWebSettings().setGeolocationEnabled(true);
49 | getWebSettings().setUserAgentString(getWebSettings().getUserAgentString().concat("agentweb/3.1.0"));
50 | return this;
51 | }
52 |
53 | @Override
54 | public WebListenerManager setDownloader(WebView webView, DownloadListener downloadListener) {
55 | return super.setDownloader(webView,
56 | DefaultDownloadImpl.create(this.mActivity
57 | , webView, mAgentWeb.getPermissionInterceptor()));
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/agentweb-core/src/main/java/com/just/agentweb/AgentWebJsInterfaceCompat.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) Justson(https://github.com/Justson/AgentWeb)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.just.agentweb;
18 |
19 | import android.app.Activity;
20 | import android.os.Handler;
21 | import android.os.Message;
22 | import android.webkit.JavascriptInterface;
23 |
24 | import java.lang.ref.WeakReference;
25 |
26 | /**
27 | * @author cenxiaozhong
28 | * @since 1.0.0
29 | */
30 | public class AgentWebJsInterfaceCompat {
31 |
32 | private WeakReference mReference = null;
33 | private WeakReference mActivityWeakReference = null;
34 | private String TAG = this.getClass().getSimpleName();
35 |
36 | AgentWebJsInterfaceCompat(AgentWeb agentWeb, Activity activity) {
37 | mReference = new WeakReference(agentWeb);
38 | mActivityWeakReference = new WeakReference(activity);
39 | }
40 |
41 | @JavascriptInterface
42 | public void uploadFile() {
43 | uploadFile("*/*");
44 | }
45 |
46 | @JavascriptInterface
47 | public void uploadFile(String acceptType) {
48 | LogUtils.i(TAG, acceptType + " " + mActivityWeakReference.get() + " " + mReference.get());
49 | if (mActivityWeakReference.get() != null && mReference.get() != null) {
50 | AgentWebUtils.showFileChooserCompat(mActivityWeakReference.get(),
51 | mReference.get().getWebCreator().getWebView(),
52 | null,
53 | null,
54 | mReference.get().getPermissionInterceptor(),
55 | null,
56 | acceptType,
57 | new Handler.Callback() {
58 | @Override
59 | public boolean handleMessage(Message msg) {
60 | if (mReference.get() != null) {
61 | mReference.get().getJsAccessEntrace()
62 | .quickCallJs("uploadFileResult",
63 | msg.obj instanceof String ? (String) msg.obj : null);
64 | }
65 | return true;
66 | }
67 | }
68 | );
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/fragment_js.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
21 |
22 |
34 |
47 |
48 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/just/agentweb/sample/fragment/VasSonicFragment.java:
--------------------------------------------------------------------------------
1 | package com.just.agentweb.sample.fragment;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import androidx.annotation.Nullable;
6 | import android.view.View;
7 |
8 | import com.just.agentweb.MiddlewareWebClientBase;
9 | import com.just.agentweb.sample.sonic.SonicImpl;
10 | import com.just.agentweb.sample.sonic.SonicJavaScriptInterface;
11 |
12 | import static com.just.agentweb.sample.sonic.SonicJavaScriptInterface.PARAM_CLICK_TIME;
13 |
14 | /**
15 | * Created by cenxiaozhong on 2017/12/18.
16 | *
17 | * If you wanna use VasSonic to fast open first page , please
18 | * follow as sample to update your code;
19 | */
20 |
21 | public class VasSonicFragment extends AgentWebFragment {
22 | private SonicImpl mSonicImpl;
23 | public static VasSonicFragment create(Bundle bundle){
24 |
25 | VasSonicFragment mVasSonicFragment =new VasSonicFragment();
26 | if(bundle!=null){
27 | mVasSonicFragment.setArguments(bundle);
28 | }
29 | return mVasSonicFragment;
30 | }
31 |
32 |
33 | @Override
34 | public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
35 |
36 | // 1. 首先创建SonicImpl
37 | mSonicImpl = new SonicImpl(this.getArguments().getString(URL_KEY), this.getContext());
38 | // 2. 调用 onCreateSession
39 | mSonicImpl.onCreateSession();
40 | //3. 创建AgentWeb ,注意创建AgentWeb的时候应该使用加入SonicWebViewClient中间件
41 | super.onViewCreated(view, savedInstanceState); // 创建 AgentWeb 注意的 go("") 传入的 mUrl 应该null 或者""
42 | //4. 注入 JavaScriptInterface
43 | mAgentWeb.getJsInterfaceHolder().addJavaObject("sonic", new SonicJavaScriptInterface(mSonicImpl.getSonicSessionClient(), new Intent().putExtra(PARAM_CLICK_TIME,getArguments().getLong(PARAM_CLICK_TIME)).putExtra("loadUrlTime", System.currentTimeMillis())));
44 | //5. 最后绑定AgentWeb
45 | mSonicImpl.bindAgentWeb(mAgentWeb);
46 |
47 | }
48 |
49 | //在步骤3的时候应该传入给AgentWeb
50 | @Override
51 | public MiddlewareWebClientBase getMiddlewareWebClient() {
52 | return mSonicImpl.createSonicClientMiddleWare();
53 | }
54 |
55 | //getUrl 应该为null
56 | @Override
57 | public String getUrl() {
58 | return null;
59 | }
60 |
61 | @Override
62 | public void onDestroyView() {
63 | super.onDestroyView();
64 | //销毁SonicSession
65 | if(mSonicImpl !=null){
66 | mSonicImpl.destrory();
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/just/agentweb/sample/sonic/SonicImpl.java:
--------------------------------------------------------------------------------
1 | package com.just.agentweb.sample.sonic;
2 |
3 | import android.content.Context;
4 |
5 | import com.just.agentweb.AgentWeb;
6 | import com.just.agentweb.MiddlewareWebClientBase;
7 | import com.tencent.sonic.sdk.SonicConfig;
8 | import com.tencent.sonic.sdk.SonicEngine;
9 | import com.tencent.sonic.sdk.SonicSession;
10 | import com.tencent.sonic.sdk.SonicSessionConfig;
11 |
12 | /**
13 | * Created by cenxiaozhong on 2017/12/17.
14 | */
15 |
16 | public class SonicImpl {
17 |
18 | private SonicSession sonicSession;
19 | private Context mContext;
20 | private String url;
21 | private SonicSessionClientImpl sonicSessionClient;
22 | public SonicImpl(String url , Context context){
23 | this.url=url;
24 | this.mContext=context;
25 |
26 | }
27 |
28 | /**
29 | */
30 | public void onCreateSession() {
31 |
32 | SonicSessionConfig.Builder sessionConfigBuilder = new SonicSessionConfig.Builder();
33 | sessionConfigBuilder.setSupportLocalServer(true);
34 | SonicEngine.createInstance(new DefaultSonicRuntimeImpl(mContext.getApplicationContext()), new SonicConfig.Builder().build());
35 | // create sonic session and run sonic flow
36 | sonicSession = SonicEngine.getInstance().createSession(url, sessionConfigBuilder.build());
37 | if (null != sonicSession) {
38 | sonicSession.bindClient(sonicSessionClient = new SonicSessionClientImpl());
39 | } else {
40 | // throw new UnknownError("create session fail!");
41 | // Toast.makeText(this, "create sonic session fail!", Toast.LENGTH_LONG).show();
42 | }
43 | }
44 |
45 | public SonicSessionClientImpl getSonicSessionClient(){
46 | return this.sonicSessionClient;
47 | }
48 |
49 | /**
50 | * 不使用中间件,使用普通的 WebViewClient 也是可以的。
51 | * @return MiddlewareWebClientBase
52 | */
53 | public MiddlewareWebClientBase createSonicClientMiddleWare(){
54 | return new SonicWebViewClient(sonicSession);
55 | }
56 |
57 | public void bindAgentWeb(AgentWeb agentWeb){
58 | if (sonicSessionClient != null) {
59 | sonicSessionClient.bindWebView(agentWeb);
60 | sonicSessionClient.clientReady();
61 | } else { // default mode
62 | agentWeb.getUrlLoader().loadUrl(url);
63 | }
64 | }
65 |
66 | public void destrory(){
67 | if(sonicSession!=null){
68 | sonicSession.destroy();
69 | }
70 | }
71 |
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/just/agentweb/sample/common/UIController.java:
--------------------------------------------------------------------------------
1 | package com.just.agentweb.sample.common;
2 |
3 | import android.app.Activity;
4 | import android.os.Handler;
5 | import android.util.Log;
6 | import android.webkit.WebView;
7 |
8 | import com.just.agentweb.AgentWebUIControllerImplBase;
9 |
10 | /**
11 | * Created by cenxiaozhong on 2017/12/23.
12 | */
13 |
14 | /**
15 | * 如果你需要修改某一个AgentWeb 内部的某一个弹窗 ,请看下面的例子
16 | * 注意写法一定要参照 DefaultUIController 的写法 ,因为UI自由定制,但是回调的方式是固定的,并且一定要回调。
17 | */
18 | public class UIController extends AgentWebUIControllerImplBase {
19 |
20 | private Activity mActivity;
21 | public UIController(Activity activity){
22 | this.mActivity=activity;
23 | }
24 |
25 | @Override
26 | public void onShowMessage(String message, String from) {
27 | super.onShowMessage(message,from);
28 | Log.i(TAG,"message:"+message);
29 | }
30 |
31 | @Override
32 | public void onSelectItemsPrompt(WebView view, String url, String[] items, Handler.Callback callback) {
33 | super.onSelectItemsPrompt(view,url,items,callback); // 使用默认的UI
34 | }
35 |
36 |
37 | /**
38 | * 修改文件选择的弹窗
39 | */
40 | /* @Override
41 | public void onSelectItemsPrompt(WebView view, String mUrl, String[] ways, final Handler.Callback callback) {
42 | //super.onSelectItemsPrompt(view,mUrl,ways,callback); //这行应该注释或者删除掉
43 | final AlertDialog mAlertDialog = new AlertDialog.Builder(mActivity)//
44 | .setSingleChoiceItems(ways, -1, new DialogInterface.OnClickListener() {
45 | @Override
46 | public void onClick(DialogInterface dialog, int which) {
47 | dialog.dismiss();
48 | if (callback != null) {
49 | Message mMessage = Message.obtain();
50 | mMessage.what = which; //mMessage.what 必须等于ways的index
51 | callback.handleMessage(mMessage); //最后callback一定要回调
52 | }
53 |
54 | }
55 | }).setOnCancelListener(new DialogInterface.OnCancelListener() {
56 | @Override
57 | public void onCancel(DialogInterface dialog) {
58 | dialog.dismiss();
59 | if (callback != null) {
60 | callback.handleMessage(Message.obtain(null, -1)); //-1表示取消 //最后callback一定要回调
61 | }
62 | }
63 | }).create();
64 | mAlertDialog.show();
65 |
66 | }*/
67 | }
68 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/just/agentweb/sample/behavior/BottomNavigationViewBehavior.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) LeonDevLifeLog(https://github.com/Justson/AgentWeb)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.just.agentweb.sample.behavior;
18 |
19 | import android.content.Context;
20 | import com.google.android.material.appbar.AppBarLayout;
21 | import androidx.coordinatorlayout.widget.CoordinatorLayout;
22 | import androidx.core.view.ViewCompat;
23 | import android.util.AttributeSet;
24 | import android.view.View;
25 |
26 | /**
27 | * 与toolbar联动隐藏底部菜单
28 | *
29 | * @author LeonDevLifeLog
30 | * @date 2018-02-24 08:59
31 | * @since V4.0.0
32 | */
33 | public class BottomNavigationViewBehavior extends CoordinatorLayout.Behavior {
34 | public BottomNavigationViewBehavior() {
35 | }
36 |
37 | public BottomNavigationViewBehavior(Context context, AttributeSet attrs) {
38 | super(context, attrs);
39 | }
40 |
41 | @Override
42 | public boolean onLayoutChild(CoordinatorLayout parent, View child, int layoutDirection) {
43 | ((CoordinatorLayout.LayoutParams) child.getLayoutParams()).topMargin = parent
44 | .getMeasuredHeight() - child.getMeasuredHeight();
45 | return super.onLayoutChild(parent, child, layoutDirection);
46 | }
47 |
48 | @Override
49 | public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
50 | return dependency instanceof AppBarLayout;
51 | }
52 |
53 | @Override
54 | public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
55 | //得到依赖View的滑动距离
56 | int top = ((AppBarLayout.Behavior) ((CoordinatorLayout.LayoutParams) dependency
57 | .getLayoutParams()).getBehavior()).getTopAndBottomOffset();
58 | //因为BottomNavigation的滑动与ToolBar是反向的,所以取负值
59 | ViewCompat.setTranslationY(child, -(top * child.getMeasuredHeight() / dependency
60 | .getMeasuredHeight()));
61 | return false;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/agentweb-core/src/main/java/com/just/agentweb/JsBaseInterfaceHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) Justson(https://github.com/Justson/AgentWeb)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.just.agentweb;
18 |
19 | import android.os.Build;
20 | import android.webkit.JavascriptInterface;
21 |
22 | import java.lang.annotation.Annotation;
23 | import java.lang.reflect.Method;
24 |
25 | /**
26 | * @author cenxiaozhong
27 | * @date 2017/5/13
28 | * @since 1.0.0
29 | */
30 | public abstract class JsBaseInterfaceHolder implements JsInterfaceHolder {
31 |
32 | private AgentWeb.SecurityType mSecurityType;
33 | private WebCreator mWebCreator;
34 |
35 | protected JsBaseInterfaceHolder(WebCreator webCreator, AgentWeb.SecurityType securityType) {
36 | this.mSecurityType = securityType;
37 | this.mWebCreator = webCreator;
38 | }
39 |
40 | @Override
41 | public boolean checkObject(Object v) {
42 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
43 | return true;
44 | }
45 | if (mWebCreator.getWebViewType() == AgentWebConfig.WEBVIEW_AGENTWEB_SAFE_TYPE) {
46 | return true;
47 | }
48 | boolean tag = false;
49 | Class clazz = v.getClass();
50 | Method[] mMethods = clazz.getMethods();
51 | for (Method mMethod : mMethods) {
52 | Annotation[] mAnnotations = mMethod.getAnnotations();
53 | for (Annotation mAnnotation : mAnnotations) {
54 | if (mAnnotation instanceof JavascriptInterface) {
55 | tag = true;
56 | break;
57 | }
58 | }
59 | if (tag) {
60 | break;
61 | }
62 | }
63 | return tag;
64 | }
65 |
66 | protected boolean checkSecurity() {
67 | return mSecurityType != AgentWeb.SecurityType.STRICT_CHECK
68 | ? true : mWebCreator.getWebViewType() == AgentWebConfig.WEBVIEW_AGENTWEB_SAFE_TYPE
69 | ? true : Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR1;
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/just/agentweb/sample/fragment/SmartRefreshWebFragment.java:
--------------------------------------------------------------------------------
1 | package com.just.agentweb.sample.fragment;
2 |
3 | import android.graphics.Color;
4 | import android.os.Bundle;
5 | import androidx.annotation.Nullable;
6 | import android.view.View;
7 | import android.webkit.WebView;
8 | import android.widget.FrameLayout;
9 |
10 | import com.just.agentweb.IWebLayout;
11 | import com.just.agentweb.sample.widget.SmartRefreshWebLayout;
12 | import com.scwang.smartrefresh.layout.SmartRefreshLayout;
13 | import com.scwang.smartrefresh.layout.api.RefreshLayout;
14 | import com.scwang.smartrefresh.layout.listener.OnRefreshListener;
15 |
16 | /**
17 | * Created by cenxiaozhong on 2017/7/1.
18 | * source code https://github.com/Justson/AgentWeb
19 | */
20 |
21 | public class SmartRefreshWebFragment extends BounceWebFragment {
22 |
23 | public static SmartRefreshWebFragment getInstance(Bundle bundle) {
24 |
25 | SmartRefreshWebFragment mSmartRefreshWebFragment = new SmartRefreshWebFragment();
26 | if (mSmartRefreshWebFragment != null) {
27 | mSmartRefreshWebFragment.setArguments(bundle);
28 | }
29 |
30 | return mSmartRefreshWebFragment;
31 | }
32 |
33 | private SmartRefreshWebLayout mSmartRefreshWebLayout = null;
34 |
35 | @Override
36 | public String getUrl() {
37 | return super.getUrl();
38 | }
39 |
40 |
41 | @Override
42 | public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
43 | super.onViewCreated(view, savedInstanceState);
44 |
45 | final SmartRefreshLayout mSmartRefreshLayout = (SmartRefreshLayout) this.mSmartRefreshWebLayout.getLayout();
46 |
47 | final WebView mWebView = this.mSmartRefreshWebLayout.getWebView();
48 | mSmartRefreshLayout.setOnRefreshListener(new OnRefreshListener() {
49 | @Override
50 | public void onRefresh(RefreshLayout refreshlayout) {
51 | mAgentWeb.getUrlLoader().reload();
52 |
53 | mSmartRefreshLayout.postDelayed(new Runnable() {
54 | @Override
55 | public void run() {
56 | mSmartRefreshLayout.finishRefresh();
57 | }
58 | }, 2000);
59 | }
60 | });
61 | mSmartRefreshLayout.autoRefresh();
62 |
63 |
64 | }
65 |
66 |
67 | @Override
68 | protected IWebLayout getWebLayout() {
69 | return this.mSmartRefreshWebLayout = new SmartRefreshWebLayout(this.getActivity());
70 | }
71 |
72 |
73 | @Override
74 | protected void addBGChild(FrameLayout frameLayout) {
75 |
76 | frameLayout.setBackgroundColor(Color.TRANSPARENT);
77 |
78 | }
79 |
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/activity_auto_hiden_toolbar.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
13 |
14 |
19 |
20 |
21 |
29 |
30 |
38 |
39 |
47 |
48 |
56 |
57 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/just/agentweb/sample/widget/CoolIndicatorLayout.java:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) Justson(https://github.com/Justson/AgentWeb)
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package com.just.agentweb.sample.widget;
19 |
20 | import android.app.Activity;
21 | import android.content.Context;
22 | import android.os.Build;
23 | import androidx.annotation.Nullable;
24 | import android.util.AttributeSet;
25 | import android.view.View;
26 | import android.widget.FrameLayout;
27 |
28 | import com.coolindicator.sdk.CoolIndicator;
29 | import com.just.agentweb.AgentWebUtils;
30 | import com.just.agentweb.BaseIndicatorView;
31 |
32 | /**
33 | * @author cenxiaozhong
34 | * @date 2018/2/23
35 | * @since 1.0.0
36 | */
37 | public class CoolIndicatorLayout extends BaseIndicatorView {
38 |
39 |
40 | private static final String TAG = CoolIndicatorLayout.class.getSimpleName();
41 | private CoolIndicator mCoolIndicator = null;
42 |
43 |
44 | public CoolIndicatorLayout(Context context) {
45 | this(context, null);
46 | }
47 |
48 | public CoolIndicatorLayout(Context context, @Nullable AttributeSet attrs) {
49 | this(context, attrs, -1);
50 | }
51 |
52 | public CoolIndicatorLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
53 | super(context, attrs, defStyleAttr);
54 | mCoolIndicator = CoolIndicator.create((Activity) context);
55 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
56 | mCoolIndicator.setProgressDrawable(context.getResources().getDrawable(com.coolindicator.sdk.R.drawable.default_drawable_indicator, context.getTheme()));
57 | } else {
58 | mCoolIndicator.setProgressDrawable(context.getResources().getDrawable(com.coolindicator.sdk.R.drawable.default_drawable_indicator));
59 | }
60 |
61 | this.addView(mCoolIndicator, offerLayoutParams());
62 |
63 | }
64 |
65 | @Override
66 | public void show() {
67 | this.setVisibility(View.VISIBLE);
68 | mCoolIndicator.start();
69 | }
70 |
71 | @Override
72 | public void setProgress(int newProgress) {
73 | }
74 |
75 | @Override
76 | public void hide() {
77 | mCoolIndicator.complete();
78 | }
79 |
80 | @Override
81 | public LayoutParams offerLayoutParams() {
82 | return new FrameLayout.LayoutParams(-1, AgentWebUtils.dp2px(getContext(), 3));
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/just/agentweb/sample/fragment/BounceWebFragment.java:
--------------------------------------------------------------------------------
1 | package com.just.agentweb.sample.fragment;
2 |
3 | import android.graphics.Color;
4 | import android.os.Bundle;
5 | import androidx.annotation.Nullable;
6 | import android.view.Gravity;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.FrameLayout;
10 | import android.widget.LinearLayout;
11 | import android.widget.TextView;
12 |
13 | import com.just.agentweb.AgentWeb;
14 | import com.just.agentweb.DefaultWebClient;
15 | import com.just.agentweb.IWebLayout;
16 | import com.just.agentweb.sample.R;
17 | import com.just.agentweb.sample.widget.WebLayout;
18 |
19 | /**
20 | * Created by cenxiaozhong on 2017/7/1.
21 | * source code https://github.com/Justson/AgentWeb
22 | */
23 |
24 | public class BounceWebFragment extends AgentWebFragment {
25 |
26 | public static BounceWebFragment getInstance(Bundle bundle) {
27 | BounceWebFragment mBounceWebFragment = new BounceWebFragment();
28 | if (mBounceWebFragment != null){
29 | mBounceWebFragment.setArguments(bundle);
30 | }
31 | return mBounceWebFragment;
32 | }
33 |
34 |
35 | @Override
36 | public String getUrl() {
37 | return super.getUrl();
38 | }
39 |
40 | @Override
41 | public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
42 | mAgentWeb = AgentWeb.with(this)
43 | .setAgentWebParent((ViewGroup) view, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT))
44 | .useDefaultIndicator(-1, 2)
45 | .setAgentWebWebSettings(getSettings())
46 | .setWebViewClient(mWebViewClient)
47 | .setWebChromeClient(mWebChromeClient)
48 | .setWebLayout(getWebLayout())
49 | .setSecurityType(AgentWeb.SecurityType.STRICT_CHECK)
50 | .interceptUnkownUrl()
51 | .setOpenOtherPageWays(DefaultWebClient.OpenOtherPageWays.ASK)
52 | .setMainFrameErrorView(com.just.agentweb.R.layout.agentweb_error_page, -1)
53 | .createAgentWeb()//
54 | .ready()//
55 | .go(getUrl());
56 | // 得到 AgentWeb 最底层的控件
57 | addBGChild((FrameLayout) mAgentWeb.getWebCreator().getWebParentLayout());
58 | initView(view);
59 |
60 |
61 | }
62 |
63 | protected IWebLayout getWebLayout() {
64 | return new WebLayout(getActivity());
65 | }
66 |
67 | protected void addBGChild(FrameLayout frameLayout) {
68 |
69 | TextView mTextView = new TextView(frameLayout.getContext());
70 | mTextView.setText("技术由 AgentWeb 提供");
71 | mTextView.setTextSize(16);
72 | mTextView.setTextColor(Color.parseColor("#727779"));
73 | frameLayout.setBackgroundColor(Color.parseColor("#272b2d"));
74 | FrameLayout.LayoutParams mFlp = new FrameLayout.LayoutParams(-2, -2);
75 | mFlp.gravity = Gravity.CENTER_HORIZONTAL;
76 | final float scale = frameLayout.getContext().getResources().getDisplayMetrics().density;
77 | mFlp.topMargin = (int) (15 * scale + 0.5f);
78 | frameLayout.addView(mTextView, 0, mFlp);
79 | }
80 |
81 |
82 | }
83 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/just/agentweb/sample/activity/EasyWebActivity.java:
--------------------------------------------------------------------------------
1 | package com.just.agentweb.sample.activity;
2 |
3 | import android.graphics.Color;
4 | import android.os.Bundle;
5 | import androidx.annotation.NonNull;
6 | import androidx.annotation.Nullable;
7 | import androidx.appcompat.widget.Toolbar;
8 | import android.text.TextUtils;
9 | import android.view.KeyEvent;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 | import android.webkit.WebView;
13 | import android.widget.LinearLayout;
14 | import android.widget.TextView;
15 |
16 | import com.just.agentweb.sample.R;
17 | import com.just.agentweb.sample.base.BaseAgentWebActivity;
18 |
19 | /**
20 | * Created by cenxiaozhong on 2017/7/22.
21 | *
22 | */
23 | public class EasyWebActivity extends BaseAgentWebActivity {
24 |
25 | private TextView mTitleTextView;
26 |
27 | @Override
28 | protected void onCreate(@Nullable Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 | setContentView(R.layout.activity_web);
31 |
32 | LinearLayout mLinearLayout = (LinearLayout) this.findViewById(R.id.container);
33 | Toolbar mToolbar = (Toolbar) this.findViewById(R.id.toolbar);
34 | mToolbar.setTitleTextColor(Color.WHITE);
35 | mToolbar.setTitle("");
36 | mTitleTextView = (TextView) this.findViewById(R.id.toolbar_title);
37 | this.setSupportActionBar(mToolbar);
38 | if (getSupportActionBar() != null) {
39 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
40 | }
41 | mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
42 | @Override
43 | public void onClick(View v) {
44 | EasyWebActivity.this.finish();
45 | }
46 | });
47 | }
48 |
49 |
50 | @NonNull
51 | @Override
52 | protected ViewGroup getAgentWebParent() {
53 | return (ViewGroup) this.findViewById(R.id.container);
54 | }
55 |
56 | @Override
57 | public boolean onKeyDown(int keyCode, KeyEvent event) {
58 | if (mAgentWeb != null && mAgentWeb.handleKeyEvent(keyCode, event)) {
59 | return true;
60 | }
61 |
62 | return super.onKeyDown(keyCode, event);
63 | }
64 |
65 | @Override
66 | protected int getIndicatorColor() {
67 | return Color.parseColor("#ff0000");
68 | }
69 |
70 | @Override
71 | protected void setTitle(WebView view, String title) {
72 | super.setTitle(view, title);
73 | if (!TextUtils.isEmpty(title)) {
74 | if (title.length() > 10) {
75 | title = title.substring(0, 10).concat("...");
76 | }
77 | }
78 | mTitleTextView.setText(title);
79 | }
80 |
81 | @Override
82 | protected int getIndicatorHeight() {
83 | return 3;
84 | }
85 |
86 | @Nullable
87 | @Override
88 | protected String getUrl() {
89 | return "https://www.baidu.com/";
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |

4 |
5 |
6 | ## AgentWeb 介绍
7 |
8 | AgentWeb 是一个基于的 Android WebView ,极度容易使用以及功能强大的库,提供了 Android WebView 一系列的问题解决方案 ,并且轻量和极度灵活,详细使用请参照上面的 Sample 。
9 |
10 |
11 | ## Gradle 引入
12 |
13 | ```groovy
14 | allprojects {
15 | repositories {
16 | mavenCentral()
17 | maven { url 'https://jitpack.io' }
18 | }
19 | }
20 | ```
21 |
22 |
23 |
24 | * Androidx
25 |
26 | ```groovy
27 | implementation 'io.github.justson:agentweb-core:v5.1.1-androidx'
28 | implementation 'io.github.justson:agentweb-filechooser:v5.1.1-androidx' // (可选)
29 | implementation 'com.github.Justson:Downloader:v5.0.4-androidx' // (可选)
30 |
31 | ```
32 |
33 |
34 | ## 相关
35 | * [flying-pigeon跨进程IPC组件](https://github.com/Justson/flying-pigeon)
36 | * [AgentWebX5](https://github.com/Justson/AgentWebX5)
37 | * [WebView 进度条](https://github.com/Justson/CoolIndicator)
38 | * [Downloader 一个轻量的文件下载器](https://github.com/Justson/Downloader)
39 |
40 |
41 |
42 |
43 | ## 注意事项
44 | * 支付宝使用需要引入支付宝SDK ,并在项目中依赖 , 微信支付不需要做任何操作。
45 | * AgentWeb 内部使用了 `AlertDialog` 需要依赖 `AppCompat` 主题 。
46 | * `setAgentWebParent` 不支持 `ConstraintLayout` 。
47 | * `mAgentWeb.getWebLifeCycle().onPause();`会暂停应用内所有`WebView` 。
48 | * `minSdkVersion` 低于等于16以下自定义`WebView`请注意与 `JS` 之间通信安全。
49 |
50 |
51 |
52 |
53 | ## 文档帮助
54 | * [Wiki](https://github.com/Justson/AgentWeb/wiki)(不全)
55 | * `Sample`(推荐,详细)
56 | * [更新日志](./releasenote.md)
57 |
58 |
59 |
60 | ## 有问题或者有更好的建议
61 | * [![QQ0Group][qq0groupsvg]][qq0group]
62 | * 欢迎提 [Issues](https://github.com/Justson/AgentWeb/issues)
63 |
64 |
65 | ## 赞赏
66 | 开源不易,你的支持是我更新的动力。
67 |
68 |
69 |
70 |
71 | [licensesvg]: https://img.shields.io/badge/License-Apache--2.0-brightgreen.svg
72 | [license]: https://github.com/Justson/AgentWeb/blob/master/LICENSE
73 |
74 | [qq0groupsvg]: https://img.shields.io/badge/QQ群-599471474-fba7f9.svg
75 | [qq0group]: http://qm.qq.com/cgi-bin/qm/qr?k=KpyfInzI2nr-Lh4StG0oh68GpbcD0vMG
76 |
77 |
78 |
79 | [![License][licensesvg]][license]
80 |
81 | ## License
82 | ```
83 | Copyright (C) Justson(https://github.com/Justson/AgentWeb)
84 |
85 | Licensed under the Apache License, Version 2.0 (the "License");
86 | you may not use this file except in compliance with the License.
87 | You may obtain a copy of the License at
88 |
89 | http://www.apache.org/licenses/LICENSE-2.0
90 |
91 | Unless required by applicable law or agreed to in writing, software
92 | distributed under the License is distributed on an "AS IS" BASIS,
93 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
94 | See the License for the specific language governing permissions and
95 | limitations under the License.
96 | ```
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/agentweb-filechooser/src/main/java/com/just/agentweb/filechooser/FileParcel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) Justson(https://github.com/Justson/AgentWeb)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.just.agentweb.filechooser;
18 |
19 | import android.os.Parcel;
20 | import android.os.Parcelable;
21 |
22 | /**
23 | * @author cenxiaozhong
24 | * @date 2017/5/24
25 | */
26 | public class FileParcel implements Parcelable {
27 |
28 | private int mId;
29 | private String mContentPath;
30 | private String mFileBase64;
31 |
32 | protected FileParcel(Parcel in) {
33 | mId = in.readInt();
34 | mContentPath = in.readString();
35 | mFileBase64 = in.readString();
36 | }
37 |
38 | public FileParcel(int id, String contentPath, String fileBase64) {
39 | this.mId = id;
40 | this.mContentPath = contentPath;
41 | this.mFileBase64 = fileBase64;
42 |
43 | }
44 |
45 | public static final Creator CREATOR = new Creator() {
46 | @Override
47 | public FileParcel createFromParcel(Parcel in) {
48 | return new FileParcel(in);
49 | }
50 |
51 | @Override
52 | public FileParcel[] newArray(int size) {
53 | return new FileParcel[size];
54 | }
55 | };
56 |
57 | public int getId() {
58 | return mId;
59 | }
60 |
61 | public void setId(int id) {
62 | this.mId = id;
63 | }
64 |
65 | public String getContentPath() {
66 | return mContentPath;
67 | }
68 |
69 | public void setContentPath(String contentPath) {
70 | this.mContentPath = contentPath;
71 | }
72 |
73 | public String getFileBase64() {
74 | return mFileBase64;
75 | }
76 |
77 | public void setFileBase64(String fileBase64) {
78 | this.mFileBase64 = fileBase64;
79 | }
80 |
81 | @Override
82 | public int describeContents() {
83 | return 0;
84 | }
85 |
86 | @Override
87 | public void writeToParcel(Parcel dest, int flags) {
88 | dest.writeInt(mId);
89 | dest.writeString(mContentPath);
90 | dest.writeString(mFileBase64);
91 | }
92 |
93 | @Override
94 | public String toString() {
95 | return "FileParcel{" +
96 | "mId=" + mId +
97 | ", mContentPath='" + mContentPath + '\'' +
98 | ", mFileBase64='" + mFileBase64 + '\'' +
99 | '}';
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/agentweb-core/src/main/java/com/just/agentweb/ProcessUtils.java:
--------------------------------------------------------------------------------
1 | package com.just.agentweb;
2 |
3 | import android.app.ActivityManager;
4 | import android.app.Application;
5 | import android.content.Context;
6 | import android.text.TextUtils;
7 |
8 | import java.io.BufferedReader;
9 | import java.io.File;
10 | import java.io.FileReader;
11 | import java.lang.reflect.Field;
12 | import java.lang.reflect.Method;
13 | import java.util.List;
14 |
15 | /**
16 | * Adapted from com.blankj.utilcode.util.ProcessUtils#getCurrentProcessName
17 | */
18 | class ProcessUtils {
19 |
20 | static String getCurrentProcessName(Context context) {
21 | String name = getCurrentProcessNameByFile();
22 | if (!TextUtils.isEmpty(name)) return name;
23 | name = getCurrentProcessNameByAms(context);
24 | if (!TextUtils.isEmpty(name)) return name;
25 | name = getCurrentProcessNameByReflect(context);
26 | return name;
27 | }
28 |
29 | private static String getCurrentProcessNameByFile() {
30 | try {
31 | File file = new File("/proc/" + android.os.Process.myPid() + "/" + "cmdline");
32 | BufferedReader mBufferedReader = new BufferedReader(new FileReader(file));
33 | String processName = mBufferedReader.readLine().trim();
34 | mBufferedReader.close();
35 | return processName;
36 | } catch (Exception e) {
37 | e.printStackTrace();
38 | return "";
39 | }
40 | }
41 |
42 | private static String getCurrentProcessNameByAms(Context context) {
43 | ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
44 | if (am == null) return "";
45 | List info = am.getRunningAppProcesses();
46 | if (info == null || info.size() == 0) return "";
47 | int pid = android.os.Process.myPid();
48 | for (ActivityManager.RunningAppProcessInfo aInfo : info) {
49 | if (aInfo.pid == pid) {
50 | if (aInfo.processName != null) {
51 | return aInfo.processName;
52 | }
53 | }
54 | }
55 | return "";
56 | }
57 |
58 | private static String getCurrentProcessNameByReflect(Context context) {
59 | String processName = "";
60 | try {
61 | Application app = (Application) context.getApplicationContext();
62 | Field loadedApkField = app.getClass().getField("mLoadedApk");
63 | loadedApkField.setAccessible(true);
64 | Object loadedApk = loadedApkField.get(app);
65 |
66 | Field activityThreadField = loadedApk.getClass().getDeclaredField("mActivityThread");
67 | activityThreadField.setAccessible(true);
68 | Object activityThread = activityThreadField.get(loadedApk);
69 |
70 | Method getProcessName = activityThread.getClass().getDeclaredMethod("getProcessName");
71 | processName = (String) getProcessName.invoke(activityThread);
72 | } catch (Exception e) {
73 | e.printStackTrace();
74 | }
75 | return processName;
76 | }
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/just/agentweb/sample/utils/ProcessUtils.java:
--------------------------------------------------------------------------------
1 | package com.just.agentweb.sample.utils;
2 |
3 | import android.app.ActivityManager;
4 | import android.app.Application;
5 | import android.content.Context;
6 | import android.text.TextUtils;
7 |
8 | import java.io.BufferedReader;
9 | import java.io.File;
10 | import java.io.FileReader;
11 | import java.lang.reflect.Field;
12 | import java.lang.reflect.Method;
13 | import java.util.List;
14 |
15 | /**
16 | * Adapted from com.blankj.utilcode.util.ProcessUtils#getCurrentProcessName
17 | */
18 | public class ProcessUtils {
19 |
20 | public static String getCurrentProcessName(Context context) {
21 | String name = getCurrentProcessNameByFile();
22 | if (!TextUtils.isEmpty(name)) return name;
23 | name = getCurrentProcessNameByAms(context);
24 | if (!TextUtils.isEmpty(name)) return name;
25 | name = getCurrentProcessNameByReflect(context);
26 | return name;
27 | }
28 |
29 | private static String getCurrentProcessNameByFile() {
30 | try {
31 | File file = new File("/proc/" + android.os.Process.myPid() + "/" + "cmdline");
32 | BufferedReader mBufferedReader = new BufferedReader(new FileReader(file));
33 | String processName = mBufferedReader.readLine().trim();
34 | mBufferedReader.close();
35 | return processName;
36 | } catch (Exception e) {
37 | e.printStackTrace();
38 | return "";
39 | }
40 | }
41 |
42 | private static String getCurrentProcessNameByAms(Context context) {
43 | ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
44 | if (am == null) return "";
45 | List info = am.getRunningAppProcesses();
46 | if (info == null || info.size() == 0) return "";
47 | int pid = android.os.Process.myPid();
48 | for (ActivityManager.RunningAppProcessInfo aInfo : info) {
49 | if (aInfo.pid == pid) {
50 | if (aInfo.processName != null) {
51 | return aInfo.processName;
52 | }
53 | }
54 | }
55 | return "";
56 | }
57 |
58 | private static String getCurrentProcessNameByReflect(Context context) {
59 | String processName = "";
60 | try {
61 | Application app = (Application) context.getApplicationContext();
62 | Field loadedApkField = app.getClass().getField("mLoadedApk");
63 | loadedApkField.setAccessible(true);
64 | Object loadedApk = loadedApkField.get(app);
65 |
66 | Field activityThreadField = loadedApk.getClass().getDeclaredField("mActivityThread");
67 | activityThreadField.setAccessible(true);
68 | Object activityThread = activityThreadField.get(loadedApk);
69 |
70 | Method getProcessName = activityThread.getClass().getDeclaredMethod("getProcessName");
71 | processName = (String) getProcessName.invoke(activityThread);
72 | } catch (Exception e) {
73 | e.printStackTrace();
74 | }
75 | return processName;
76 | }
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/agentweb-core/src/main/java/com/just/agentweb/JsInterfaceHolderImpl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) Justson(https://github.com/Justson/AgentWeb)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.just.agentweb;
18 |
19 | import android.webkit.WebView;
20 |
21 | import java.util.Map;
22 | import java.util.Set;
23 |
24 | /**
25 | * @author cenxiaozhong
26 | * @date 2017/5/13
27 | * @since 1.0.0
28 | */
29 | public class JsInterfaceHolderImpl extends JsBaseInterfaceHolder {
30 |
31 | private static final String TAG = JsInterfaceHolderImpl.class.getSimpleName();
32 | private WebCreator mWebCreator;
33 | private AgentWeb.SecurityType mSecurityType;
34 | private WebView mWebView;
35 |
36 | static JsInterfaceHolderImpl getJsInterfaceHolder(WebCreator webCreator, AgentWeb.SecurityType securityType) {
37 | return new JsInterfaceHolderImpl(webCreator, securityType);
38 | }
39 |
40 | JsInterfaceHolderImpl(WebCreator webCreator, AgentWeb.SecurityType securityType) {
41 | super(webCreator, securityType);
42 | this.mWebCreator = webCreator;
43 | this.mWebView = mWebCreator.getWebView();
44 | this.mSecurityType = securityType;
45 | }
46 |
47 | @Override
48 | public JsInterfaceHolder addJavaObjects(Map maps) {
49 | if (!checkSecurity()) {
50 | LogUtils.e(TAG, "The injected object is not safe, give up injection");
51 | return this;
52 | }
53 | Set> sets = maps.entrySet();
54 | for (Map.Entry mEntry : sets) {
55 | Object v = mEntry.getValue();
56 | boolean t = checkObject(v);
57 | if (!t) {
58 | throw new JsInterfaceObjectException("This object has not offer method javascript to call ,please check addJavascriptInterface annotation was be added");
59 | } else {
60 | addJavaObjectDirect(mEntry.getKey(), v);
61 | }
62 | }
63 | return this;
64 | }
65 |
66 | @Override
67 | public JsInterfaceHolder addJavaObject(String k, Object v) {
68 | if (!checkSecurity()) {
69 | return this;
70 | }
71 | boolean t = checkObject(v);
72 | if (!t) {
73 | throw new JsInterfaceObjectException("this object has not offer method javascript to call , please check addJavascriptInterface annotation was be added");
74 | } else {
75 | addJavaObjectDirect(k, v);
76 | }
77 | return this;
78 | }
79 |
80 | private JsInterfaceHolder addJavaObjectDirect(String k, Object v) {
81 | LogUtils.i(TAG, "k:" + k + " v:" + v);
82 | this.mWebView.addJavascriptInterface(v, k);
83 | return this;
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/agentweb-core/src/main/java/com/just/agentweb/BaseJsAccessEntrace.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) Justson(https://github.com/Justson/AgentWeb)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.just.agentweb;
18 |
19 | import android.os.Build;
20 | import android.webkit.ValueCallback;
21 | import android.webkit.WebView;
22 |
23 | /**
24 | * @author cenxiaozhong
25 | * @date 2017/5/26
26 | * @since 1.0.0
27 | */
28 | public abstract class BaseJsAccessEntrace implements JsAccessEntrace {
29 | private WebView mWebView;
30 | public static final String TAG=BaseJsAccessEntrace.class.getSimpleName();
31 | BaseJsAccessEntrace(WebView webView){
32 | this.mWebView=webView;
33 | }
34 | @Override
35 | public void callJs(String js, final ValueCallback callback) {
36 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
37 | this.evaluateJs(js, callback);
38 | } else {
39 | this.loadJs(js);
40 | }
41 | }
42 | @Override
43 | public void callJs(String js) {
44 | this.callJs(js, null);
45 | }
46 |
47 | private void loadJs(String js) {
48 | mWebView.loadUrl(js);
49 | }
50 | private void evaluateJs(String js, final ValueCallbackcallback){
51 | mWebView.evaluateJavascript(js, new ValueCallback() {
52 | @Override
53 | public void onReceiveValue(String value) {
54 | if (callback != null){
55 | callback.onReceiveValue(value);
56 | }
57 | }
58 | });
59 | }
60 |
61 |
62 | @Override
63 | public void quickCallJs(String method, ValueCallback callback, String... params) {
64 | StringBuilder sb=new StringBuilder();
65 | sb.append("javascript:"+method);
66 | if(params==null||params.length==0){
67 | sb.append("()");
68 | }else{
69 | sb.append("(").append(concat(params)).append(")");
70 | }
71 | callJs(sb.toString(),callback);
72 | }
73 |
74 | private String concat(String...params){
75 | StringBuilder mStringBuilder=new StringBuilder();
76 | for(int i=0;i
2 |
13 |
14 |
17 |
20 |
21 |
31 |
40 |
49 |
50 |
58 |
59 |
60 |
70 |
71 |
72 |
81 |
82 |
87 |
88 |
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/agentweb-core/src/main/java/com/just/agentweb/AgentWebCompat.java:
--------------------------------------------------------------------------------
1 | package com.just.agentweb;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.Context;
5 | import android.os.Build;
6 | import android.text.TextUtils;
7 | import android.webkit.WebView;
8 |
9 | import java.io.File;
10 | import java.io.RandomAccessFile;
11 | import java.nio.channels.FileLock;
12 | import java.util.HashSet;
13 | import java.util.Set;
14 |
15 | /**
16 | * @author cenxiaozhong
17 | * @date 2021/11/24
18 | * @since 1.0.0
19 | */
20 | public class AgentWebCompat {
21 |
22 |
23 | /**
24 | * 来之 https://github.com/Justson/AgentWeb/issues/934 建议
25 | * https://juejin.cn/post/6950091477192015902
26 | * fix Using WebView from more than one process
27 | * @param context
28 | */
29 | public static void setDataDirectorySuffix(Context context) {
30 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
31 | return;
32 | }
33 | try {
34 |
35 | Set pathSet = new HashSet<>();
36 | String suffix = "";
37 | String dataPath = context.getDataDir().getAbsolutePath();
38 | String webViewDir = "/app_webview";
39 | String huaweiWebViewDir = "/app_hws_webview";
40 | String lockFile = "/webview_data.lock";
41 | String processName = ProcessUtils.getCurrentProcessName(context);
42 | if (!TextUtils.equals(context.getPackageName(), processName)) {//判断不等于默认进程名称
43 | suffix = TextUtils.isEmpty(processName) ? context.getPackageName() : processName;
44 | WebView.setDataDirectorySuffix(suffix);
45 | suffix = "_" + suffix;
46 | pathSet.add(dataPath + webViewDir + suffix + lockFile);
47 | if (RomUtils.isHuawei()) {
48 | pathSet.add(dataPath + huaweiWebViewDir + suffix + lockFile);
49 | }
50 | }else{
51 | //主进程
52 | suffix = "_" + processName;
53 | pathSet.add(dataPath + webViewDir + lockFile);//默认未添加进程名后缀
54 | pathSet.add(dataPath + webViewDir + suffix + lockFile);//系统自动添加了进程名后缀
55 | if (RomUtils.isHuawei()) {//部分华为手机更改了webview目录名
56 | pathSet.add(dataPath + huaweiWebViewDir + lockFile);
57 | pathSet.add(dataPath + huaweiWebViewDir + suffix + lockFile);
58 | }
59 | }
60 | for (String path : pathSet) {
61 | File file = new File(path);
62 | if (file.exists()) {
63 | tryLockOrRecreateFile(file);
64 | break;
65 | }
66 | }
67 | } catch (Exception e) {
68 | e.printStackTrace();
69 | }
70 | }
71 |
72 | @TargetApi(Build.VERSION_CODES.P)
73 | private static void tryLockOrRecreateFile(File file) {
74 | try {
75 | FileLock tryLock = new RandomAccessFile(file, "rw").getChannel().tryLock();
76 | if (tryLock != null) {
77 | tryLock.close();
78 | } else {
79 | createFile(file, file.delete());
80 | }
81 | } catch (Exception e) {
82 | e.printStackTrace();
83 | boolean deleted = false;
84 | if (file.exists()) {
85 | deleted = file.delete();
86 | }
87 | createFile(file, deleted);
88 | }
89 | }
90 |
91 | private static void createFile(File file, boolean deleted){
92 | try {
93 | if (deleted && !file.exists()) {
94 | file.createNewFile();
95 | }
96 | } catch (Exception e) {
97 | e.printStackTrace();
98 | }
99 | }
100 |
101 | }
102 |
103 |
--------------------------------------------------------------------------------