Showing preview only (692K chars total). Download the full file or copy to clipboard to get everything.
Repository: Justson/AgentWeb
Branch: androidx
Commit: 95d48cd5a032
Files: 202
Total size: 630.7 KB
Directory structure:
gitextract_lyaxu09n/
├── .github/
│ └── FUNDING.yml
├── .gitignore
├── LICENSE
├── README.md
├── agentweb-core/
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ ├── providedLibs/
│ │ └── alipaySdk-20180601.jar
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── com/
│ │ └── just/
│ │ └── agentweb/
│ │ └── ExampleInstrumentedTest.java
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── just/
│ │ │ └── agentweb/
│ │ │ ├── AbsAgentWebSettings.java
│ │ │ ├── AbsAgentWebUIController.java
│ │ │ ├── Action.java
│ │ │ ├── AgentActionFragment.java
│ │ │ ├── AgentWeb.java
│ │ │ ├── AgentWebCompat.java
│ │ │ ├── AgentWebConfig.java
│ │ │ ├── AgentWebFileProvider.java
│ │ │ ├── AgentWebJsInterfaceCompat.java
│ │ │ ├── AgentWebPermissions.java
│ │ │ ├── AgentWebSettingsImpl.java
│ │ │ ├── AgentWebUIControllerImplBase.java
│ │ │ ├── AgentWebUtils.java
│ │ │ ├── AgentWebView.java
│ │ │ ├── BaseIndicatorSpec.java
│ │ │ ├── BaseIndicatorView.java
│ │ │ ├── BaseJsAccessEntrace.java
│ │ │ ├── DefaultChromeClient.java
│ │ │ ├── DefaultDesignUIController.java
│ │ │ ├── DefaultDownloadImpl.java
│ │ │ ├── DefaultUIController.java
│ │ │ ├── DefaultWebClient.java
│ │ │ ├── DefaultWebCreator.java
│ │ │ ├── DefaultWebLifeCycleImpl.java
│ │ │ ├── EventHandlerImpl.java
│ │ │ ├── EventInterceptor.java
│ │ │ ├── HookManager.java
│ │ │ ├── HttpHeaders.java
│ │ │ ├── IAgentWebSettings.java
│ │ │ ├── IEventHandler.java
│ │ │ ├── IUrlLoader.java
│ │ │ ├── IVideo.java
│ │ │ ├── IWebIndicator.java
│ │ │ ├── IWebLayout.java
│ │ │ ├── IndicatorController.java
│ │ │ ├── IndicatorHandler.java
│ │ │ ├── JsAccessEntrace.java
│ │ │ ├── JsAccessEntraceImpl.java
│ │ │ ├── JsBaseInterfaceHolder.java
│ │ │ ├── JsCallJava.java
│ │ │ ├── JsCallback.java
│ │ │ ├── JsInterfaceHolder.java
│ │ │ ├── JsInterfaceHolderImpl.java
│ │ │ ├── JsInterfaceObjectException.java
│ │ │ ├── LayoutParamsOffer.java
│ │ │ ├── LogUtils.java
│ │ │ ├── LollipopFixedWebView.java
│ │ │ ├── MiddlewareWebChromeBase.java
│ │ │ ├── MiddlewareWebClientBase.java
│ │ │ ├── NestedScrollAgentWebView.java
│ │ │ ├── PermissionInterceptor.java
│ │ │ ├── ProcessUtils.java
│ │ │ ├── Provider.java
│ │ │ ├── QuickCallJs.java
│ │ │ ├── RomUtils.java
│ │ │ ├── UrlCommonException.java
│ │ │ ├── UrlLoaderImpl.java
│ │ │ ├── VideoImpl.java
│ │ │ ├── WebChromeClient.java
│ │ │ ├── WebChromeClientDelegate.java
│ │ │ ├── WebCreator.java
│ │ │ ├── WebIndicator.java
│ │ │ ├── WebLifeCycle.java
│ │ │ ├── WebListenerManager.java
│ │ │ ├── WebParentLayout.java
│ │ │ ├── WebSecurityCheckLogic.java
│ │ │ ├── WebSecurityController.java
│ │ │ ├── WebSecurityControllerImpl.java
│ │ │ ├── WebSecurityLogicImpl.java
│ │ │ ├── WebViewClient.java
│ │ │ └── WebViewClientDelegate.java
│ │ └── res/
│ │ ├── layout/
│ │ │ └── agentweb_error_page.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── ids.xml
│ │ │ ├── strings.xml
│ │ │ └── style.xml
│ │ ├── values-zh/
│ │ │ └── strings.xml
│ │ └── xml/
│ │ └── web_files_public.xml
│ └── test/
│ └── java/
│ └── com/
│ └── just/
│ └── agentweb/
│ └── ExampleUnitTest.java
├── agentweb-filechooser/
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── com/
│ │ └── just/
│ │ └── agentweb/
│ │ └── filechooser/
│ │ └── ExampleInstrumentedTest.java
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── just/
│ │ │ └── agentweb/
│ │ │ └── filechooser/
│ │ │ ├── FileChooser.java
│ │ │ ├── FileCompressor.java
│ │ │ └── FileParcel.java
│ │ └── res/
│ │ └── values/
│ │ └── strings.xml
│ └── test/
│ └── java/
│ └── com/
│ └── just/
│ └── agentweb/
│ └── filechooser/
│ └── ExampleUnitTest.java
├── agentweb.apk
├── build.gradle
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── jitpack.yml
├── releasenote.md
├── sample/
│ ├── .gitignore
│ ├── build.gradle
│ ├── keystore/
│ │ └── keystore.jks
│ ├── keystore.jks
│ ├── libs/
│ │ └── alipaySdk-20180601.jar
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── com/
│ │ └── just/
│ │ └── agentweb/
│ │ └── sample/
│ │ └── ExampleInstrumentedTest.java
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── assets/
│ │ │ ├── js_interaction/
│ │ │ │ ├── button.css
│ │ │ │ └── hello.html
│ │ │ ├── jsbridge/
│ │ │ │ └── demo.html
│ │ │ ├── sms/
│ │ │ │ └── sms.html
│ │ │ └── upload_file/
│ │ │ ├── event.js
│ │ │ ├── jsuploadfile.html
│ │ │ ├── upload.css
│ │ │ └── uploadfile.html
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── just/
│ │ │ └── agentweb/
│ │ │ └── sample/
│ │ │ ├── activity/
│ │ │ │ ├── AutoHidenToolbarActivity.java
│ │ │ │ ├── BaseWebActivity.java
│ │ │ │ ├── CommonActivity.java
│ │ │ │ ├── ContainerActivity.java
│ │ │ │ ├── EasyWebActivity.java
│ │ │ │ ├── ExternalActivity.java
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── NativeDownloadActivity.java
│ │ │ │ ├── RemoteWebViewlActivity.java
│ │ │ │ └── WebActivity.java
│ │ │ ├── api/
│ │ │ │ └── Api.java
│ │ │ ├── app/
│ │ │ │ └── App.java
│ │ │ ├── base/
│ │ │ │ ├── BaseAgentWebActivity.java
│ │ │ │ ├── BaseAgentWebFragment.java
│ │ │ │ └── FragmentKeyDown.java
│ │ │ ├── behavior/
│ │ │ │ └── BottomNavigationViewBehavior.java
│ │ │ ├── client/
│ │ │ │ ├── MiddlewareChromeClient.java
│ │ │ │ ├── MiddlewareWebViewClient.java
│ │ │ │ └── SonicWebViewClient.java
│ │ │ ├── common/
│ │ │ │ ├── AndroidInterface.java
│ │ │ │ ├── CommonWebChromeClient.java
│ │ │ │ ├── CustomSettings.java
│ │ │ │ ├── FragmentKeyDown.java
│ │ │ │ ├── GuideItemEntity.java
│ │ │ │ └── UIController.java
│ │ │ ├── fragment/
│ │ │ │ ├── AgentWebFragment.java
│ │ │ │ ├── BounceWebFragment.java
│ │ │ │ ├── CustomIndicatorFragment.java
│ │ │ │ ├── CustomSettingsFragment.java
│ │ │ │ ├── CustomWebViewFragment.java
│ │ │ │ ├── EasyWebFragment.java
│ │ │ │ ├── JsAgentWebFragment.java
│ │ │ │ ├── JsbridgeWebFragment.java
│ │ │ │ ├── SmartRefreshWebFragment.java
│ │ │ │ └── VasSonicFragment.java
│ │ │ ├── provider/
│ │ │ │ ├── ServiceProvider.java
│ │ │ │ └── WebServiceProvider.java
│ │ │ ├── service/
│ │ │ │ └── WebService.java
│ │ │ ├── sonic/
│ │ │ │ ├── DefaultSonicRuntimeImpl.java
│ │ │ │ ├── SonicImpl.java
│ │ │ │ ├── SonicJavaScriptInterface.java
│ │ │ │ ├── SonicSessionClientImpl.java
│ │ │ │ └── SonicWebViewClient.java
│ │ │ ├── utils/
│ │ │ │ ├── FileUtils.java
│ │ │ │ ├── ProcessUtils.java
│ │ │ │ └── WebCompat.java
│ │ │ └── widget/
│ │ │ ├── CommonIndicator.java
│ │ │ ├── CoolIndicatorLayout.java
│ │ │ ├── SmartRefreshWebLayout.java
│ │ │ └── WebLayout.java
│ │ └── res/
│ │ ├── drawable/
│ │ │ ├── btn_shape.xml
│ │ │ ├── btn_shape_s.xml
│ │ │ ├── ic_baseline_search_24.xml
│ │ │ ├── indicator_shape.xml
│ │ │ ├── iv_back_selector.xml
│ │ │ └── selector_drawable_for_btn.xml
│ │ ├── drawable-v21/
│ │ │ ├── ripple_for_btn.xml
│ │ │ └── selector_drawable_for_btn.xml
│ │ ├── layout/
│ │ │ ├── activity_auto_hiden_toolbar.xml
│ │ │ ├── activity_common.xml
│ │ │ ├── activity_main.xml
│ │ │ ├── activity_native_download.xml
│ │ │ ├── activity_web.xml
│ │ │ ├── fragment_agentweb.xml
│ │ │ ├── fragment_js.xml
│ │ │ ├── fragment_srl_web.xml
│ │ │ ├── fragment_twk_web.xml
│ │ │ ├── listview_main.xml
│ │ │ ├── markdown_view.xml
│ │ │ ├── recyclerview_item_download.xml
│ │ │ └── toorbar_main.xml
│ │ ├── menu/
│ │ │ └── toolbar_menu.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── xml/
│ │ └── network_security_config.xml
│ └── test/
│ └── java/
│ └── com/
│ └── just/
│ └── agentweb/
│ └── sample/
│ └── ExampleUnitTest.java
└── settings.gradle
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
custom: # Replace with a single custom sponsorship URL
================================================
FILE: .gitignore
================================================
*.iml
.gradle
.idea
/local.properties
.DS_Store
/build
/captures
.externalNativeBuild
# Built application files
# *.apk
*.ap_
# Files for the ART/Dalvik VM
*.dex
# Java class files
*.class
# Generated files
bin/
gen/
out/
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
# Proguard folder generated by Eclipse
proguard/
# Log Files
*.log
# Android Studio Navigation editor temp files
.navigation/
# Android Studio captures folder
captures/
# Intellij
*.iml
.idea/workspace.xml
local.properties
# Keystore files
#*.jks
app/keystore/
#sample/keystore/
library/src/main/res/mipmap-xxhdpi/
sample/sampledata/
node_modules
package-lock.json
package.json
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
onResult of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
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.
================================================
FILE: README.md
================================================
<div style="display: flex;flex-direction: row;justify-content: center" width="100%">
<img src="./img/logo.png"></img>
</div>
## AgentWeb 介绍
AgentWeb 是一个基于的 Android WebView ,极度容易使用以及功能强大的库,提供了 Android WebView 一系列的问题解决方案 ,并且轻量和极度灵活,详细使用请参照上面的 Sample 。
## Gradle 引入
```groovy
allprojects {
repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
```
* Androidx
```groovy
implementation 'io.github.justson:agentweb-core:v5.1.1-androidx'
implementation 'io.github.justson:agentweb-filechooser:v5.1.1-androidx' // (可选)
implementation 'com.github.Justson:Downloader:v5.0.4-androidx' // (可选)
```
## 相关
* [flying-pigeon跨进程IPC组件](https://github.com/Justson/flying-pigeon)
* [AgentWebX5](https://github.com/Justson/AgentWebX5)
* [WebView 进度条](https://github.com/Justson/CoolIndicator)
* [Downloader 一个轻量的文件下载器](https://github.com/Justson/Downloader)
## 注意事项
* 支付宝使用需要引入支付宝SDK ,并在项目中依赖 , 微信支付不需要做任何操作。
* AgentWeb 内部使用了 `AlertDialog` 需要依赖 `AppCompat` 主题 。
* `setAgentWebParent` 不支持 `ConstraintLayout` 。
* `mAgentWeb.getWebLifeCycle().onPause();`会暂停应用内所有`WebView` 。
* `minSdkVersion` 低于等于16以下自定义`WebView`请注意与 `JS` 之间通信安全。
## 文档帮助
* [Wiki](https://github.com/Justson/AgentWeb/wiki)(不全)
* `Sample`(推荐,详细)
* [更新日志](./releasenote.md)
## 有问题或者有更好的建议
* [![QQ0Group][qq0groupsvg]][qq0group]
* 欢迎提 [Issues](https://github.com/Justson/AgentWeb/issues)
## 赞赏
开源不易,你的支持是我更新的动力。
<a href="img/alipay.jpg"><img src="img/alipay.jpg" width="30%"/></a> <a href="img/wechat_pay.jpg"><img src="img/wechat_pay.jpg" width="30%"/></a> <a href="img/alipay.jpg"><img src="img/alipay.jpg" width="30%"/></a>
[licensesvg]: https://img.shields.io/badge/License-Apache--2.0-brightgreen.svg
[license]: https://github.com/Justson/AgentWeb/blob/master/LICENSE
[qq0groupsvg]: https://img.shields.io/badge/QQ群-599471474-fba7f9.svg
[qq0group]: http://qm.qq.com/cgi-bin/qm/qr?k=KpyfInzI2nr-Lh4StG0oh68GpbcD0vMG
[![License][licensesvg]][license]
## License
```
Copyright (C) Justson(https://github.com/Justson/AgentWeb)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
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.
```
================================================
FILE: agentweb-core/.gitignore
================================================
/build
================================================
FILE: agentweb-core/build.gradle
================================================
apply plugin: 'com.android.library'
apply plugin: 'maven-publish'
android {
compileSdk COMPILE_SDK_VERSION.toInteger()
defaultConfig {
minSdkVersion 14
targetSdkVersion TARGET_SDK_VERSION.toInteger()
namespace 'com.just.agentweb'
versionCode 3
versionName VERSION_NAME
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
repositories {
flatDir {
dirs 'libs', 'providedLibs'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
// defaultPublishConfig "debug"
}
dependencies {
compileOnly fileTree(include: ['*.jar'], dir: 'libs')
androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', {
exclude group: 'com.android.support', module: 'support-annotations'
})
testImplementation 'junit:junit:4.12'
compileOnly 'com.github.Justson:Downloader:v5.0.4-androidx'
compileOnly 'com.google.android.material:material:1.0.0'
compileOnly 'androidx.legacy:legacy-support-v4:1.0.0'
compileOnly fileTree(include: ['*.jar'], dir: 'providedLibs')
}
publishing {
publications {
// Creates a Maven publication called "release".
release(MavenPublication) {
groupId = 'com.github.Justson.AgentWeb'
artifactId = 'agentweb-core'
version = 'v5.0.7-androidx'
}
}
}
================================================
FILE: agentweb-core/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/cenxiaozhong/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.create.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
-keep class com.just.agentweb.** {
*;
}
-dontwarn com.just.agentweb.**
================================================
FILE: agentweb-core/src/androidTest/java/com/just/agentweb/ExampleInstrumentedTest.java
================================================
package com.just.agentweb;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumentation test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.just.library.test", appContext.getPackageName());
}
}
================================================
FILE: agentweb-core/src/main/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<provider
android:name="com.just.agentweb.AgentWebFileProvider"
android:authorities="${applicationId}.AgentWebFileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/web_files_public"/>
</provider>
</application>
</manifest>
================================================
FILE: agentweb-core/src/main/java/com/just/agentweb/AbsAgentWebSettings.java
================================================
/*
* Copyright (C) Justson(https://github.com/Justson/AgentWeb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
package com.just.agentweb;
import android.os.Build;
import android.view.View;
import android.webkit.DownloadListener;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
/**
* @author cenxiaozhong
* @update 4.0.0 ,WebDefaultSettingsManager rename to AbsAgentWebSettings
* @since 1.0.0
*/
public abstract class AbsAgentWebSettings implements IAgentWebSettings, WebListenerManager {
private WebSettings mWebSettings;
private static final String TAG = AbsAgentWebSettings.class.getSimpleName();
public static final String USERAGENT_UC = " UCBrowser/11.6.4.950 ";
public static final String USERAGENT_QQ_BROWSER = " MQQBrowser/8.0 ";
public static final String USERAGENT_AGENTWEB = " " + AgentWebConfig.AGENTWEB_VERSION + " ";
protected AgentWeb mAgentWeb;
public static AbsAgentWebSettings getInstance() {
return new AgentWebSettingsImpl();
}
public AbsAgentWebSettings() {
}
final void bindAgentWeb(AgentWeb agentWeb) {
this.mAgentWeb = agentWeb;
this.bindAgentWebSupport(agentWeb);
}
protected abstract void bindAgentWebSupport(AgentWeb agentWeb);
@Override
public IAgentWebSettings toSetting(WebView webView) {
settings(webView);
return this;
}
private void settings(WebView webView) {
mWebSettings = webView.getSettings();
mWebSettings.setJavaScriptEnabled(true);
mWebSettings.setSupportZoom(true);
mWebSettings.setBuiltInZoomControls(false);
mWebSettings.setSavePassword(false);
if (AgentWebUtils.checkNetwork(webView.getContext().getApplicationContext())) {
//根据cache-control获取数据。
mWebSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
} else {
//没网,则从本地获取,即离线加载
mWebSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//适配5.0不允许http和https混合使用情况
mWebSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
mWebSettings.setTextZoom(100);
mWebSettings.setDatabaseEnabled(true);
mWebSettings.setLoadsImagesAutomatically(true);
mWebSettings.setSupportMultipleWindows(false);
// 是否阻塞加载网络图片 协议http or https
mWebSettings.setBlockNetworkImage(false);
// 允许加载本地文件html file协议
mWebSettings.setAllowFileAccess(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
// 通过 file url 加载的 Javascript 读取其他的本地文件 .建议关闭
mWebSettings.setAllowFileAccessFromFileURLs(false);
// 允许通过 file url 加载的 Javascript 可以访问其他的源,包括其他的文件和 http,https 等其他的源
mWebSettings.setAllowUniversalAccessFromFileURLs(false);
}
mWebSettings.setJavaScriptCanOpenWindowsAutomatically(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
mWebSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
} else {
mWebSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
}
mWebSettings.setLoadWithOverviewMode(false);
mWebSettings.setUseWideViewPort(false);
mWebSettings.setDomStorageEnabled(true);
mWebSettings.setNeedInitialFocus(true);
mWebSettings.setDefaultTextEncodingName("utf-8");//设置编码格式
mWebSettings.setDefaultFontSize(16);
mWebSettings.setMinimumFontSize(12);//设置 WebView 支持的最小字体大小,默认为 8
mWebSettings.setGeolocationEnabled(true);
String dir = AgentWebConfig.getCachePath(webView.getContext());
LogUtils.i(TAG, "dir:" + dir + " appcache:" + AgentWebConfig.getCachePath(webView.getContext()));
//设置数据库路径 api19 已经废弃,这里只针对 webkit 起作用
mWebSettings.setGeolocationDatabasePath(dir);
mWebSettings.setDatabasePath(dir);
mWebSettings.setUserAgentString(getWebSettings()
.getUserAgentString()
.concat(USERAGENT_AGENTWEB)
.concat(USERAGENT_UC)
);
LogUtils.i(TAG, "UserAgentString : " + mWebSettings.getUserAgentString());
}
@Override
public WebSettings getWebSettings() {
return mWebSettings;
}
@Override
public WebListenerManager setWebChromeClient(WebView webview, WebChromeClient webChromeClient) {
webview.setWebChromeClient(webChromeClient);
return this;
}
@Override
public WebListenerManager setWebViewClient(WebView webView, WebViewClient webViewClient) {
webView.setWebViewClient(webViewClient);
return this;
}
@Override
public WebListenerManager setDownloader(WebView webView, DownloadListener downloadListener) {
webView.setDownloadListener(downloadListener);
return this;
}
}
================================================
FILE: agentweb-core/src/main/java/com/just/agentweb/AbsAgentWebUIController.java
================================================
/*
* Copyright (C) Justson(https://github.com/Justson/AgentWeb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
package com.just.agentweb;
import android.app.Activity;
import android.app.Dialog;
import android.net.http.SslError;
import android.os.Handler;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.PermissionRequest;
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
/**
* 该类统一控制了与用户交互的界面
*
* @author cenxiaozhong
* @since 3.0.0
*/
public abstract class AbsAgentWebUIController {
public static boolean HAS_DESIGN_LIB = false;
private Activity mActivity;
private WebParentLayout mWebParentLayout;
private volatile boolean mIsBindWebParent = false;
protected AbsAgentWebUIController mAgentWebUIControllerDelegate;
protected String TAG = this.getClass().getSimpleName();
static {
try {
Class.forName("com.google.android.material.snackbar.Snackbar");
Class.forName("com.google.android.material.bottomsheet.BottomSheetDialog");
HAS_DESIGN_LIB = true;
} catch (Throwable ignore) {
HAS_DESIGN_LIB = false;
if (LogUtils.isDebug()) {
ignore.printStackTrace();
}
}
}
protected AbsAgentWebUIController create() {
return HAS_DESIGN_LIB ? new DefaultDesignUIController() : new DefaultUIController();
}
protected AbsAgentWebUIController getDelegate() {
AbsAgentWebUIController mAgentWebUIController = this.mAgentWebUIControllerDelegate;
if (mAgentWebUIController == null) {
this.mAgentWebUIControllerDelegate = mAgentWebUIController = create();
}
return mAgentWebUIController;
}
final synchronized void bindWebParent(WebParentLayout webParentLayout, Activity activity) {
if (!mIsBindWebParent) {
mIsBindWebParent = true;
this.mWebParentLayout = webParentLayout;
this.mActivity = activity;
bindSupportWebParent(webParentLayout, activity);
}
}
protected void toDismissDialog(Dialog dialog) {
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
}
protected void toShowDialog(Dialog dialog) {
if (dialog != null && !dialog.isShowing()) {
dialog.show();
}
}
protected abstract void bindSupportWebParent(WebParentLayout webParentLayout, Activity activity);
/**
* WebChromeClient#onJsAlert
*
* @param view
* @param url
* @param message
*/
public abstract void onJsAlert(WebView view, String url, String message);
/**
* 咨询用户是否前往其他页面
*
* @param view
* @param url
* @param callback
*/
public abstract void onOpenPagePrompt(WebView view, String url, Handler.Callback callback);
/**
* WebChromeClient#onJsConfirm
*
* @param view
* @param url
* @param message
* @param jsResult
*/
public abstract void onJsConfirm(WebView view, String url, String message, JsResult jsResult);
public abstract void onSelectItemsPrompt(WebView view, String url, String[] ways, Handler.Callback callback);
/**
* 强制下载弹窗
*
* @param url 当前下载地址。
* @param callback 用户操作回调回调
*/
public abstract void onForceDownloadAlert(String url, Handler.Callback callback);
/**
* WebChromeClient#onJsPrompt
*
* @param view
* @param url
* @param message
* @param defaultValue
* @param jsPromptResult
*/
public abstract void onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult jsPromptResult);
/**
* 显示错误页
*
* @param view
* @param errorCode
* @param description
* @param failingUrl
*/
public abstract void onMainFrameError(WebView view, int errorCode, String description, String failingUrl);
/**
* 隐藏错误页
*/
public abstract void onShowMainFrame();
/**
* 正在加载...
*
* @param msg
*/
public abstract void onLoading(String msg);
/**
* 取消正在加载...
*/
public abstract void onCancelLoading();
/**
* @param message 消息
* @param intent 说明message的来源,意图
*/
public abstract void onShowMessage(String message, String intent);
/**
* 当权限被拒回调该方法
*
* @param permissions
* @param permissionType
* @param action
*/
public abstract void onPermissionsDeny(String[] permissions, String permissionType, String action);
/**
*
* @param view
* @param handler
* @param error
*/
public abstract void onShowSslCertificateErrorDialog(WebView view, SslErrorHandler handler, SslError error);
/**
* 权限请求
* @param request
*/
public abstract void onPermissionRequest(PermissionRequest request);
}
================================================
FILE: agentweb-core/src/main/java/com/just/agentweb/Action.java
================================================
/*
* Copyright (C) Justson(https://github.com/Justson/AgentWeb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
package com.just.agentweb;
import android.content.Intent;
import android.net.Uri;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author cenxiaozhong
* @since 2.0.0
*/
public final class Action {
public transient static final int ACTION_PERMISSION = 1;
public transient static final int ACTION_FILE = 2;
public transient static final int ACTION_CAMERA = 3;
public transient static final int ACTION_VIDEO = 4;
private ArrayList<String> mPermissions = new ArrayList<>();
private int mAction;
private int mFromIntention;
private Intent mIntent;
private Uri mUri;
private AgentActionFragment.RationaleListener mRationaleListener;
private AgentActionFragment.PermissionListener mPermissionListener;
private AgentActionFragment.ChooserListener mChooserListener;
public Action() {
}
public ArrayList<String> getPermissions() {
return mPermissions;
}
public void setPermissions(ArrayList<String> permissions) {
this.mPermissions = permissions;
}
public void setPermissions(String[] permissions) {
this.mPermissions = new ArrayList<>(Arrays.asList(permissions));
}
public int getAction() {
return mAction;
}
public void setAction(int action) {
this.mAction = action;
}
public int getFromIntention() {
return mFromIntention;
}
public static Action createPermissionsAction(String[] permissions) {
Action mAction = new Action();
mAction.setAction(Action.ACTION_PERMISSION);
List<String> mList = Arrays.asList(permissions);
mAction.setPermissions(new ArrayList<String>(mList));
return mAction;
}
public Action setFromIntention(int fromIntention) {
this.mFromIntention = fromIntention;
return this;
}
public AgentActionFragment.RationaleListener getRationaleListener() {
return mRationaleListener;
}
public void setRationaleListener(AgentActionFragment.RationaleListener rationaleListener) {
mRationaleListener = rationaleListener;
}
public AgentActionFragment.PermissionListener getPermissionListener() {
return mPermissionListener;
}
public void setPermissionListener(AgentActionFragment.PermissionListener permissionListener) {
mPermissionListener = permissionListener;
}
public AgentActionFragment.ChooserListener getChooserListener() {
return mChooserListener;
}
public void setChooserListener(AgentActionFragment.ChooserListener chooserListener) {
mChooserListener = chooserListener;
}
public Intent getIntent() {
return mIntent;
}
public Uri getUri() {
return mUri;
}
public void setUri(Uri uri) {
mUri = uri;
}
public void setIntent(Intent intent) {
mIntent = intent;
}
}
================================================
FILE: agentweb-core/src/main/java/com/just/agentweb/AgentActionFragment.java
================================================
/*
* Copyright (C) Justson(https://github.com/Justson/AgentWeb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
package com.just.agentweb;
import static android.provider.MediaStore.EXTRA_OUTPUT;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import java.io.File;
import java.util.List;
/**
* @author cenxiaozhong
* @since 2.0.0
*/
public final class AgentActionFragment extends Fragment {
public static final String KEY_URI = "KEY_URI";
public static final String KEY_FROM_INTENTION = "KEY_FROM_INTENTION";
private static final String TAG = AgentActionFragment.class.getSimpleName();
private Action mAction;
public static final int REQUEST_CODE = 0x254;
public static final String FRAGMENT_TAG = "AgentWebActionFragment";
public static void start(Activity activity, Action action) {
FragmentActivity fragmentActivity = (FragmentActivity) activity;
FragmentManager fragmentManager = fragmentActivity.getSupportFragmentManager();
AgentActionFragment fragment = (AgentActionFragment) fragmentManager.findFragmentByTag(FRAGMENT_TAG);
if (fragment == null) {
fragment = new AgentActionFragment();
fragmentManager.beginTransaction().add(fragment, FRAGMENT_TAG).commitAllowingStateLoss();
}
fragment.mAction = action;
if (fragment.isViewCreated) {
fragment.runAction();
}
}
public AgentActionFragment() {
}
private void resetAction() {
// mAction = null;
}
private boolean isViewCreated = false;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
LogUtils.i(TAG, "savedInstanceState:" + savedInstanceState);
return;
}
isViewCreated = true;
runAction();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
private void runAction() {
if (mAction == null) {
resetAction();
return;
}
if (mAction.getAction() == Action.ACTION_PERMISSION) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermission(mAction);
} else {
resetAction();
}
} else if (mAction.getAction() == Action.ACTION_CAMERA) {
captureCamera();
} else if (mAction.getAction() == Action.ACTION_VIDEO) {
recordVideo();
} else {
choose();
}
}
private void choose() {
try {
if (mAction.getChooserListener() == null) {
return;
}
Intent mIntent = mAction.getIntent();
if (mIntent == null) {
resetAction();
return;
}
this.startActivityForResult(mIntent, REQUEST_CODE);
} catch (Throwable throwable) {
LogUtils.i(TAG, "找不到文件选择器");
chooserActionCallback(-1, null);
if (LogUtils.isDebug()) {
throwable.printStackTrace();
}
}
}
private void chooserActionCallback(int resultCode, Intent data) {
if (mAction.getChooserListener() != null) {
mAction.getChooserListener().onChoiceResult(REQUEST_CODE, resultCode, data);
}
resetAction();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (mAction == null) {
return;
}
if (requestCode == REQUEST_CODE) {
if (mAction.getUri() != null) {
chooserActionCallback(resultCode, new Intent().putExtra(KEY_URI, mAction.getUri()));
} else {
chooserActionCallback(resultCode, data);
}
}
resetAction();
}
@RequiresApi(api = Build.VERSION_CODES.M)
private void requestPermission(Action action) {
List<String> permissions = action.getPermissions();
if (AgentWebUtils.isEmptyCollection(permissions)) {
resetAction();
return;
}
if (mAction.getRationaleListener() != null) {
boolean rationale = false;
for (String permission : permissions) {
rationale = shouldShowRequestPermissionRationale(permission);
if (rationale) {
break;
}
}
mAction.getRationaleListener().onRationaleResult(rationale, new Bundle());
resetAction();
return;
}
if (mAction.getPermissionListener() != null) {
requestPermissions(permissions.toArray(new String[]{}), 1);
}
}
private void captureCamera() {
try {
if (mAction.getChooserListener() == null) {
resetAction();
return;
}
File mFile = AgentWebUtils.createImageFile(this.getActivity());
if (mFile == null) {
mAction.getChooserListener().onChoiceResult(REQUEST_CODE, Activity.RESULT_CANCELED, null);
}
Intent intent = AgentWebUtils.getIntentCaptureCompat(getActivity(), mFile);
// 指定开启系统相机的Action
mAction.setUri((Uri) intent.getParcelableExtra(EXTRA_OUTPUT));
this.startActivityForResult(intent, REQUEST_CODE);
} catch (Throwable ignore) {
LogUtils.e(TAG, "找不到系统相机");
if (mAction.getChooserListener() != null) {
mAction.getChooserListener().onChoiceResult(REQUEST_CODE, Activity.RESULT_CANCELED, null);
}
resetAction();
if (LogUtils.isDebug()) {
ignore.printStackTrace();
}
}
}
private void recordVideo() {
try {
if (mAction.getChooserListener() == null) {
resetAction();
return;
}
File mFile = AgentWebUtils.createVideoFile(this.getActivity());
if (mFile == null) {
mAction.getChooserListener().onChoiceResult(REQUEST_CODE, Activity.RESULT_CANCELED, null);
resetAction();
return;
}
Intent intent = AgentWebUtils.getIntentVideoCompat(getActivity(), mFile);
// 指定开启系统相机的Action
mAction.setUri((Uri) intent.getParcelableExtra(EXTRA_OUTPUT));
this.startActivityForResult(intent, REQUEST_CODE);
} catch (Throwable ignore) {
LogUtils.e(TAG, "找不到系统相机");
if (mAction.getChooserListener() != null) {
mAction.getChooserListener().onChoiceResult(REQUEST_CODE, Activity.RESULT_CANCELED, null);
}
resetAction();
if (LogUtils.isDebug()) {
ignore.printStackTrace();
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (mAction.getPermissionListener() != null) {
Bundle mBundle = new Bundle();
mBundle.putInt(KEY_FROM_INTENTION, mAction.getFromIntention());
mAction.getPermissionListener().onRequestPermissionsResult(permissions, grantResults, mBundle);
}
resetAction();
}
public interface RationaleListener {
void onRationaleResult(boolean showRationale, Bundle extras);
}
public interface PermissionListener {
void onRequestPermissionsResult(@NonNull String[] permissions, @NonNull int[] grantResults, Bundle extras);
}
public interface ChooserListener {
void onChoiceResult(int requestCode, int resultCode, Intent data);
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
================================================
FILE: agentweb-core/src/main/java/com/just/agentweb/AgentWeb.java
================================================
/*
* Copyright (C) Justson(https://github.com/Justson/AgentWeb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
package com.just.agentweb;
import android.app.Activity;
import androidx.annotation.ColorInt;
import androidx.annotation.IdRes;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.collection.ArrayMap;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import java.lang.ref.WeakReference;
import java.util.Map;
/**
* @author cenxiaozhong
* @update 4.0.0
* @since 1.0.0
*/
public final class AgentWeb {
/**
* AgentWeb 's TAG
*/
private static final String TAG = AgentWeb.class.getSimpleName();
/**
* Activity
*/
private Activity mActivity;
/**
* 承载 WebParentLayout 的 ViewGroup
*/
private ViewGroup mViewGroup;
/**
* 负责创建布局 WebView ,WebParentLayout Indicator等。
*/
private WebCreator mWebCreator;
/**
* 管理 WebSettings
*/
private IAgentWebSettings mAgentWebSettings;
/**
* AgentWeb
*/
private AgentWeb mAgentWeb = null;
/**
* IndicatorController 控制Indicator
*/
private IndicatorController mIndicatorController;
/**
* WebChromeClient
*/
private com.just.agentweb.WebChromeClient mWebChromeClient;
/**
* WebViewClient
*/
private com.just.agentweb.WebViewClient mWebViewClient;
/**
* is show indicator
*/
private boolean mEnableIndicator;
/**
* IEventHandler 处理WebView相关返回事件
*/
private IEventHandler mIEventHandler;
/**
* WebView 注入对象
*/
private ArrayMap<String, Object> mJavaObjects = new ArrayMap<>();
/**
* flag
*/
private int mTagTarget = 0;
/**
* WebListenerManager
*/
private WebListenerManager mWebListenerManager;
/**
* 安全 Controller
*/
private WebSecurityController<WebSecurityCheckLogic> mWebSecurityController = null;
/**
* WebSecurityCheckLogic
*/
private WebSecurityCheckLogic mWebSecurityCheckLogic = null;
/**
* WebChromeClient
*/
private WebChromeClient mTargetChromeClient;
/**
* flag security 's mode
*/
private SecurityType mSecurityType = SecurityType.DEFAULT_CHECK;
/**
* Activity
*/
private static final int ACTIVITY_TAG = 0;
/**
* Fragment
*/
private static final int FRAGMENT_TAG = 1;
/**
* AgentWeb 默认注入对像
*/
private AgentWebJsInterfaceCompat mAgentWebJsInterfaceCompat = null;
/**
* JsAccessEntrace 提供快速JS方法调用
*/
private JsAccessEntrace mJsAccessEntrace = null;
/**
* URL Loader , 提供了 WebView#loadUrl(url) reload() stopLoading() postUrl()等方法
*/
private IUrlLoader mIUrlLoader = null;
/**
* WebView 生命周期 , 跟随生命周期释放CPU
*/
private WebLifeCycle mWebLifeCycle;
/**
* Video 视屏播放管理类
*/
private IVideo mIVideo = null;
/**
* WebViewClient 辅助控制开关
*/
private boolean mWebClientHelper = true;
/**
* PermissionInterceptor 权限拦截
*/
private PermissionInterceptor mPermissionInterceptor;
/**
* 是否拦截未知的Url, @link{DefaultWebClient}
*/
private boolean mIsInterceptUnkownUrl = true;
/**
* Url处理方式,是直接跳转还是弹窗让用户去选择
*/
private int mUrlHandleWays = -1;
/**
* MiddlewareWebClientBase WebViewClient 中间件
*/
private MiddlewareWebClientBase mMiddleWrareWebClientBaseHeader;
/**
* MiddlewareWebChromeBase WebChromeClient 中间件
*/
private MiddlewareWebChromeBase mMiddlewareWebChromeBaseHeader;
/**
* 事件拦截
*/
private EventInterceptor mEventInterceptor;
/**
* 注入对象管理类
*/
private JsInterfaceHolder mJsInterfaceHolder = null;
private AgentWeb(AgentBuilder agentBuilder) {
mTagTarget = agentBuilder.mTag;
this.mActivity = agentBuilder.mActivity;
this.mViewGroup = agentBuilder.mViewGroup;
this.mIEventHandler = agentBuilder.mIEventHandler;
this.mEnableIndicator = agentBuilder.mEnableIndicator;
mWebCreator = agentBuilder.mWebCreator == null ? configWebCreator(agentBuilder.mBaseIndicatorView, agentBuilder.mIndex, agentBuilder.mLayoutParams, agentBuilder.mIndicatorColor, agentBuilder.mHeight, agentBuilder.mWebView, agentBuilder.mWebLayout) : agentBuilder.mWebCreator;
mIndicatorController = agentBuilder.mIndicatorController;
this.mWebChromeClient = agentBuilder.mWebChromeClient;
this.mWebViewClient = agentBuilder.mWebViewClient;
mAgentWeb = this;
this.mAgentWebSettings = agentBuilder.mAgentWebSettings;
if (agentBuilder.mJavaObject != null && !agentBuilder.mJavaObject.isEmpty()) {
this.mJavaObjects.putAll((Map<? extends String, ?>) agentBuilder.mJavaObject);
LogUtils.i(TAG, "mJavaObject size:" + this.mJavaObjects.size());
}
this.mPermissionInterceptor = agentBuilder.mPermissionInterceptor == null ? null : new PermissionInterceptorWrapper(agentBuilder.mPermissionInterceptor);
this.mSecurityType = agentBuilder.mSecurityType;
this.mIUrlLoader = new UrlLoaderImpl(mWebCreator.create().getWebView(), agentBuilder.mHttpHeaders);
if (this.mWebCreator.getWebParentLayout() instanceof WebParentLayout) {
WebParentLayout mWebParentLayout = (WebParentLayout) this.mWebCreator.getWebParentLayout();
mWebParentLayout.bindController(agentBuilder.mAgentWebUIController == null ? AgentWebUIControllerImplBase.build() : agentBuilder.mAgentWebUIController);
mWebParentLayout.setErrorLayoutRes(agentBuilder.mErrorLayout, agentBuilder.mReloadId);
mWebParentLayout.setErrorView(agentBuilder.mErrorView);
}
this.mWebLifeCycle = new DefaultWebLifeCycleImpl(mWebCreator.getWebView());
mWebSecurityController = new WebSecurityControllerImpl(mWebCreator.getWebView(), this.mAgentWeb.mJavaObjects, this.mSecurityType);
this.mWebClientHelper = agentBuilder.mWebClientHelper;
this.mIsInterceptUnkownUrl = agentBuilder.mIsInterceptUnkownUrl;
if (agentBuilder.mOpenOtherPage != null) {
this.mUrlHandleWays = agentBuilder.mOpenOtherPage.code;
}
this.mMiddleWrareWebClientBaseHeader = agentBuilder.mMiddlewareWebClientBaseHeader;
this.mMiddlewareWebChromeBaseHeader = agentBuilder.mChromeMiddleWareHeader;
init();
}
/**
* @return PermissionInterceptor 权限控制者
*/
public PermissionInterceptor getPermissionInterceptor() {
return this.mPermissionInterceptor;
}
public WebLifeCycle getWebLifeCycle() {
return this.mWebLifeCycle;
}
public JsAccessEntrace getJsAccessEntrace() {
JsAccessEntrace mJsAccessEntrace = this.mJsAccessEntrace;
if (mJsAccessEntrace == null) {
this.mJsAccessEntrace = mJsAccessEntrace = JsAccessEntraceImpl.getInstance(mWebCreator.getWebView());
}
return mJsAccessEntrace;
}
public AgentWeb clearWebCache() {
if (this.getWebCreator().getWebView() != null) {
AgentWebUtils.clearWebViewAllCache(mActivity, this.getWebCreator().getWebView());
} else {
AgentWebUtils.clearWebViewAllCache(mActivity);
}
return this;
}
public static AgentBuilder with(@NonNull Activity activity) {
if (activity == null) {
throw new NullPointerException("activity can not be null .");
}
return new AgentBuilder(activity);
}
public static AgentBuilder with(@NonNull Fragment fragment) {
Activity mActivity = null;
if ((mActivity = fragment.getActivity()) == null) {
throw new NullPointerException("activity can not be null .");
}
return new AgentBuilder(mActivity, fragment);
}
public boolean handleKeyEvent(int keyCode, KeyEvent keyEvent) {
if (mIEventHandler == null) {
mIEventHandler = EventHandlerImpl.getInstantce(mWebCreator.getWebView(), getInterceptor());
}
return mIEventHandler.onKeyDown(keyCode, keyEvent);
}
public boolean back() {
if (mIEventHandler == null) {
mIEventHandler = EventHandlerImpl.getInstantce(mWebCreator.getWebView(), getInterceptor());
}
return mIEventHandler.back();
}
public WebCreator getWebCreator() {
return this.mWebCreator;
}
public IEventHandler getIEventHandler() {
return this.mIEventHandler == null ? (this.mIEventHandler = EventHandlerImpl.getInstantce(mWebCreator.getWebView(), getInterceptor())) : this.mIEventHandler;
}
public IAgentWebSettings getAgentWebSettings() {
return this.mAgentWebSettings;
}
public IndicatorController getIndicatorController() {
return this.mIndicatorController;
}
public JsInterfaceHolder getJsInterfaceHolder() {
return this.mJsInterfaceHolder;
}
public IUrlLoader getUrlLoader() {
return this.mIUrlLoader;
}
public void destroy() {
this.mWebLifeCycle.onDestroy();
}
public static class PreAgentWeb {
private AgentWeb mAgentWeb;
private boolean isReady = false;
PreAgentWeb(AgentWeb agentWeb) {
this.mAgentWeb = agentWeb;
}
public PreAgentWeb ready() {
if (!isReady) {
mAgentWeb.ready();
isReady = true;
}
return this;
}
public AgentWeb get() {
ready();
return mAgentWeb;
}
public AgentWeb go(@Nullable String url) {
if (!isReady) {
ready();
}
return mAgentWeb.go(url);
}
}
private void doSafeCheck() {
WebSecurityCheckLogic mWebSecurityCheckLogic = this.mWebSecurityCheckLogic;
if (mWebSecurityCheckLogic == null) {
this.mWebSecurityCheckLogic = mWebSecurityCheckLogic = WebSecurityLogicImpl.getInstance(mWebCreator.getWebViewType());
}
mWebSecurityController.check(mWebSecurityCheckLogic);
}
private void doCompat() {
mJavaObjects.put("agentWeb", mAgentWebJsInterfaceCompat = new AgentWebJsInterfaceCompat(this, mActivity));
}
private WebCreator configWebCreator(BaseIndicatorView progressView, int index, ViewGroup.LayoutParams lp, int indicatorColor, int height_dp, WebView webView, IWebLayout webLayout) {
if (progressView != null && mEnableIndicator) {
return new DefaultWebCreator(mActivity, mViewGroup, lp, index, progressView, webView, webLayout);
} else {
return mEnableIndicator ?
new DefaultWebCreator(mActivity, mViewGroup, lp, index, indicatorColor, height_dp, webView, webLayout)
: new DefaultWebCreator(mActivity, mViewGroup, lp, index, webView, webLayout);
}
}
private AgentWeb go(String url) {
this.getUrlLoader().loadUrl(url);
IndicatorController mIndicatorController = null;
if (!TextUtils.isEmpty(url) && (mIndicatorController = getIndicatorController()) != null && mIndicatorController.offerIndicator() != null) {
getIndicatorController().offerIndicator().show();
}
return this;
}
private EventInterceptor getInterceptor() {
if (this.mEventInterceptor != null) {
return this.mEventInterceptor;
}
if (mIVideo instanceof VideoImpl) {
return this.mEventInterceptor = (EventInterceptor) this.mIVideo;
}
return null;
}
private void init() {
doCompat();
doSafeCheck();
}
private IVideo getIVideo() {
return mIVideo == null ? new VideoImpl(mActivity, mWebCreator.getWebView()) : mIVideo;
}
private WebViewClient getWebViewClient() {
LogUtils.i(TAG, "getDelegate:" + this.mMiddleWrareWebClientBaseHeader);
DefaultWebClient mDefaultWebClient = DefaultWebClient
.createBuilder()
.setActivity(this.mActivity)
.setWebClientHelper(this.mWebClientHelper)
.setPermissionInterceptor(this.mPermissionInterceptor)
.setWebView(this.mWebCreator.getWebView())
.setInterceptUnkownUrl(this.mIsInterceptUnkownUrl)
.setUrlHandleWays(this.mUrlHandleWays)
.build();
MiddlewareWebClientBase header = this.mMiddleWrareWebClientBaseHeader;
if (this.mWebViewClient != null) {
this.mWebViewClient.enq(this.mMiddleWrareWebClientBaseHeader);
header = this.mWebViewClient;
}
if (header != null) {
MiddlewareWebClientBase tail = header;
int count = 1;
MiddlewareWebClientBase tmp = header;
while (tmp.next() != null) {
tail = tmp = tmp.next();
count++;
}
LogUtils.i(TAG, "MiddlewareWebClientBase middleware count:" + count);
tail.setDelegate(mDefaultWebClient);
return header;
} else {
return mDefaultWebClient;
}
}
private AgentWeb ready() {
AgentWebConfig.initCookiesManager(mActivity.getApplicationContext());
IAgentWebSettings mAgentWebSettings = this.mAgentWebSettings;
if (mAgentWebSettings == null) {
this.mAgentWebSettings = mAgentWebSettings = AgentWebSettingsImpl.getInstance();
}
if (mAgentWebSettings instanceof AbsAgentWebSettings) {
((AbsAgentWebSettings) mAgentWebSettings).bindAgentWeb(this);
}
if (mWebListenerManager == null && mAgentWebSettings instanceof AbsAgentWebSettings) {
mWebListenerManager = (WebListenerManager) mAgentWebSettings;
}
mAgentWebSettings.toSetting(mWebCreator.getWebView());
if (mJsInterfaceHolder == null) {
mJsInterfaceHolder = JsInterfaceHolderImpl.getJsInterfaceHolder(mWebCreator, this.mSecurityType);
}
LogUtils.i(TAG, "mJavaObjects:" + mJavaObjects.size());
if (mJavaObjects != null && !mJavaObjects.isEmpty()) {
mJsInterfaceHolder.addJavaObjects(mJavaObjects);
}
if (mWebListenerManager != null) {
mWebListenerManager.setDownloader(mWebCreator.getWebView(), null);
mWebListenerManager.setWebChromeClient(mWebCreator.getWebView(), getChromeClient());
mWebListenerManager.setWebViewClient(mWebCreator.getWebView(), getWebViewClient());
}
return this;
}
private WebChromeClient getChromeClient() {
IndicatorController mIndicatorController =
(this.mIndicatorController == null) ?
IndicatorHandler.getInstance().inJectIndicator(mWebCreator.offer())
: this.mIndicatorController;
DefaultChromeClient mDefaultChromeClient =
new DefaultChromeClient(this.mActivity,
this.mIndicatorController = mIndicatorController,
null, this.mIVideo = getIVideo(),
this.mPermissionInterceptor, mWebCreator.getWebView());
LogUtils.i(TAG, "WebChromeClient:" + this.mWebChromeClient);
MiddlewareWebChromeBase header = this.mMiddlewareWebChromeBaseHeader;
if (this.mWebChromeClient != null) {
this.mWebChromeClient.enq(header);
header = this.mWebChromeClient;
}
if (header != null) {
MiddlewareWebChromeBase tail = header;
int count = 1;
MiddlewareWebChromeBase tmp = header;
for (; tmp.next() != null; ) {
tail = tmp = tmp.next();
count++;
}
LogUtils.i(TAG, "MiddlewareWebClientBase middleware count:" + count);
tail.setDelegate(mDefaultChromeClient);
return this.mTargetChromeClient = header;
} else {
return this.mTargetChromeClient = mDefaultChromeClient;
}
}
public enum SecurityType {
DEFAULT_CHECK, STRICT_CHECK;
}
public static final class AgentBuilder {
private Activity mActivity;
private Fragment mFragment;
private ViewGroup mViewGroup;
private boolean mIsNeedDefaultProgress;
private int mIndex = -1;
private BaseIndicatorView mBaseIndicatorView;
private IndicatorController mIndicatorController = null;
/*默认进度条是显示的*/
private boolean mEnableIndicator = true;
private ViewGroup.LayoutParams mLayoutParams = null;
private com.just.agentweb.WebViewClient mWebViewClient;
private com.just.agentweb.WebChromeClient mWebChromeClient;
private int mIndicatorColor = -1;
private IAgentWebSettings mAgentWebSettings;
private WebCreator mWebCreator;
private HttpHeaders mHttpHeaders = null;
private IEventHandler mIEventHandler;
private int mHeight = -1;
private ArrayMap<String, Object> mJavaObject;
private SecurityType mSecurityType = SecurityType.DEFAULT_CHECK;
private WebView mWebView;
private boolean mWebClientHelper = true;
private IWebLayout mWebLayout = null;
private PermissionInterceptor mPermissionInterceptor = null;
private AbsAgentWebUIController mAgentWebUIController;
private DefaultWebClient.OpenOtherPageWays mOpenOtherPage = null;
private boolean mIsInterceptUnkownUrl = true;
private MiddlewareWebClientBase mMiddlewareWebClientBaseHeader;
private MiddlewareWebClientBase mMiddlewareWebClientBaseTail;
private MiddlewareWebChromeBase mChromeMiddleWareHeader = null;
private MiddlewareWebChromeBase mChromeMiddleWareTail = null;
private View mErrorView;
private int mErrorLayout;
private int mReloadId;
private int mTag = -1;
public AgentBuilder(@NonNull Activity activity, @NonNull Fragment fragment) {
mActivity = activity;
mFragment = fragment;
mTag = AgentWeb.FRAGMENT_TAG;
}
public AgentBuilder(@NonNull Activity activity) {
mActivity = activity;
mTag = AgentWeb.ACTIVITY_TAG;
}
public IndicatorBuilder setAgentWebParent(@NonNull ViewGroup v, @NonNull ViewGroup.LayoutParams lp) {
this.mViewGroup = v;
this.mLayoutParams = lp;
return new IndicatorBuilder(this);
}
public IndicatorBuilder setAgentWebParent(@NonNull ViewGroup v, int index, @NonNull ViewGroup.LayoutParams lp) {
this.mViewGroup = v;
this.mLayoutParams = lp;
this.mIndex = index;
return new IndicatorBuilder(this);
}
private PreAgentWeb buildAgentWeb() {
if (mTag == AgentWeb.FRAGMENT_TAG && this.mViewGroup == null) {
throw new NullPointerException("ViewGroup is null,Please check your parameters .");
}
return new PreAgentWeb(HookManager.hookAgentWeb(new AgentWeb(this), this));
}
private void addJavaObject(String key, Object o) {
if (mJavaObject == null) {
mJavaObject = new ArrayMap<>();
}
mJavaObject.put(key, o);
}
private void addHeader(String baseUrl, String k, String v) {
if (mHttpHeaders == null) {
mHttpHeaders = HttpHeaders.create();
}
mHttpHeaders.additionalHttpHeader(baseUrl, k, v);
}
private void addHeader(String baseUrl, Map<String, String> headers) {
if (mHttpHeaders == null) {
mHttpHeaders = HttpHeaders.create();
}
mHttpHeaders.additionalHttpHeaders(baseUrl, headers);
}
}
public static class IndicatorBuilder {
private AgentBuilder mAgentBuilder = null;
public IndicatorBuilder(AgentBuilder agentBuilder) {
this.mAgentBuilder = agentBuilder;
}
public CommonBuilder useDefaultIndicator(int color) {
this.mAgentBuilder.mEnableIndicator = true;
this.mAgentBuilder.mIndicatorColor = color;
return new CommonBuilder(mAgentBuilder);
}
public CommonBuilder useDefaultIndicator() {
this.mAgentBuilder.mEnableIndicator = true;
return new CommonBuilder(mAgentBuilder);
}
public CommonBuilder closeIndicator() {
this.mAgentBuilder.mEnableIndicator = false;
this.mAgentBuilder.mIndicatorColor = -1;
this.mAgentBuilder.mHeight = -1;
return new CommonBuilder(mAgentBuilder);
}
public CommonBuilder setCustomIndicator(@NonNull BaseIndicatorView v) {
if (v != null) {
this.mAgentBuilder.mEnableIndicator = true;
this.mAgentBuilder.mBaseIndicatorView = v;
this.mAgentBuilder.mIsNeedDefaultProgress = false;
} else {
this.mAgentBuilder.mEnableIndicator = true;
this.mAgentBuilder.mIsNeedDefaultProgress = true;
}
return new CommonBuilder(mAgentBuilder);
}
public CommonBuilder useDefaultIndicator(@ColorInt int color, int height_dp) {
this.mAgentBuilder.mIndicatorColor = color;
this.mAgentBuilder.mHeight = height_dp;
return new CommonBuilder(this.mAgentBuilder);
}
}
public static class CommonBuilder {
private AgentBuilder mAgentBuilder;
public CommonBuilder(AgentBuilder agentBuilder) {
this.mAgentBuilder = agentBuilder;
}
public CommonBuilder setEventHanadler(@Nullable IEventHandler iEventHandler) {
mAgentBuilder.mIEventHandler = iEventHandler;
return this;
}
public CommonBuilder closeWebViewClientHelper() {
mAgentBuilder.mWebClientHelper = false;
return this;
}
public CommonBuilder setWebChromeClient(@Nullable com.just.agentweb.WebChromeClient webChromeClient) {
this.mAgentBuilder.mWebChromeClient = webChromeClient;
return this;
}
public CommonBuilder setWebViewClient(@Nullable com.just.agentweb.WebViewClient webChromeClient) {
this.mAgentBuilder.mWebViewClient = webChromeClient;
return this;
}
public CommonBuilder useMiddlewareWebClient(@NonNull MiddlewareWebClientBase middleWrareWebClientBase) {
if (middleWrareWebClientBase == null) {
return this;
}
if (this.mAgentBuilder.mMiddlewareWebClientBaseHeader == null) {
this.mAgentBuilder.mMiddlewareWebClientBaseHeader = this.mAgentBuilder.mMiddlewareWebClientBaseTail = middleWrareWebClientBase;
} else {
this.mAgentBuilder.mMiddlewareWebClientBaseTail.enq(middleWrareWebClientBase);
this.mAgentBuilder.mMiddlewareWebClientBaseTail = middleWrareWebClientBase;
}
return this;
}
public CommonBuilder useMiddlewareWebChrome(@NonNull MiddlewareWebChromeBase middlewareWebChromeBase) {
if (middlewareWebChromeBase == null) {
return this;
}
if (this.mAgentBuilder.mChromeMiddleWareHeader == null) {
this.mAgentBuilder.mChromeMiddleWareHeader = this.mAgentBuilder.mChromeMiddleWareTail = middlewareWebChromeBase;
} else {
this.mAgentBuilder.mChromeMiddleWareTail.enq(middlewareWebChromeBase);
this.mAgentBuilder.mChromeMiddleWareTail = middlewareWebChromeBase;
}
return this;
}
public CommonBuilder setMainFrameErrorView(@NonNull View view) {
this.mAgentBuilder.mErrorView = view;
return this;
}
public CommonBuilder setMainFrameErrorView(@LayoutRes int errorLayout, @IdRes int clickViewId) {
this.mAgentBuilder.mErrorLayout = errorLayout;
this.mAgentBuilder.mReloadId = clickViewId;
return this;
}
public CommonBuilder setAgentWebWebSettings(@Nullable IAgentWebSettings agentWebSettings) {
this.mAgentBuilder.mAgentWebSettings = agentWebSettings;
return this;
}
public PreAgentWeb createAgentWeb() {
return this.mAgentBuilder.buildAgentWeb();
}
public CommonBuilder addJavascriptInterface(@NonNull String name, @NonNull Object o) {
this.mAgentBuilder.addJavaObject(name, o);
return this;
}
public CommonBuilder setSecurityType(@NonNull SecurityType type) {
this.mAgentBuilder.mSecurityType = type;
return this;
}
public CommonBuilder setWebView(@Nullable WebView webView) {
this.mAgentBuilder.mWebView = webView;
return this;
}
public CommonBuilder setWebLayout(@Nullable IWebLayout iWebLayout) {
this.mAgentBuilder.mWebLayout = iWebLayout;
return this;
}
public CommonBuilder additionalHttpHeader(String baseUrl, String k, String v) {
this.mAgentBuilder.addHeader(baseUrl, k, v);
return this;
}
public CommonBuilder additionalHttpHeader(String baseUrl, Map<String, String> headers) {
this.mAgentBuilder.addHeader(baseUrl, headers);
return this;
}
public CommonBuilder setPermissionInterceptor(@Nullable PermissionInterceptor permissionInterceptor) {
this.mAgentBuilder.mPermissionInterceptor = permissionInterceptor;
return this;
}
public CommonBuilder setAgentWebUIController(@Nullable AgentWebUIControllerImplBase agentWebUIController) {
this.mAgentBuilder.mAgentWebUIController = agentWebUIController;
return this;
}
public CommonBuilder setOpenOtherPageWays(@Nullable DefaultWebClient.OpenOtherPageWays openOtherPageWays) {
this.mAgentBuilder.mOpenOtherPage = openOtherPageWays;
return this;
}
public CommonBuilder interceptUnkownUrl() {
this.mAgentBuilder.mIsInterceptUnkownUrl = true;
return this;
}
public CommonBuilder isInterceptUnkownUrl(boolean isInterceptUnkownUrl) {
this.mAgentBuilder.mIsInterceptUnkownUrl = isInterceptUnkownUrl;
return this;
}
}
Activity getActivity() {
return this.mActivity;
}
private static final class PermissionInterceptorWrapper implements PermissionInterceptor {
private WeakReference<PermissionInterceptor> mWeakReference;
private PermissionInterceptorWrapper(PermissionInterceptor permissionInterceptor) {
this.mWeakReference = new WeakReference<PermissionInterceptor>(permissionInterceptor);
}
@Override
public boolean intercept(String url, String[] permissions, String a) {
if (this.mWeakReference.get() == null) {
return false;
}
return mWeakReference.get().intercept(url, permissions, a);
}
}
}
================================================
FILE: agentweb-core/src/main/java/com/just/agentweb/AgentWebCompat.java
================================================
package com.just.agentweb;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.text.TextUtils;
import android.webkit.WebView;
import java.io.File;
import java.io.RandomAccessFile;
import java.nio.channels.FileLock;
import java.util.HashSet;
import java.util.Set;
/**
* @author cenxiaozhong
* @date 2021/11/24
* @since 1.0.0
*/
public class AgentWebCompat {
/**
* 来之 https://github.com/Justson/AgentWeb/issues/934 建议
* https://juejin.cn/post/6950091477192015902
* fix Using WebView from more than one process
* @param context
*/
public static void setDataDirectorySuffix(Context context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
return;
}
try {
Set<String> pathSet = new HashSet<>();
String suffix = "";
String dataPath = context.getDataDir().getAbsolutePath();
String webViewDir = "/app_webview";
String huaweiWebViewDir = "/app_hws_webview";
String lockFile = "/webview_data.lock";
String processName = ProcessUtils.getCurrentProcessName(context);
if (!TextUtils.equals(context.getPackageName(), processName)) {//判断不等于默认进程名称
suffix = TextUtils.isEmpty(processName) ? context.getPackageName() : processName;
WebView.setDataDirectorySuffix(suffix);
suffix = "_" + suffix;
pathSet.add(dataPath + webViewDir + suffix + lockFile);
if (RomUtils.isHuawei()) {
pathSet.add(dataPath + huaweiWebViewDir + suffix + lockFile);
}
}else{
//主进程
suffix = "_" + processName;
pathSet.add(dataPath + webViewDir + lockFile);//默认未添加进程名后缀
pathSet.add(dataPath + webViewDir + suffix + lockFile);//系统自动添加了进程名后缀
if (RomUtils.isHuawei()) {//部分华为手机更改了webview目录名
pathSet.add(dataPath + huaweiWebViewDir + lockFile);
pathSet.add(dataPath + huaweiWebViewDir + suffix + lockFile);
}
}
for (String path : pathSet) {
File file = new File(path);
if (file.exists()) {
tryLockOrRecreateFile(file);
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
@TargetApi(Build.VERSION_CODES.P)
private static void tryLockOrRecreateFile(File file) {
try {
FileLock tryLock = new RandomAccessFile(file, "rw").getChannel().tryLock();
if (tryLock != null) {
tryLock.close();
} else {
createFile(file, file.delete());
}
} catch (Exception e) {
e.printStackTrace();
boolean deleted = false;
if (file.exists()) {
deleted = file.delete();
}
createFile(file, deleted);
}
}
private static void createFile(File file, boolean deleted){
try {
if (deleted && !file.exists()) {
file.createNewFile();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
================================================
FILE: agentweb-core/src/main/java/com/just/agentweb/AgentWebConfig.java
================================================
/*
* Copyright (C) Justson(https://github.com/Justson/AgentWeb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
package com.just.agentweb;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Build;
import androidx.annotation.Nullable;
import android.text.TextUtils;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.ValueCallback;
import android.webkit.WebView;
import java.io.File;
import static com.just.agentweb.AgentWebUtils.getAgentWebFilePath;
/**
* @author cenxiaozhong
* @since 1.0.0
*/
public class AgentWebConfig {
static final String FILE_CACHE_PATH = "agentweb-cache";
static final String AGENTWEB_CACHE_PATCH = File.separator + "agentweb-cache";
/**
* 缓存路径
*/
static String AGENTWEB_FILE_PATH;
/**
* DEBUG 模式 , 如果需要查看日志请设置为 true
*/
public static boolean DEBUG = false;
/**
* 当前操作系统是否低于 KITKAT
*/
static final boolean IS_KITKAT_OR_BELOW_KITKAT = Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT;
/**
* 默认 WebView 类型 。
*/
public static final int WEBVIEW_DEFAULT_TYPE = 1;
/**
* 使用 AgentWebView
*/
public static final int WEBVIEW_AGENTWEB_SAFE_TYPE = 2;
/**
* 自定义 WebView
*/
public static final int WEBVIEW_CUSTOM_TYPE = 3;
private static volatile boolean IS_INITIALIZED = false;
private static final String TAG = AgentWebConfig.class.getSimpleName();
public static final String AGENTWEB_NAME = "AgentWeb";
/**
* AgentWeb 的版本
*/
public static final String AGENTWEB_VERSION = AGENTWEB_NAME + "/" + "5.0.8";
/**
* 通过JS获取的文件大小, 这里限制最大为5MB ,太大会抛出 OutOfMemoryError
*/
public static int MAX_FILE_LENGTH = 1024 * 1024 * 5;
//获取Cookie
public static String getCookiesByUrl(String url) {
return CookieManager.getInstance() == null ? null : CookieManager.getInstance().getCookie(url);
}
public static void debug() {
DEBUG = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
}
/**
* 删除所有已经过期的 Cookies
*/
public static void removeExpiredCookies() {
CookieManager mCookieManager = null;
if ((mCookieManager = CookieManager.getInstance()) != null) { //同步清除
mCookieManager.removeExpiredCookie();
toSyncCookies();
}
}
/**
* 删除所有 Cookies
*/
public static void removeAllCookies() {
removeAllCookies(null);
}
// 解决兼容 Android 4.4 java.lang.NoSuchMethodError: android.webkit.CookieManager.removeSessionCookies
public static void removeSessionCookies() {
removeSessionCookies(null);
}
/**
* 同步cookie
*
* @param url
* @param cookies
*/
public static void syncCookie(String url, String cookies) {
CookieManager mCookieManager = CookieManager.getInstance();
if (mCookieManager != null) {
mCookieManager.setCookie(url, cookies);
toSyncCookies();
}
}
public static void removeSessionCookies(ValueCallback<Boolean> callback) {
if (callback == null) {
callback = getDefaultIgnoreCallback();
}
if (CookieManager.getInstance() == null) {
callback.onReceiveValue(new Boolean(false));
return;
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
CookieManager.getInstance().removeSessionCookie();
toSyncCookies();
callback.onReceiveValue(new Boolean(true));
return;
}
CookieManager.getInstance().removeSessionCookies(callback);
toSyncCookies();
}
/**
* @param context
* @return WebView 的缓存路径
*/
public static String getCachePath(Context context) {
return context.getCacheDir().getAbsolutePath() + AGENTWEB_CACHE_PATCH;
}
/**
* @param context
* @return AgentWeb 缓存路径
*/
public static String getExternalCachePath(Context context) {
return getAgentWebFilePath(context);
}
//Android 4.4 NoSuchMethodError: android.webkit.CookieManager.removeAllCookies
public static void removeAllCookies(@Nullable ValueCallback<Boolean> callback) {
if (callback == null) {
callback = getDefaultIgnoreCallback();
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
CookieManager.getInstance().removeAllCookie();
toSyncCookies();
callback.onReceiveValue(!CookieManager.getInstance().hasCookies());
return;
}
CookieManager.getInstance().removeAllCookies(callback);
toSyncCookies();
}
/**
* 清空缓存
*
* @param context
*/
public static synchronized void clearDiskCache(Context context) {
try {
AgentWebUtils.clearCacheFolder(new File(getCachePath(context)), 0);
String path = getExternalCachePath(context);
if (!TextUtils.isEmpty(path)) {
File mFile = new File(path);
AgentWebUtils.clearCacheFolder(mFile, 0);
}
} catch (Throwable throwable) {
if (LogUtils.isDebug()) {
throwable.printStackTrace();
}
}
}
static synchronized void initCookiesManager(Context context) {
if (!IS_INITIALIZED) {
createCookiesSyncInstance(context);
IS_INITIALIZED = true;
}
}
private static void createCookiesSyncInstance(Context context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
CookieSyncManager.createInstance(context);
}
}
private static void toSyncCookies() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
CookieSyncManager.getInstance().sync();
return;
}
AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
@Override
public void run() {
CookieManager.getInstance().flush();
}
});
}
static String getDatabasesCachePath(Context context) {
return context.getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
}
private static ValueCallback<Boolean> getDefaultIgnoreCallback() {
return new ValueCallback<Boolean>() {
@Override
public void onReceiveValue(Boolean ignore) {
LogUtils.i(TAG, "removeExpiredCookies:" + ignore);
}
};
}
}
================================================
FILE: agentweb-core/src/main/java/com/just/agentweb/AgentWebFileProvider.java
================================================
/*
* Copyright (C) Justson(https://github.com/Justson/AgentWeb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
package com.just.agentweb;
import android.content.Context;
import android.content.pm.ProviderInfo;
import androidx.annotation.NonNull;
import androidx.core.content.FileProvider;
/**
* @since 2.0.0
* @author cenxiaozhong
*/
public class AgentWebFileProvider extends FileProvider {
@Override
public void attachInfo(@NonNull Context context, @NonNull ProviderInfo info) {
super.attachInfo(context, info);
}
}
================================================
FILE: agentweb-core/src/main/java/com/just/agentweb/AgentWebJsInterfaceCompat.java
================================================
/*
* Copyright (C) Justson(https://github.com/Justson/AgentWeb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
package com.just.agentweb;
import android.app.Activity;
import android.os.Handler;
import android.os.Message;
import android.webkit.JavascriptInterface;
import java.lang.ref.WeakReference;
/**
* @author cenxiaozhong
* @since 1.0.0
*/
public class AgentWebJsInterfaceCompat {
private WeakReference<AgentWeb> mReference = null;
private WeakReference<Activity> mActivityWeakReference = null;
private String TAG = this.getClass().getSimpleName();
AgentWebJsInterfaceCompat(AgentWeb agentWeb, Activity activity) {
mReference = new WeakReference<AgentWeb>(agentWeb);
mActivityWeakReference = new WeakReference<Activity>(activity);
}
@JavascriptInterface
public void uploadFile() {
uploadFile("*/*");
}
@JavascriptInterface
public void uploadFile(String acceptType) {
LogUtils.i(TAG, acceptType + " " + mActivityWeakReference.get() + " " + mReference.get());
if (mActivityWeakReference.get() != null && mReference.get() != null) {
AgentWebUtils.showFileChooserCompat(mActivityWeakReference.get(),
mReference.get().getWebCreator().getWebView(),
null,
null,
mReference.get().getPermissionInterceptor(),
null,
acceptType,
new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
if (mReference.get() != null) {
mReference.get().getJsAccessEntrace()
.quickCallJs("uploadFileResult",
msg.obj instanceof String ? (String) msg.obj : null);
}
return true;
}
}
);
}
}
}
================================================
FILE: agentweb-core/src/main/java/com/just/agentweb/AgentWebPermissions.java
================================================
/*
* Copyright (C) Justson(https://github.com/Justson/AgentWeb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
package com.just.agentweb;
import android.Manifest;
import android.os.Build;
/**
* @author cenxiaozhong
* @since 1.0.0
*/
public class AgentWebPermissions {
public static String[] CAMERA;
public static String[] LOCATION;
public static String[] MEDIA;
public static final String ACTION_CAMERA = "Camera";
public static final String ACTION_LOCATION = "Location";
public static final String ACTION_MEDIA = "Media";
static {
CAMERA = new String[]{
Manifest.permission.CAMERA};
LOCATION = new String[]{
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION};
if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
MEDIA = new String[]{
Manifest.permission.READ_MEDIA_VIDEO,
Manifest.permission.READ_MEDIA_AUDIO,
Manifest.permission.READ_MEDIA_IMAGES,
};
} else {
MEDIA = new String[]{
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
}
}
private static void emptyMediaPermission() {
MEDIA = new String[]{};
}
private static void emptyCameraPermission() {
CAMERA = new String[]{};
}
public static void dontAskUnnecessaryPermissions() {
if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
emptyMediaPermission();
emptyCameraPermission();
}
}
}
================================================
FILE: agentweb-core/src/main/java/com/just/agentweb/AgentWebSettingsImpl.java
================================================
/*
* Copyright (C) Justson(https://github.com/Justson/AgentWeb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
package com.just.agentweb;
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.webkit.DownloadListener;
import android.webkit.WebView;
/**
* @author cenxiaozhong
* @since 1.0.0
*/
public class AgentWebSettingsImpl extends AbsAgentWebSettings {
private AgentWeb mAgentWeb;
@Override
protected void bindAgentWebSupport(AgentWeb agentWeb) {
this.mAgentWeb = agentWeb;
}
@Override
public WebListenerManager setDownloader(WebView webView, DownloadListener downloadListener) {
if (downloadListener == null) {
downloadListener = DefaultDownloadImpl.create(mAgentWeb.getActivity(), webView, mAgentWeb.getPermissionInterceptor());
}
return super.setDownloader(webView, downloadListener);
}
/**
* Copy from com.blankj.utilcode.util.ActivityUtils#getActivityByView
*/
private Activity getActivityByContext(Context context) {
if (context instanceof Activity) return (Activity) context;
while (context instanceof ContextWrapper) {
if (context instanceof Activity) {
return (Activity) context;
}
context = ((ContextWrapper) context).getBaseContext();
}
return null;
}
}
================================================
FILE: agentweb-core/src/main/java/com/just/agentweb/AgentWebUIControllerImplBase.java
================================================
/*
* Copyright (C) Justson(https://github.com/Justson/AgentWeb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
package com.just.agentweb;
import android.app.Activity;
import android.net.http.SslError;
import android.os.Handler;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.PermissionRequest;
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
/**
* @author cenxiaozhong
* @date 2017/12/6
* @since 3.0.0
*/
public class AgentWebUIControllerImplBase extends AbsAgentWebUIController {
public static AbsAgentWebUIController build() {
return new AgentWebUIControllerImplBase();
}
@Override
public void onJsAlert(WebView view, String url, String message) {
getDelegate().onJsAlert(view, url, message);
}
@Override
public void onOpenPagePrompt(WebView view, String url, Handler.Callback callback) {
getDelegate().onOpenPagePrompt(view, url, callback);
}
@Override
public void onJsConfirm(WebView view, String url, String message, JsResult jsResult) {
getDelegate().onJsConfirm(view, url, message, jsResult);
}
@Override
public void onSelectItemsPrompt(WebView view, String url, String[] ways, Handler.Callback callback) {
getDelegate().onSelectItemsPrompt(view, url, ways, callback);
}
@Override
public void onForceDownloadAlert(String url, Handler.Callback callback) {
getDelegate().onForceDownloadAlert(url, callback);
}
@Override
public void onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult jsPromptResult) {
getDelegate().onJsPrompt(view, url, message, defaultValue, jsPromptResult);
}
@Override
public void onMainFrameError(WebView view, int errorCode, String description, String failingUrl) {
getDelegate().onMainFrameError(view, errorCode, description, failingUrl);
}
@Override
public void onShowMainFrame() {
getDelegate().onShowMainFrame();
}
@Override
public void onLoading(String msg) {
getDelegate().onLoading(msg);
}
@Override
public void onCancelLoading() {
getDelegate().onCancelLoading();
}
@Override
public void onShowMessage(String message, String from) {
getDelegate().onShowMessage(message, from);
}
@Override
public void onPermissionsDeny(String[] permissions, String permissionType, String action) {
getDelegate().onPermissionsDeny(permissions, permissionType, action);
}
@Override
public void onShowSslCertificateErrorDialog(WebView view, SslErrorHandler handler, SslError error) {
getDelegate().onShowSslCertificateErrorDialog(view, handler, error);
}
@Override
public void onPermissionRequest(PermissionRequest request) {
getDelegate().onPermissionRequest(request);
}
@Override
protected void bindSupportWebParent(WebParentLayout webParentLayout, Activity activity) {
getDelegate().bindSupportWebParent(webParentLayout, activity);
}
}
================================================
FILE: agentweb-core/src/main/java/com/just/agentweb/AgentWebUtils.java
================================================
/*
* Copyright (C) Justson(https://github.com/Justson/AgentWeb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
package com.just.agentweb;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.StatFs;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import com.google.android.material.snackbar.Snackbar;
import androidx.core.app.AppOpsManagerCompat;
import androidx.core.content.ContextCompat;
import androidx.loader.content.CursorLoader;
import androidx.core.content.FileProvider;
import androidx.core.os.EnvironmentCompat;
import android.telephony.TelephonyManager;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import static com.just.agentweb.AgentWebConfig.AGENTWEB_FILE_PATH;
import static com.just.agentweb.AgentWebConfig.FILE_CACHE_PATH;
/**
* @author cenxiaozhong
* @since 1.0.0
*/
public class AgentWebUtils {
private static final String TAG = AgentWebUtils.class.getSimpleName();
private static Handler mHandler = null;
private AgentWebUtils() {
throw new UnsupportedOperationException("u can't init me");
}
public static int dp2px(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
static final void clearWebView(WebView m) {
if (m == null) {
return;
}
if (Looper.myLooper() != Looper.getMainLooper()) {
return;
}
m.loadUrl("about:blank");
m.stopLoading();
if (m.getHandler() != null) {
m.getHandler().removeCallbacksAndMessages(null);
}
m.removeAllViews();
ViewGroup mViewGroup = null;
if ((mViewGroup = ((ViewGroup) m.getParent())) != null) {
mViewGroup.removeView(m);
}
m.setWebChromeClient(null);
m.setWebViewClient(null);
m.setTag(null);
m.clearHistory();
m.destroy();
m = null;
}
public static String getAgentWebFilePath(Context context) {
if (!TextUtils.isEmpty(AGENTWEB_FILE_PATH)) {
return AGENTWEB_FILE_PATH;
}
String dir = getDiskExternalCacheDir(context);
File mFile = new File(dir, FILE_CACHE_PATH);
try {
if (!mFile.exists()) {
mFile.mkdirs();
}
} catch (Throwable throwable) {
LogUtils.i(TAG, "create dir exception");
}
LogUtils.i(TAG, "path:" + mFile.getAbsolutePath() + " path:" + mFile.getPath());
return AGENTWEB_FILE_PATH = mFile.getAbsolutePath();
}
public static File createFileByName(Context context, String name, boolean cover) throws IOException {
String path = getAgentWebFilePath(context);
if (TextUtils.isEmpty(path)) {
return null;
}
File mFile = new File(path, name);
if (mFile.exists()) {
if (cover) {
mFile.delete();
mFile.createNewFile();
}
} else {
mFile.createNewFile();
}
return mFile;
}
public static int checkNetworkType(Context context) {
int netType = 0;
//连接管理对象
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
//获取NetworkInfo对象
@SuppressLint("MissingPermission") NetworkInfo networkInfo = manager.getActiveNetworkInfo();
if (networkInfo == null) {
return netType;
}
switch (networkInfo.getType()) {
case ConnectivityManager.TYPE_WIFI:
case ConnectivityManager.TYPE_WIMAX:
case ConnectivityManager.TYPE_ETHERNET:
return 1;
case ConnectivityManager.TYPE_MOBILE:
switch (networkInfo.getSubtype()) {
case TelephonyManager.NETWORK_TYPE_LTE: // 4G
case TelephonyManager.NETWORK_TYPE_HSPAP:
case TelephonyManager.NETWORK_TYPE_EHRPD:
return 2;
case TelephonyManager.NETWORK_TYPE_UMTS: // 3G
case TelephonyManager.NETWORK_TYPE_CDMA:
case TelephonyManager.NETWORK_TYPE_EVDO_0:
case TelephonyManager.NETWORK_TYPE_EVDO_A:
case TelephonyManager.NETWORK_TYPE_EVDO_B:
return 3;
case TelephonyManager.NETWORK_TYPE_GPRS: // 2G
case TelephonyManager.NETWORK_TYPE_EDGE:
return 4;
default:
return netType;
}
default:
return netType;
}
}
public static long getAvailableStorage() {
try {
StatFs stat = new StatFs(Environment.getExternalStorageDirectory().toString());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
return stat.getAvailableBlocksLong() * stat.getBlockSizeLong();
} else {
return (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();
}
} catch (RuntimeException ex) {
return 0;
}
}
public static Uri getUriFromFile(Context context, File file) {
Uri uri = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
uri = getUriFromFileForN(context, file);
} else {
uri = Uri.fromFile(file);
}
return uri;
}
static Uri getUriFromFileForN(Context context, File file) {
Uri fileUri = FileProvider.getUriForFile(context, context.getPackageName() + ".AgentWebFileProvider", file);
return fileUri;
}
static void setIntentDataAndType(Context context,
Intent intent,
String type,
File file,
boolean writeAble) {
if (Build.VERSION.SDK_INT >= 24) {
intent.setDataAndType(getUriFromFile(context, file), type);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
if (writeAble) {
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
} else {
intent.setDataAndType(Uri.fromFile(file), type);
}
}
static void setIntentData(Context context,
Intent intent,
File file,
boolean writeAble) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.setData(getUriFromFile(context, file));
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
if (writeAble) {
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
} else {
intent.setData(Uri.fromFile(file));
}
}
static String getDiskExternalCacheDir(Context context) {
File mFile = context.getExternalCacheDir();
if (Environment.MEDIA_MOUNTED.equals(EnvironmentCompat.getStorageState(mFile))) {
return mFile.getAbsolutePath();
}
return null;
}
static void grantPermissions(Context context, Intent intent, Uri uri, boolean writeAble) {
int flag = Intent.FLAG_GRANT_READ_URI_PERMISSION;
if (writeAble) {
flag |= Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
}
intent.addFlags(flag);
List<ResolveInfo> resInfoList = context.getPackageManager()
.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
context.grantUriPermission(packageName, uri, flag);
}
}
private static String getMIMEType(File f) {
String type = "";
String fName = f.getName();
/* 取得扩展名 */
String end = fName.substring(fName.lastIndexOf(".") + 1, fName.length()).toLowerCase();
/* 依扩展名的类型决定MimeType */
if (end.equals("pdf")) {
type = "application/pdf";//
} else if (end.equals("m4a") || end.equals("mp3") || end.equals("mid") ||
end.equals("xmf") || end.equals("ogg") || end.equals("wav")) {
type = "audio/*";
} else if (end.equals("3gp") || end.equals("mp4")) {
type = "video/*";
} else if (end.equals("jpg") || end.equals("gif") || end.equals("png") ||
end.equals("jpeg") || end.equals("bmp")) {
type = "image/*";
} else if (end.equals("apk")) {
type = "application/vnd.android.package-archive";
} else if (end.equals("pptx") || end.equals("ppt")) {
type = "application/vnd.ms-powerpoint";
} else if (end.equals("docx") || end.equals("doc")) {
type = "application/vnd.ms-word";
} else if (end.equals("xlsx") || end.equals("xls")) {
type = "application/vnd.ms-excel";
} else {
type = "*/*";
}
return type;
}
private static WeakReference<Snackbar> snackbarWeakReference;
static void show(View parent,
CharSequence text,
int duration,
@ColorInt int textColor,
@ColorInt int bgColor,
CharSequence actionText,
@ColorInt int actionTextColor,
View.OnClickListener listener) {
SpannableString spannableString = new SpannableString(text);
ForegroundColorSpan colorSpan = new ForegroundColorSpan(textColor);
spannableString.setSpan(colorSpan, 0, spannableString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
snackbarWeakReference = new WeakReference<>(Snackbar.make(parent, spannableString, duration));
Snackbar snackbar = snackbarWeakReference.get();
View view = snackbar.getView();
view.setBackgroundColor(bgColor);
if (actionText != null && actionText.length() > 0 && listener != null) {
snackbar.setActionTextColor(actionTextColor);
snackbar.setAction(actionText, listener);
}
snackbar.show();
}
static void dismiss() {
if (snackbarWeakReference != null && snackbarWeakReference.get() != null) {
snackbarWeakReference.get().dismiss();
snackbarWeakReference = null;
}
}
public static boolean checkWifi(Context context) {
ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity == null) {
return false;
}
@SuppressLint("MissingPermission") NetworkInfo info = connectivity.getActiveNetworkInfo();
return info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_WIFI;
}
public static boolean checkNetwork(Context context) {
ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity == null) {
return false;
}
@SuppressLint("MissingPermission") NetworkInfo info = connectivity.getActiveNetworkInfo();
return info != null && info.isConnected();
}
static boolean isOverriedMethod(Object currentObject, String methodName, String method, Class... clazzs) {
LogUtils.i(TAG, " methodName:" + methodName + " method:" + method);
boolean tag = false;
if (currentObject == null) {
return tag;
}
try {
Class clazz = currentObject.getClass();
Method mMethod = clazz.getMethod(methodName, clazzs);
String gStr = mMethod.toGenericString();
tag = !gStr.contains(method);
} catch (Exception igonre) {
if (LogUtils.isDebug()) {
igonre.printStackTrace();
}
}
LogUtils.i(TAG, "isOverriedMethod:" + tag);
return tag;
}
static Method isExistMethod(Object o, String methodName, Class... clazzs) {
if (null == o) {
return null;
}
try {
Class clazz = o.getClass();
Method mMethod = clazz.getDeclaredMethod(methodName, clazzs);
mMethod.setAccessible(true);
return mMethod;
} catch (Throwable ignore) {
// if (LogUtils.isDebug()) {
// ignore.printStackTrace();
// }
}
return null;
}
static void clearAgentWebCache(Context context) {
try {
clearCacheFolder(new File(getAgentWebFilePath(context)), 0);
} catch (Throwable throwable) {
if (LogUtils.isDebug()) {
throwable.printStackTrace();
}
}
}
static void clearWebViewAllCache(Context context, WebView webView) {
try {
AgentWebConfig.removeAllCookies(null);
webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
context.deleteDatabase("webviewCache.db");
context.deleteDatabase("webview.db");
webView.clearCache(true);
webView.clearHistory();
webView.clearFormData();
clearCacheFolder(new File(AgentWebConfig.getCachePath(context)), 0);
} catch (Exception ignore) {
//ignore.printStackTrace();
if (AgentWebConfig.DEBUG) {
ignore.printStackTrace();
}
}
}
static void clearWebViewAllCache(Context context) {
try {
clearWebViewAllCache(context, new LollipopFixedWebView(context.getApplicationContext()));
} catch (Exception e) {
e.printStackTrace();
}
}
static int clearCacheFolder(final File dir, final int numDays) {
int deletedFiles = 0;
if (dir != null) {
Log.i("Info", "dir:" + dir.getAbsolutePath());
}
if (dir != null && dir.isDirectory()) {
try {
for (File child : dir.listFiles()) {
//first delete subdirectories recursively
if (child.isDirectory()) {
deletedFiles += clearCacheFolder(child, numDays);
}
//then delete the files and subdirectories in this dir
//only empty directories can be deleted, so subdirs have been done first
if (child.lastModified() < new Date().getTime() - numDays * DateUtils.DAY_IN_MILLIS) {
Log.i(TAG, "file name:" + child.getName());
if (child.delete()) {
deletedFiles++;
}
}
}
} catch (Exception e) {
Log.e("Info", String.format("Failed to clean the cache, result %s", e.getMessage()));
}
}
return deletedFiles;
}
static void clearCache(final Context context, final int numDays) {
Log.i("Info", String.format("Starting cache prune, deleting files older than %d days", numDays));
int numDeletedFiles = clearCacheFolder(context.getCacheDir(), numDays);
Log.i("Info", String.format("Cache pruning completed, %d files deleted", numDeletedFiles));
}
public static String[] uriToPath(Activity activity, Uri[] uris) {
if (activity == null || uris == null || uris.length == 0) {
return null;
}
try {
String[] paths = new String[uris.length];
int i = 0;
for (Uri mUri : uris) {
paths[i++] = Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2 ? getFileAbsolutePath(activity, mUri) : getRealPathBelowVersion(activity, mUri);
}
return paths;
} catch (Throwable throwable) {
if (LogUtils.isDebug()) {
throwable.printStackTrace();
}
}
return null;
}
private static String getRealPathBelowVersion(Context context, Uri uri) {
String filePath = null;
LogUtils.i(TAG, "method -> getRealPathBelowVersion " + uri + " path:" + uri.getPath() + " getAuthority:" + uri.getAuthority());
String[] projection = {MediaStore.Images.Media.DATA};
CursorLoader loader = new CursorLoader(context, uri, projection, null,
null, null);
Cursor cursor = loader.loadInBackground();
if (cursor != null) {
cursor.moveToFirst();
filePath = cursor.getString(cursor.getColumnIndex(projection[0]));
cursor.close();
}
if (filePath == null) {
filePath = uri.getPath();
}
return filePath;
}
public static File createImageFile(Context context) {
File mFile = null;
try {
String timeStamp =
new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()).format(new Date());
String imageName = String.format("aw_%s.jpg", timeStamp);
mFile = createFileByName(context, imageName, true);
} catch (Throwable e) {
e.printStackTrace();
}
return mFile;
}
static File createVideoFile(Context context){
File mFile = null;
try {
String timeStamp =
new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()).format(new Date());
String imageName = String.format("aw_%s.mp4", timeStamp); //默认生成mp4
mFile = createFileByName(context, imageName, true);
} catch (Throwable e) {
e.printStackTrace();
}
return mFile;
}
public static void closeIO(Closeable closeable) {
try {
if (closeable != null) {
closeable.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
@TargetApi(19)
static String getFileAbsolutePath(Activity context, Uri fileUri) {
if (context == null || fileUri == null) {
return null;
}
// LogUtils.i(TAG, "getAuthority:" + fileUri.getAuthority() + " getHost:" + fileUri.getHost() + " getPath:" + fileUri.getPath() + " getScheme:" + fileUri.getScheme() + " query:" + fileUri.getQuery());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, fileUri)) {
if (isExternalStorageDocument(fileUri)) {
String docId = DocumentsContract.getDocumentId(fileUri);
String[] split = docId.split(":");
String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
} else if (isDownloadsDocument(fileUri)) {
String id = DocumentsContract.getDocumentId(fileUri);
Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
} else if (isMediaDocument(fileUri)) {
String docId = DocumentsContract.getDocumentId(fileUri);
String[] split = docId.split(":");
String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
String selection = MediaStore.Images.Media._ID + "=?";
String[] selectionArgs = new String[]{split[1]};
return getDataColumn(context, contentUri, selection, selectionArgs);
} else {
}
} // MediaStore (and general)
else if (fileUri.getAuthority().equalsIgnoreCase(context.getPackageName() + ".AgentWebFileProvider")) {
String path = fileUri.getPath();
int index = path.lastIndexOf("/");
return getAgentWebFilePath(context) + File.separator + path.substring(index + 1, path.length());
} else if ("content".equalsIgnoreCase(fileUri.getScheme())) {
// Return the remote address
if (isGooglePhotosUri(fileUri)) {
return fileUri.getLastPathSegment();
}
return getDataColumn(context, fileUri, null, null);
}
// File
else if ("file".equalsIgnoreCase(fileUri.getScheme())) {
return fileUri.getPath();
}
return null;
}
static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
Cursor cursor = null;
String[] projection = {MediaStore.Images.Media.DATA};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
int index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
return cursor.getString(index);
}
} finally {
if (cursor != null) {
cursor.close();
}
}
return null;
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is Google Photos.
*/
static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
static Intent getInstallApkIntentCompat(Context context, File file) {
Intent mIntent = new Intent().setAction(Intent.ACTION_VIEW);
setIntentDataAndType(context, mIntent, "application/vnd.android.package-archive", file, false);
return mIntent;
}
public static Intent getCommonFileIntentCompat(Context context, File file) {
Intent mIntent = new Intent().setAction(Intent.ACTION_VIEW);
setIntentDataAndType(context, mIntent, getMIMEType(file), file, false);
return mIntent;
}
static Intent getIntentCaptureCompat(Context context, File file) {
Intent mIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri mUri = getUriFromFile(context, file);
mIntent.addCategory(Intent.CATEGORY_DEFAULT);
mIntent.putExtra(MediaStore.EXTRA_OUTPUT, mUri);
return mIntent;
}
static Intent getIntentVideoCompat(Context context, File file){
Intent mIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
Uri mUri = getUriFromFile(context, file);
mIntent.addCategory(Intent.CATEGORY_DEFAULT);
mIntent.putExtra(MediaStore.EXTRA_OUTPUT, mUri);
return mIntent;
}
static boolean isJson(String target) {
if (TextUtils.isEmpty(target)) {
return false;
}
boolean tag = false;
try {
if (target.startsWith("[")) {
new JSONArray(target);
} else {
new JSONObject(target);
}
tag = true;
} catch (JSONException ignore) {
// ignore.printStackTrace();
tag = false;
}
return tag;
}
public static boolean isUIThread() {
return Looper.myLooper() == Looper.getMainLooper();
}
static boolean isEmptyCollection(Collection collection) {
return collection == null || collection.isEmpty();
}
static boolean isEmptyMap(Map map) {
return map == null || map.isEmpty();
}
private static Toast mToast = null;
static void toastShowShort(Context context, String msg) {
if (mToast == null) {
mToast = Toast.makeText(context.getApplicationContext(), msg, Toast.LENGTH_SHORT);
} else {
mToast.setText(msg);
}
mToast.show();
}
@Deprecated
static void getUIControllerAndShowMessage(Activity activity, String message, String from) {
if (activity == null || activity.isFinishing()) {
return;
}
WebParentLayout mWebParentLayout = (WebParentLayout) activity.findViewById(R.id.web_parent_layout_id);
AbsAgentWebUIController mAgentWebUIController = mWebParentLayout.provide();
if (mAgentWebUIController != null) {
mAgentWebUIController.onShowMessage(message, from);
}
}
public static boolean hasPermission(@NonNull Context context, @NonNull String... permissions) {
return hasPermission(context, Arrays.asList(permissions));
}
public static boolean hasPermission(@NonNull Context context, @NonNull List<String> permissions) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return true;
}
for (String permission : permissions) {
int result = ContextCompat.checkSelfPermission(context, permission);
if (result == PackageManager.PERMISSION_DENIED) {
return false;
}
String op = AppOpsManagerCompat.permissionToOp(permission);
if (TextUtils.isEmpty(op)) {
continue;
}
result = AppOpsManagerCompat.noteProxyOp(context, op, context.getPackageName());
if (result != AppOpsManagerCompat.MODE_ALLOWED) {
return false;
}
}
return true;
}
public static List<String> getDeniedPermissions(Activity activity, String[] permissions) {
if (permissions == null || permissions.length == 0) {
return Collections.EMPTY_LIST;
}
List<String> deniedPermissions = new ArrayList<>(permissions.length);
for (int i = 0; i < permissions.length; i++) {
if (!hasPermission(activity, permissions[i])) {
deniedPermissions.add(permissions[i]);
}
}
return deniedPermissions;
}
public static AbsAgentWebUIController getAgentWebUIControllerByWebView(WebView webView) {
WebParentLayout mWebParentLayout = getWebParentLayoutByWebView(webView);
return mWebParentLayout.provide();
}
//获取应用的名称
public static String getApplicationName(Context context) {
PackageManager packageManager = null;
ApplicationInfo applicationInfo = null;
try {
packageManager = context.getApplicationContext().getPackageManager();
applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
applicationInfo = null;
}
String applicationName =
(String) packageManager.getApplicationLabel(applicationInfo);
return applicationName;
}
static WebParentLayout getWebParentLayoutByWebView(WebView webView) {
ViewGroup mViewGroup = null;
if (!(webView.getParent() instanceof ViewGroup)) {
throw new IllegalStateException("please check webcreator's create method was be called ?");
}
mViewGroup = (ViewGroup) webView.getParent();
AbsAgentWebUIController mAgentWebUIController;
while (mViewGroup != null) {
LogUtils.i(TAG, "ViewGroup:" + mViewGroup);
if (mViewGroup.getId() == R.id.web_parent_layout_id) {
WebParentLayout mWebParentLayout = (WebParentLayout) mViewGroup;
LogUtils.i(TAG, "found WebParentLayout");
return mWebParentLayout;
} else {
ViewParent mViewParent = mViewGroup.getParent();
if (mViewParent instanceof ViewGroup) {
mViewGroup = (ViewGroup) mViewParent;
} else {
mViewGroup = null;
}
}
}
throw new IllegalStateException("please check webcreator's create method was be called ?");
}
public static void runInUiThread(Runnable runnable) {
if (mHandler == null) {
mHandler = new Handler(Looper.getMainLooper());
}
mHandler.post(runnable);
}
public static boolean showFileChooserCompat(Activity activity,
WebView webView,
ValueCallback<Uri[]> valueCallbacks,
WebChromeClient.FileChooserParams fileChooserParams,
PermissionInterceptor permissionInterceptor,
ValueCallback valueCallback,
String mimeType,
Handler.Callback jsChannelCallback
) {
try {
Class<?> clz = Class.forName("com.just.agentweb.filechooser.FileChooser");
Object mFileChooser$Builder = clz.getDeclaredMethod("newBuilder",
Activity.class, WebView.class)
.invoke(null, activity, webView);
clz = mFileChooser$Builder.getClass();
Method mMethod = null;
if (valueCallbacks != null) {
mMethod = clz.getDeclaredMethod("setUriValueCallbacks", ValueCallback.class);
mMethod.setAccessible(true);
mMethod.invoke(mFileChooser$Builder, valueCallbacks);
}
if (fileChooserParams != null) {
mMethod = clz.getDeclaredMethod("setFileChooserParams", WebChromeClient.FileChooserParams.class);
mMethod.setAccessible(true);
mMethod.invoke(mFileChooser$Builder, fileChooserParams);
}
if (valueCallback != null) {
mMethod = clz.getDeclaredMethod("setUriValueCallback", ValueCallback.class);
mMethod.setAccessible(true);
mMethod.invoke(mFileChooser$Builder, valueCallback);
}
if (!TextUtils.isEmpty(mimeType)) {
// LogUtils.i(TAG, Arrays.toString(clz.getDeclaredMethods()));
mMethod = clz.getDeclaredMethod("setAcceptType", String.class);
mMethod.setAccessible(true);
mMethod.invoke(mFileChooser$Builder, mimeType);
}
if (jsChannelCallback != null) {
mMethod = clz.getDeclaredMethod("setJsChannelCallback", Handler.Callback.class);
mMethod.setAccessible(true);
mMethod.invoke(mFileChooser$Builder, jsChannelCallback);
}
mMethod = clz.getDeclaredMethod("setPermissionInterceptor", PermissionInterceptor.class);
mMethod.setAccessible(true);
mMethod.invoke(mFileChooser$Builder, permissionInterceptor);
mMethod = clz.getDeclaredMethod("build");
mMethod.setAccessible(true);
Object mFileChooser = mMethod.invoke(mFileChooser$Builder);
mMethod = mFileChooser.getClass().getDeclaredMethod("openFileChooser");
mMethod.setAccessible(true);
mMethod.invoke(mFileChooser);
} catch (Throwable throwable) {
if (LogUtils.isDebug()) {
throwable.printStackTrace();
}
if (throwable instanceof ClassNotFoundException) {
LogUtils.e(TAG, "Please check whether compile'com.just.agentweb:filechooser:x.x.x' dependency was added.");
}
if (valueCallbacks != null) {
LogUtils.i(TAG, "onReceiveValue empty");
return false;
}
if (valueCallback != null) {
valueCallback.onReceiveValue(null);
}
}
return true;
}
public static String md5(String str) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(str.getBytes());
return new BigInteger(1, md.digest()).toString(16);
} catch (Exception e) {
if (LogUtils.isDebug()) {
e.printStackTrace();
}
}
return "";
}
}
================================================
FILE: agentweb-core/src/main/java/com/just/agentweb/AgentWebView.java
================================================
/*
* Copyright (C) Justson(https://github.com/Justson/AgentWeb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
package com.just.agentweb;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Pair;
import android.view.ActionMode;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.accessibility.AccessibilityManager;
import android.webkit.JsPromptResult;
import android.webkit.WebBackForwardList;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
import org.json.JSONObject;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
/**
* @author cenxiaozhong
* @since 1.0.0
*/
public class AgentWebView extends LollipopFixedWebView {
private static final String TAG = AgentWebView.class.getSimpleName();
private Map<String, JsCallJava> mJsCallJavas;
private Map<String, String> mInjectJavaScripts;
private FixedOnReceivedTitle mFixedOnReceivedTitle;
private boolean mIsInited;
private Boolean mIsAccessibilityEnabledOriginal;
public AgentWebView(Context context) {
this(context, null);
}
public AgentWebView(Context context, AttributeSet attrs) {
super(context, attrs);
removeSearchBoxJavaBridge();
mIsInited = true;
mFixedOnReceivedTitle = new FixedOnReceivedTitle();
}
/**
* 经过大量的测试,按照以下方式才能保证JS脚本100%注入成功:
* 1、在第一次loadUrl之前注入JS(在addJavascriptInterface里面注入即可,setWebViewClient和setWebChromeClient要在addJavascriptInterface之前执行);
* 2、在webViewClient.onPageStarted中都注入JS;
* 3、在webChromeClient.onProgressChanged中都注入JS,并且不能通过自检查(onJsPrompt里面判断)JS是否注入成功来减少注入JS的次数,因为网页中的JS可以同时打开多个url导致无法控制检查的准确性;
*
* @deprecated Android 4.2.2及以上版本的 addJavascriptInterface 方法已经解决了安全问题,如果不使用“网页能将JS函数传到Java层”功能,不建议使用该类,毕竟系统的JS注入效率才是最高的;
*/
@Override
@Deprecated
public final void addJavascriptInterface(Object interfaceObj, String interfaceName) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
super.addJavascriptInterface(interfaceObj, interfaceName);
Log.i(TAG, "注入");
return;
} else {
Log.i(TAG, "use mJsCallJavas:" + interfaceName);
}
LogUtils.i(TAG, "addJavascriptInterface:" + interfaceObj + " interfaceName:" + interfaceName);
if (mJsCallJavas == null) {
mJsCallJavas = new HashMap<String, JsCallJava>();
}
mJsCallJavas.put(interfaceName, new JsCallJava(interfaceObj, interfaceName));
injectJavaScript();
if (LogUtils.isDebug()) {
Log.d(TAG, "injectJavaScript, addJavascriptInterface.interfaceObj = " + interfaceObj + ", interfaceName = " + interfaceName);
}
addJavascriptInterfaceSupport(interfaceObj, interfaceName);
}
protected void addJavascriptInterfaceSupport(Object interfaceObj, String interfaceName) {
}
@Override
public final void setWebChromeClient(WebChromeClient client) {
AgentWebChrome mAgentWebChrome = new AgentWebChrome(this);
mAgentWebChrome.setDelegate(client);
mFixedOnReceivedTitle.setWebChromeClient(client);
super.setWebChromeClient(mAgentWebChrome);
setWebChromeClientSupport(mAgentWebChrome);
}
protected final void setWebChromeClientSupport(WebChromeClient client) {
}
@Override
public final void setWebViewClient(WebViewClient client) {
AgentWebClient mAgentWebClient = new AgentWebClient(this);
mAgentWebClient.setDelegate(client);
super.setWebViewClient(mAgentWebClient);
setWebViewClientSupport(mAgentWebClient);
}
public final void setWebViewClientSupport(WebViewClient client) {
}
@Override
public ActionMode startActionMode(ActionMode.Callback callback) {
return super.startActionMode(callback);
}
@Override
public void destroy() {
setVisibility(View.GONE);
if (mJsCallJavas != null) {
mJsCallJavas.clear();
}
if (mInjectJavaScripts != null) {
mInjectJavaScripts.clear();
}
removeAllViewsInLayout();
fixedStillAttached();
releaseConfigCallback();
if (mIsInited) {
resetAccessibilityEnabled();
LogUtils.i(TAG, "destroy web");
super.destroy();
}
}
@Override
public void clearHistory() {
if (mIsInited) {
super.clearHistory();
}
}
public static Pair<Boolean, String> isWebViewPackageException(Throwable e) {
String messageCause = e.getCause() == null ? e.toString() : e.getCause().toString();
String trace = Log.getStackTraceString(e);
if (trace.contains("android.content.pm.PackageManager$NameNotFoundException")
|| trace.contains("java.lang.RuntimeException: Cannot load WebView")
|| trace.contains("android.webkit.WebViewFactory$MissingWebViewPackageException: Failed to load WebView provider: No WebView installed")) {
LogUtils.safeCheckCrash(TAG, "isWebViewPackageException", e);
return new Pair<Boolean, String>(true, "WebView load failed, " + messageCause);
}
return new Pair<Boolean, String>(false, messageCause);
}
@Override
public void setOverScrollMode(int mode) {
try {
super.setOverScrollMode(mode);
} catch (Throwable e) {
Pair<Boolean, String> pair = isWebViewPackageException(e);
if (pair.first) {
Toast.makeText(getContext(), pair.second, Toast.LENGTH_SHORT).show();
destroy();
} else {
throw e;
}
}
}
@Override
public boolean isPrivateBrowsingEnabled() {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1
&& getSettings() == null) {
return false; // getSettings().isPrivateBrowsingEnabled()
} else {
return super.isPrivateBrowsingEnabled();
}
}
/**
* 添加并注入JavaScript脚本(和“addJavascriptInterface”注入对象的注入时机一致,100%能注入成功);
* 注意:为了做到能100%注入,需要在注入的js中自行判断对象是否已经存在(如:if (typeof(window.Android) = 'undefined'));
*
* @param javaScript
*/
public void addInjectJavaScript(String javaScript) {
if (mInjectJavaScripts == null) {
mInjectJavaScripts = new HashMap<String, String>();
}
mInjectJavaScripts.put(String.valueOf(javaScript.hashCode()), javaScript);
injectExtraJavaScript();
}
private void injectJavaScript() {
for (Map.Entry<String, JsCallJava> entry : mJsCallJavas.entrySet()) {
this.loadUrl(buildNotRepeatInjectJS(entry.getKey(), entry.getValue().getPreloadInterfaceJs()));
}
}
private void injectExtraJavaScript() {
for (Map.Entry<String, String> entry : mInjectJavaScripts.entrySet()) {
this.loadUrl(buildNotRepeatInjectJS(entry.getKey(), entry.getValue()));
}
}
/**
* 构建一个“不会重复注入”的js脚本;
*
* @param key
* @param js
* @return
*/
public String buildNotRepeatInjectJS(String key, String js) {
String obj = String.format("__injectFlag_%1$s__", key);
StringBuilder sb = new StringBuilder();
sb.append("javascript:try{(function(){if(window.");
sb.append(obj);
sb.append("){console.log('");
sb.append(obj);
sb.append(" has been injected');return;}window.");
sb.append(obj);
sb.append("=true;");
sb.append(js);
sb.append("}())}catch(e){console.warn(e)}");
return sb.toString();
}
/**
* 构建一个“带try catch”的js脚本;
*
* @param js
* @return
*/
public String buildTryCatchInjectJS(String js) {
StringBuilder sb = new StringBuilder();
sb.append("javascript:try{");
sb.append(js);
sb.append("}catch(e){console.warn(e)}");
return sb.toString();
}
public static class AgentWebClient extends MiddlewareWebClientBase {
private AgentWebView mAgentWebView;
private AgentWebClient(AgentWebView agentWebView) {
this.mAgentWebView = agentWebView;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
if (mAgentWebView.mJsCallJavas != null) {
mAgentWebView.injectJavaScript();
if (LogUtils.isDebug()) {
Log.d(TAG, "injectJavaScript, onPageStarted.url = " + view.getUrl());
}
}
if (mAgentWebView.mInjectJavaScripts != null) {
mAgentWebView.injectExtraJavaScript();
}
mAgentWebView.mFixedOnReceivedTitle.onPageStarted();
mAgentWebView.fixedAccessibilityInjectorExceptionForOnPageFinished(url);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
mAgentWebView.mFixedOnReceivedTitle.onPageFinished(view);
if (LogUtils.isDebug()) {
Log.d(TAG, "onPageFinished.url = " + view.getUrl());
}
}
}
public static class AgentWebChrome extends MiddlewareWebChromeBase {
private AgentWebView mAgentWebView;
private AgentWebChrome(AgentWebView agentWebView) {
this.mAgentWebView = agentWebView;
}
@Override
public void onReceivedTitle(WebView view, String title) {
this.mAgentWebView.mFixedOnReceivedTitle.onReceivedTitle();
super.onReceivedTitle(view, title);
}
@Override
public void onProgressChanged(WebView view, int newProgress) {
if (this.mAgentWebView.mJsCallJavas != null) {
this.mAgentWebView.injectJavaScript();
if (LogUtils.isDebug()) {
Log.d(TAG, "injectJavaScript, onProgressChanged.newProgress = " + newProgress + ", url = " + view.getUrl());
}
}
if (this.mAgentWebView.mInjectJavaScripts != null) {
this.mAgentWebView.injectExtraJavaScript();
}
super.onProgressChanged(view, newProgress);
}
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
Log.i(TAG, "onJsPrompt:" + url + " message:" + message + " d:" + defaultValue + " ");
if (this.mAgentWebView.mJsCallJavas != null && JsCallJava.isSafeWebViewCallMsg(message)) {
JSONObject jsonObject = JsCallJava.getMsgJSONObject(message);
String interfacedName = JsCallJava.getInterfacedName(jsonObject);
if (interfacedName != null) {
JsCallJava mJsCallJava = this.mAgentWebView.mJsCallJavas.get(interfacedName);
if (mJsCallJava != null) {
result.confirm(mJsCallJava.call(view, jsonObject));
}
}
return true;
} else {
return super.onJsPrompt(view, url, message, defaultValue, result);
}
}
}
/**
* 解决部分手机webView返回时不触发onReceivedTitle的问题(如:三星SM-G9008V 4.4.2);
*/
private static class FixedOnReceivedTitle {
private WebChromeClient mWebChromeClient;
private boolean mIsOnReceivedTitle;
public void setWebChromeClient(WebChromeClient webChromeClient) {
mWebChromeClient = webChromeClient;
}
public void onPageStarted() {
mIsOnReceivedTitle = false;
}
public void onPageFinished(WebView view) {
if (!mIsOnReceivedTitle && mWebChromeClient != null) {
WebBackForwardList list = null;
try {
list = view.copyBackForwardList();
} catch (NullPointerException e) {
if (LogUtils.isDebug()) {
e.printStackTrace();
}
}
if (list != null
&& list.getSize() > 0
&& list.getCurrentIndex() >= 0
&& list.getItemAtIndex(list.getCurrentIndex()) != null) {
String previousTitle = list.getItemAtIndex(list.getCurrentIndex()).getTitle();
mWebChromeClient.onReceivedTitle(view, previousTitle);
}
}
}
public void onReceivedTitle() {
mIsOnReceivedTitle = true;
}
}
// Activity在onDestory时调用webView的destroy,可以停止播放页面中的音频
private void fixedStillAttached() {
// java.lang.Throwable: Error: WebView.destroy() called while still attached!
// at android.webkit.WebViewClassic.destroy(WebViewClassic.java:4142)
// at android.webkit.WebView.destroy(WebView.java:707)
ViewParent parent = getParent();
if (parent instanceof ViewGroup) { // 由于自定义webView构建时传入了该Activity的context对象,因此需要先从父容器中移除webView,然后再销毁webView;
ViewGroup mWebViewContainer = (ViewGroup) getParent();
mWebViewContainer.removeAllViewsInLayout();
}
}
// 解决WebView内存泄漏问题;
private void releaseConfigCallback() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { // JELLY_BEAN
try {
Field field = WebView.class.getDeclaredField("mWebViewCore");
field = field.getType().getDeclaredField("mBrowserFrame");
field = field.getType().getDeclaredField("sConfigCallback");
field.setAccessible(true);
field.set(null, null);
} catch (NoSuchFieldException e) {
if (LogUtils.isDebug()) {
e.printStackTrace();
}
} catch (IllegalAccessException e) {
if (LogUtils.isDebug()) {
e.printStackTrace();
}
}
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { // KITKAT
try {
Field sConfigCallback = Class.forName("android.webkit.BrowserFrame").getDeclaredField("sConfigCallback");
if (sConfigCallback != null) {
sConfigCallback.setAccessible(true);
sConfigCallback.set(null, null);
}
} catch (NoSuchFieldException e) {
if (LogUtils.isDebug()) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
if (LogUtils.isDebug()) {
e.printStackTrace();
}
} catch (IllegalAccessException e) {
if (LogUtils.isDebug()) {
e.printStackTrace();
}
}
}
}
/**
* Android 4.4 KitKat 使用Chrome DevTools 远程调试WebView
* WebView.setWebContentsDebuggingEnabled(true);
* http://blog.csdn.net/t12x3456/article/details/14225235
*/
@TargetApi(19)
protected void trySetWebDebuggEnabled() {
if (LogUtils.isDebug() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
try {
Class<?> clazz = WebView.class;
Method method = clazz.getMethod("setWebContentsDebuggingEnabled", boolean.class);
method.invoke(null, true);
} catch (Throwable e) {
if (LogUtils.isDebug()) {
e.printStackTrace();
}
}
}
}
@TargetApi(11)
protected boolean removeSearchBoxJavaBridge() {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB
&& Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
Method method = this.getClass().getMethod("removeJavascriptInterface", String.class);
method.invoke(this, "searchBoxJavaBridge_");
return true;
}
} catch (Exception e) {
if (LogUtils.isDebug()) {
e.printStackTrace();
}
}
return false;
}
protected void fixedAccessibilityInjectorException() {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN_MR1
&& mIsAccessibilityEnabledOriginal == null
&& isAccessibilityEnabled()) {
mIsAccessibilityEnabledOriginal = true;
setAccessibilityEnabled(false);
}
}
protected void fixedAccessibilityInjectorExceptionForOnPageFinished(String url) {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN
&& getSettings().getJavaScriptEnabled()
&& mIsAccessibilityEnabledOriginal == null
&& isAccessibilityEnabled()) {
try {
try {
URLEncoder.encode(String.valueOf(new URI(url)), "utf-8");
// URLEncodedUtils.parse(new URI(url), null); // AccessibilityInjector.getAxsUrlParameterValue
} catch (IllegalArgumentException e) {
if ("bad parameter".equals(e.getMessage())) {
mIsAccessibilityEnabledOriginal = true;
setAccessibilityEnabled(false);
LogUtils.safeCheckCrash(TAG, "fixedAccessibilityInjectorExceptionForOnPageFinished.url = " + url, e);
}
}
} catch (Throwable e) {
if (LogUtils.isDebug()) {
LogUtils.e(TAG, "fixedAccessibilityInjectorExceptionForOnPageFinished", e);
}
}
}
}
private boolean isAccessibilityEnabled() {
AccessibilityManager am = (AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
return am.isEnabled();
}
private void setAccessibilityEnabled(boolean enabled) {
AccessibilityManager am = (AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
try {
Method setAccessibilityState = am.getClass().getDeclaredMethod("setAccessibilityState", boolean.class);
setAccessibilityState.setAccessible(true);
setAccessibilityState.invoke(am, enabled);
setAccessibilityState.setAccessible(false);
} catch (Throwable e) {
if (LogUtils.isDebug()) {
LogUtils.e(TAG, "setAccessibilityEnabled", e);
}
}
}
private void resetAccessibilityEnabled() {
if (mIsAccessibilityEnabledOriginal != null) {
setAccessibilityEnabled(mIsAccessibilityEnabledOriginal);
}
}
}
================================================
FILE: agentweb-core/src/main/java/com/just/agentweb/BaseIndicatorSpec.java
================================================
/*
* Copyright (C) Justson(https://github.com/Justson/AgentWeb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
package com.just.agentweb;
/**
* @author cenxiaozhong
* @since 1.0.0
*/
public interface BaseIndicatorSpec {
void show();
void hide();
void reset();
void setProgress(int newProgress);
}
================================================
FILE: agentweb-core/src/main/java/com/just/agentweb/BaseIndicatorView.java
================================================
/*
* Copyright (C) Justson(https://github.com/Justson/AgentWeb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
package com.just.agentweb;
import android.content.Context;
import androidx.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.FrameLayout;
/**
* @author cenxiaozhong
* @date 2017/5/12
* @since 1.0.0
*/
public abstract class BaseIndicatorView extends FrameLayout implements BaseIndicatorSpec,LayoutParamsOffer{
public BaseIndicatorView(Context context) {
super(context);
}
public BaseIndicatorView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public BaseIndicatorView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void reset() {
}
@Override
public void setProgress(int newProgress) {
}
@Override
public void show() {
}
@Override
public void hide() {
}
}
================================================
FILE: agentweb-core/src/main/java/com/just/agentweb/BaseJsAccessEntrace.java
================================================
/*
* Copyright (C) Justson(https://github.com/Justson/AgentWeb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
package com.just.agentweb;
import android.os.Build;
import android.webkit.ValueCallback;
import android.webkit.WebView;
/**
* @author cenxiaozhong
* @date 2017/5/26
* @since 1.0.0
*/
public abstract class BaseJsAccessEntrace implements JsAccessEntrace {
private WebView mWebView;
public static final String TAG=BaseJsAccessEntrace.class.getSimpleName();
BaseJsAccessEntrace(WebView webView){
this.mWebView=webView;
}
@Override
public void callJs(String js, final ValueCallback<String> callback) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
this.evaluateJs(js, callback);
} else {
this.loadJs(js);
}
}
@Override
public void callJs(String js) {
this.callJs(js, null);
}
private void loadJs(String js) {
mWebView.loadUrl(js);
}
private void evaluateJs(String js, final ValueCallback<String>callback){
mWebView.evaluateJavascript(js, new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
if (callback != null){
callback.onReceiveValue(value);
}
}
});
}
@Override
public void quickCallJs(String method, ValueCallback<String> callback, String... params) {
StringBuilder sb=new StringBuilder();
sb.append("javascript:"+method);
if(params==null||params.length==0){
sb.append("()");
}else{
sb.append("(").append(concat(params)).append(")");
}
callJs(sb.toString(),callback);
}
private String concat(String...params){
StringBuilder mStringBuilder=new StringBuilder();
for(int i=0;i<params.length;i++){
String param=params[i];
if(!AgentWebUtils.isJson(param)){
mStringBuilder.append("\"").append(param).append("\"");
}else{
mStringBuilder.append(param);
}
if(i!=params.length-1){
mStringBuilder.append(" , ");
}
}
return mStringBuilder.toString();
}
@Override
public void quickCallJs(String method, String... params) {
this.quickCallJs(method,null,params);
}
@Override
public void quickCallJs(String method) {
this.quickCallJs(method,(String[])null);
}
}
================================================
FILE: agentweb-core/src/main/java/com/just/agentweb/DefaultChromeClient.java
================================================
/*
* Copyright (C) Justson(https://github.com/Justson/AgentWeb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
package com.just.agentweb;
import android.Manifest;
import android.app.Activity;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import android.util.Log;
import android.view.View;
import android.webkit.ConsoleMessage;
import android.webkit.GeolocationPermissions;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.PermissionRequest;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebStorage;
import android.webkit.WebView;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static com.just.agentweb.AgentActionFragment.KEY_FROM_INTENTION;
/**
* @author cenxiaozhong
* @since 1.0.0
*/
public class DefaultChromeClient extends MiddlewareWebChromeBase {
/**
* Activity
*/
private WeakReference<Activity> mActivityWeakReference = null;
/**
* DefaultChromeClient 's TAG
*/
private String TAG = DefaultChromeClient.class.getSimpleName();
/**
* Android WebChromeClient path ,用于反射,用户是否重写来该方法
*/
public static final String ANDROID_WEBCHROMECLIENT_PATH = "android.webkit.WebChromeClient";
/**
* WebChromeClient
*/
private WebChromeClient mWebChromeClient;
/**
* 包装Flag
*/
private boolean mIsWrapper = false;
/**
* Video 处理类
*/
private IVideo mIVideo;
/**
* PermissionInterceptor 权限拦截器
*/
private PermissionInterceptor mPermissionInterceptor;
/**
* 当前 WebView
*/
private WebView mWebView;
/**
* Web端触发的定位 mOrigin
*/
private String mOrigin = null;
/**
* Web 端触发的定位 Callback 回调成功,或者失败
*/
private GeolocationPermissions.Callback mCallback = null;
/**
* 标志位
*/
public static final int FROM_CODE_INTENTION = 0x18;
/**
* 标识当前是获取定位权限
*/
public static final int FROM_CODE_INTENTION_LOCATION = FROM_CODE_INTENTION << 2;
/**
* AbsAgentWebUIController
*/
private WeakReference<AbsAgentWebUIController> mAgentWebUIController = null;
/**
* IndicatorController 进度条控制器
*/
private IndicatorController mIndicatorController;
/**
* 文件选择器
*/
private Object mFileChooser;
DefaultChromeClient(Activity activity,
IndicatorController indicatorController,
WebChromeClient chromeClient,
@Nullable IVideo iVideo,
PermissionInterceptor permissionInterceptor, WebView webView) {
super(chromeClient);
this.mIndicatorController = indicatorController;
mIsWrapper = chromeClient != null ? true : false;
this.mWebChromeClient = chromeClient;
mActivityWeakReference = new WeakReference<Activity>(activity);
this.mIVideo = iVideo;
this.mPermissionInterceptor = permissionInterceptor;
this.mWebView = webView;
mAgentWebUIController = new WeakReference<AbsAgentWebUIController>(AgentWebUtils.getAgentWebUIControllerByWebView(webView));
}
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
if (mIndicatorController != null) {
mIndicatorController.progress(view, newProgress);
}
}
@Override
public void onReceivedTitle(WebView view, String title) {
if (mIsWrapper) {
super.onReceivedTitle(view, title);
}
}
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
if (mAgentWebUIController.get() != null) {
mAgentWebUIController.get().onJsAlert(view, url, message);
}
result.confirm();
return true;
}
@Override
public void onReceivedIcon(WebView view, Bitmap icon) {
super.onReceivedIcon(view, icon);
}
@Override
public void onGeolocationPermissionsHidePrompt() {
super.onGeolocationPermissionsHidePrompt();
}
//location
@Override
public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
onGeolocationPermissionsShowPromptInternal(origin, callback);
}
private void onGeolocationPermissionsShowPromptInternal(String origin, GeolocationPermissions.Callback callback) {
if (mPermissionInterceptor != null) {
if (mPermissionInterceptor.intercept(this.mWebView.getUrl(), AgentWebPermissions.LOCATION, "location")) {
callback.invoke(origin, false, false);
return;
}
}
Activity mActivity = mActivityWeakReference.get();
if (mActivity == null) {
callback.invoke(origin, false, false);
return;
}
List<String> deniedPermissions = null;
if ((deniedPermissions = AgentWebUtils.getDeniedPermissions(mActivity, AgentWebPermissions.LOCATION)).isEmpty()) {
LogUtils.i(TAG, "onGeolocationPermissionsShowPromptInternal:" + true);
callback.invoke(origin, true, false);
} else {
Action mAction = Action.createPermissionsAction(deniedPermissions.toArray(new String[]{}));
mAction.setFromIntention(FROM_CODE_INTENTION_LOCATION);
mAction.setPermissionListener(mPermissionListener);
this.mCallback = callback;
this.mOrigin = origin;
AgentActionFragment.start(mActivity, mAction);
}
}
private AgentActionFragment.PermissionListener mPermissionListener = new AgentActionFragment.PermissionListener() {
@Override
public void onRequestPermissionsResult(@NonNull String[] permissions, @NonNull int[] grantResults, Bundle extras) {
if (extras.getInt(KEY_FROM_INTENTION) == FROM_CODE_INTENTION_LOCATION) {
boolean hasPermission = AgentWebUtils.hasPermission(mActivityWeakReference.get(), permissions);
if (mCallback != null) {
if (hasPermission) {
mCallback.invoke(mOrigin, true, false);
} else {
mCallback.invoke(mOrigin, false, false);
}
mCallback = null;
mOrigin = null;
}
if (!hasPermission && null != mAgentWebUIController.get()) {
mAgentWebUIController
.get()
.onPermissionsDeny(
AgentWebPermissions.LOCATION,
AgentWebPermissions.ACTION_LOCATION,
"Location");
}
}
}
};
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
try {
if (this.mAgentWebUIController.get() != null) {
this.mAgentWebUIController.get().onJsPrompt(mWebView, url, message, defaultValue, result);
}
} catch (Exception e) {
if (LogUtils.isDebug()) {
e.printStackTrace();
}
}
return true;
}
@Override
public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
if (mAgentWebUIController.get() != null) {
mAgentWebUIController.get().onJsConfirm(view, url, message, result);
}
return true;
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onPermissionRequest(PermissionRequest request) {
if (request == null) {
return;
}
final String[] resources = request.getResources();
if (resources == null || resources.length <= 0) {
request.deny();
return;
}
Set<String> resourcesSet = new HashSet<>(Arrays.asList(resources));
ArrayList<String> permissions = new ArrayList<>(resourcesSet.size());
if (resourcesSet.contains(PermissionRequest.RESOURCE_VIDEO_CAPTURE)) {
permissions.add(Manifest.permission.CAMERA);
}
if (resourcesSet.contains(PermissionRequest.RESOURCE_AUDIO_CAPTURE)) {
permissions.add(Manifest.permission.RECORD_AUDIO);
}
if (mPermissionInterceptor != null) {
boolean intercept = mPermissionInterceptor.intercept(mWebView.getUrl(), permissions.toArray(new String[]{}), "onPermissionRequest");
if (intercept) {
return;
}
}
if (mAgentWebUIController.get() != null) {
mAgentWebUIController.get().onPermissionRequest(request);
}
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onPermissionRequestCanceled(PermissionRequest request) {
super.onPermissionRequestCanceled(request);
}
@Override
public void onExceededDatabaseQuota(String url, String databaseIdentifier, long quota, long estimatedDatabaseSize, long totalQuota, WebStorage.QuotaUpdater quotaUpdater) {
quotaUpdater.updateQuota(totalQuota * 2);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
LogUtils.i(TAG, "openFileChooser>=5.0");
return openFileChooserAboveL(webView, filePathCallback, fileChooserParams);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private boolean openFileChooserAboveL(WebView webView, ValueCallback<Uri[]> valueCallbacks, FileChooserParams fileChooserParams) {
// LogUtils.i(TAG, "fileChooserParams:" + fileChooserParams.getAcceptTypes() + " getTitle:" + fileChooserParams.getTitle() + " accept:" + Arrays.toString(fileChooserParams.getAcceptTypes()) + " length:" + fileChooserParams.getAcceptTypes().length + " isCaptureEnabled:" + fileChooserParams.isCaptureEnabled() + " " + fileChooserParams.getFilenameHint() + " intent:" + fileChooserParams.createIntent().toString() + " mode:" + fileChooserParams.getMode());
if (valueCallbacks == null) {
return false;
}
Activity mActivity = this.mActivityWeakReference.get();
if (mActivity == null || mActivity.isFinishing()) {
return false;
}
return AgentWebUtils.showFileChooserCompat(mActivity,
mWebView,
valueCallbacks,
fileChooserParams,
this.mPermissionInterceptor,
null,
null,
null
);
}
/**
* Android >= 4.1
*
* @param uploadFile ValueCallback , File URI callback
* @param acceptType
* @param capture
*/
@Override
public void openFileChooser(ValueCallback<Uri> uploadFile, String acceptType, String capture) {
/*believe me , i never want to do this */
LogUtils.i(TAG, "openFileChooser>=4.1");
createAndOpenCommonFileChooser(uploadFile, acceptType);
}
// Android < 3.0
@Override
public void openFileChooser(ValueCallback<Uri> valueCallback) {
Log.i(TAG, "openFileChooser<3.0");
createAndOpenCommonFileChooser(valueCallback, "*/*");
}
// Android >= 3.0
@Override
public void openFileChooser(ValueCallback valueCallback, String acceptType) {
Log.i(TAG, "openFileChooser>3.0");
createAndOpenCommonFileChooser(valueCallback, acceptType);
}
private void createAndOpenCommonFileChooser(ValueCallback valueCallback, String mimeType) {
if (valueCallback == null) {
return;
}
Activity mActivity = this.mActivityWeakReference.get();
if (mActivity == null || mActivity.isFinishing()) {
valueCallback.onReceiveValue(new Object());
return;
}
AgentWebUtils.showFileChooserCompat(mActivity,
mWebView,
null,
null,
this.mPermissionInterceptor,
valueCallback,
mimeType,
null
);
}
@Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
super.onConsoleMessage(consoleMessage);
return true;
}
@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
if (mIVideo != null) {
mIVideo.onShowCustomView(view, callback);
}
}
@Override
public void onHideCustomView() {
if (mIVideo != null) {
mIVideo.onHideCustomView();
}
}
}
================================================
FILE: agentweb-core/src/main/java/com/just/agentweb/DefaultDesignUIController.java
================================================
/*
* Copyright (C) Justson(https://github.com/Justson/AgentWeb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
package com.just.agentweb;
import android.app.Activity;
import android.content.DialogInterface;
import android.graphics.Color;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.WebView;
import android.widget.TextView;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.google.android.material.snackbar.Snackbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
/**
* @author cenxiaozhong
* @date 2017/12/8
* @since 3.0.0
*/
public class DefaultDesignUIController extends DefaultUIController {
private BottomSheetDialog mBottomSheetDialog;
private static final int RECYCLERVIEW_ID = 0x1001;
private Activity mActivity = null;
private WebParentLayout mWebParentLayout;
private LayoutInflater mLayoutInflater;
@Override
public void onJsAlert(WebView view, String url, String message) {
onJsAlertInternal(view, message);
}
private void onJsAlertInternal(WebView view, String message) {
Activity mActivity = this.mActivity;
if (mActivity == null || mActivity.isFinishing()) {
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (mActivity.isDestroyed()) {
return;
}
}
try {
AgentWebUtils.show(view,
message,
Snackbar.LENGTH_SHORT,
Color.WHITE,
mActivity.getResources().getColor(R.color.black),
null,
-1,
null);
} catch (Throwable throwable) {
if (LogUtils.isDebug()){
throwable.printStackTrace();
}
}
}
@Override
public void onJsConfirm(WebView view, String url, String message, JsResult jsResult) {
super.onJsConfirm(view, url, message, jsResult);
}
@Override
public void onSelectItemsPrompt(WebView view, String url, String[] ways, Handler.Callback callback) {
showChooserInternal(view, url, ways, callback);
}
@Override
public void onForceDownloadAlert(String url, final Handler.Callback callback) {
super.onForceDownloadAlert(url, callback);
}
private void showChooserInternal(WebView view, String url, final String[] ways, final Handler.Callback callback) {
Activity mActivity;
if ((mActivity = this.mActivity) == null || mActivity.isFinishing()) {
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (mActivity.isDestroyed()) {
return;
}
}
LogUtils.i(TAG, "url:" + url + " ways:" + ways[0]);
RecyclerView mRecyclerView;
if (mBottomSheetDialog == null) {
mBottomSheetDialog = new BottomSheetDialog(mActivity);
mRecyclerView = new RecyclerView(mActivity);
mRecyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
mRecyclerView.setId(RECYCLERVIEW_ID);
mBottomSheetDialog.setContentView(mRecyclerView);
}
mRecyclerView = (RecyclerView) mBottomSheetDialog.getDelegate().findViewById(RECYCLERVIEW_ID);
mRecyclerView.setAdapter(getAdapter(ways, callback));
mBottomSheetDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
if (callback != null) {
callback.handleMessage(Message.obtain(null, -1));
}
}
});
mBottomSheetDialog.show();
}
private RecyclerView.Adapter getAdapter(final String[] ways, final Handler.Callback callback) {
return new RecyclerView.Adapter<BottomSheetHolder>() {
@Override
public BottomSheetHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
return new BottomSheetHolder(mLayoutInflater.inflate(android.R.layout.simple_list_item_1, viewGroup, false));
}
@Override
public void onBindViewHolder(BottomSheetHolder bottomSheetHolder, final int i) {
TypedValue outValue = new TypedValue();
mActivity.getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
bottomSheetHolder.mTextView.setBackgroundResource(outValue.resourceId);
bottomSheetHolder.mTextView.setText(ways[i]);
bottomSheetHolder.mTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mBottomSheetDialog != null && mBottomSheetDialog.isShowing()) {
mBottomSheetDialog.dismiss();
}
Message mMessage = Message.obtain();
mMessage.what = i;
callback.handleMessage(mMessage);
}
});
}
@Override
public int getItemCount() {
return ways.length;
}
};
}
private static class BottomSheetHolder extends RecyclerView.ViewHolder {
TextView mTextView;
public BottomSheetHolder(View itemView) {
super(itemView);
mTextView = (TextView) itemView.findViewById(android.R.id.text1);
}
}
@Override
public void onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult jsPromptResult) {
super.onJsPrompt(view, url, message, defaultValue, jsPromptResult);
}
@Override
protected void bindSupportWebParent(WebParentLayout webParentLayout, Activity activity) {
super.bindSupportWebParent(webParentLayout, activity);
this.mActivity = activity;
this.mWebParentLayout = webParentLayout;
mLayoutInflater = LayoutInflater.from(mActivity);
}
@Override
public void onShowMessage(String message, String from) {
Activity mActivity;
if ((mActivity = this.mActivity) == null || mActivity.isFinishing()) {
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (mActivity.isDestroyed()) {
return;
}
}
if (!TextUtils.isEmpty(from) && from.contains("performDownload")) {
return;
}
onJsAlertInternal(mWebParentLayout.getWebView(), message);
}
}
================================================
FILE: agentweb-core/src/main/java/com/just/agentweb/DefaultDownloadImpl.java
================================================
/*
* Copyright (C) Justson(https://github.com/Justson/AgentWeb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
package com.just.agentweb;
import android.app.Activity;
import android.content.Context;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.webkit.WebView;
import com.download.library.DownloadImpl;
import com.download.library.DownloadListenerAdapter;
import com.download.library.Extra;
import com.download.library.ResourceRequest;
import java.lang.ref.WeakReference;
import java.util.concurrent.ConcurrentHashMap;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* @author cenxiaozhong
* @date 2017/5/13
*/
public class DefaultDownloadImpl implements android.webkit.DownloadListener {
/**
* Application Context
*/
protected Context mContext;
protected ConcurrentHashMap<String, ResourceRequest> mDownloadTasks = new ConcurrentHashMap<>();
/**
* Activity
*/
protected WeakReference<Activity> mActivityWeakReference = null;
/**
* TAG 用于打印,标识
*/
private static final String TAG = DefaultDownloadImpl.class.getSimpleName();
/**
* 权限拦截
*/
protected PermissionInterceptor mPermissionListener = null;
/**
* AbsAgentWebUIController
*/
protected WeakReference<AbsAgentWebUIController> mAgentWebUIController;
private static Handler mHandler = new Handler(Looper.getMainLooper());
private boolean isInstallDownloader;
protected DefaultDownloadImpl(Activity activity, WebView webView, PermissionInterceptor permissionInterceptor) {
this.mContext = activity.getApplicationContext();
this.mActivityWeakReference = new WeakReference<Activity>(activity);
this.mPermissionListener = permissionInterceptor;
this.mAgentWebUIController = new WeakReference<AbsAgentWebUIController>(AgentWebUtils.getAgentWebUIControllerByWebView(webView));
try {
DownloadImpl.getInstance(this.mContext);
isInstallDownloader = true;
} catch (Throwable throwable) {
LogUtils.e(TAG, "implementation 'com.download.library:Downloader:x.x.x'");
if (LogUtils.isDebug()) {
throwable.printStackTrace();
}
isInstallDownloader = false;
}
}
@Override
public void onDownloadStart(final String url, final String userAgent, final String contentDisposition, final String mimetype, final long contentLength) {
if (!isInstallDownloader) {
LogUtils.e(TAG, "unable start download " + url + "; implementation 'com.download.library:Downloader:x.x.x'");
return;
}
mHandler.post(new Runnable() {
@Override
public void run() {
onDownloadStartInternal(url, userAgent, contentDisposition, mimetype, contentLength);
}
});
}
protected void onDownloadStartInternal(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
if (null == mActivityWeakReference.get() || mActivityWeakReference.get().isFinishing()) {
return;
}
if (null != this.mPermissionListener) {
if (this.mPermissionListener.intercept(url, new String[]{}, "download")) {
return;
}
}
ResourceRequest resourceRequest = createResourceRequest(url);
this.mDownloadTasks.put(url, resourceRequest);
preDownload(url);
}
protected ResourceRequest createResourceRequest(String url) {
return DownloadImpl.getInstance(this.mContext).with(url).setEnableIndicator(true).autoOpenIgnoreMD5();
}
protected void preDownload(String url) {
// 移动数据
if (!isForceRequest(url) &&
AgentWebUtils.checkNetworkType(mContext) > 1) {
showDialog(url);
return;
}
performDownload(url);
}
protected boolean isForceRequest(String url) {
ResourceRequest resourceRequest = mDownloadTasks.get(url);
if (null != resourceRequest) {
return resourceRequest.getDownloadTask().isForceDownload();
}
return false;
}
protected void forceDownload(final String url) {
ResourceRequest resourceRequest = mDownloadTasks.get(url);
resourceRequest.setForceDownload(true);
performDownload(url);
}
protected void showDialog(final String url) {
Activity mActivity;
if (null == (mActivity = mActivityWeakReference.get()) || mActivity.isFinishing()) {
return;
}
AbsAgentWebUIController mAgentWebUIController;
if (null != (mAgentWebUIController = this.mAgentWebUIController.get())) {
mAgentWebUIController.onForceDownloadAlert(url, createCallback(url));
}
}
protected Handler.Callback createCallback(final String url) {
return new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
forceDownload(url);
return true;
}
};
}
protected void performDownload(String url) {
try {
LogUtils.e(TAG, "performDownload:" + url + " exist:" + DownloadImpl.getInstance(this.mContext).exist(url));
// 该链接是否正在下载
if (DownloadImpl.getInstance(mContext).exist(url)) {
if (null != mAgentWebUIController.get()) {
mAgentWebUIController.get().onShowMessage(
mActivityWeakReference.get()
.getString(R.string.agentweb_download_task_has_been_exist), "preDownload");
}
return;
}
ResourceRequest resourceRequest = mDownloadTasks.get(url);
resourceRequest.addHeader("Cookie", AgentWebConfig.getCookiesByUrl(url));
taskEnqueue(resourceRequest);
} catch (Throwable ignore) {
if (LogUtils.isDebug()) {
ignore.printStackTrace();
}
}
}
protected void taskEnqueue(ResourceRequest resourceRequest) {
resourceRequest.enqueue(new DownloadListenerAdapter() {
@Override
public boolean onResult(Throwable throwable, Uri path, String url, Extra extra) {
mDownloadTasks.remove(url);
return super.onResult(throwable, path, url, extra);
}
});
}
public static DefaultDownloadImpl create(@NonNull Activity activity,
@NonNull WebView webView,
@Nullable PermissionInterceptor permissionInterceptor) {
return new DefaultDownloadImpl(activity, webView, permissionInterceptor);
}
}
================================================
FILE: agentweb-core/src/main/java/com/just/agentweb/DefaultUIController.java
================================================
/*
* Copyright (C) Justson(https://github.com/Justson/AgentWeb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
package com.just.agentweb;
import android.Manifest;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.net.http.SslError;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.PermissionRequest;
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
import android.widget.EditText;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
/**
* @author cenxiaozhong
* @date 2017/12/8
* @since 3.0.0
*/
public class DefaultUIController extends AbsAgentWebUIController {
private AlertDialog mAlertDialog;
protected AlertDialog mConfirmDialog;
private JsPromptResult mJsPromptResult = null;
private JsResult mJsResult = null;
private AlertDialog mPromptDialog = null;
private Activity mActivity;
private WebParentLayout mWebParentLayout;
private AlertDialog mAskOpenOtherAppDialog = null;
private ProgressDialog mProgressDialog;
private Resources mResources = null;
@Override
public void onJsAlert(WebView view, String url, String message) {
AgentWebUtils.toastShowShort(view.getContext().getApplicationContext(), message);
}
@Override
public void onOpenPagePrompt(WebView view, String url, final Handler.Callback callback) {
LogUtils.i(TAG, "onOpenPagePrompt");
Activity mActivity;
if ((mActivity = this.mActivity) == null || mActivity.isFinishing()) {
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (mActivity.isDestroyed()) {
return;
}
}
if (mAskOpenOtherAppDialog == null) {
mAskOpenOtherAppDialog = new AlertDialog
.Builder(mActivity)
.setMessage(mResources.getString(R.string.agentweb_leave_app_and_go_other_page,
AgentWebUtils.getApplicationName(mActivity)))
.setTitle(mResources.getString(R.string.agentweb_tips))
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (callback != null) {
callback.handleMessage(Message.obtain(null, -1));
}
}
})//
.setPositiveButton(mResources.getString(R.string.agentweb_leave), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (callback != null) {
callback.handleMessage(Message.obtain(null, 1));
}
}
})
.create();
}
mAskOpenOtherAppDialog.show();
}
@Override
public void onJsConfirm(WebView view, String url, String message, JsResult jsResult) {
onJsConfirmInternal(message, jsResult);
}
@Override
public void onSelectItemsPrompt(WebView view, String url, final String[] ways, final Handler.Callback callback) {
showChooserInternal(ways, callback);
}
@Override
public void onForceDownloadAlert(String url, final Handler.Callback callback) {
onForceDownloadAlertInternal(callback);
}
private void onForceDownloadAlertInternal(final Handler.Callback callback) {
Activity mActivity;
if ((mActivity = this.mActivity) == null || mActivity.isFinishing()) {
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (mActivity.isDestroyed()) {
return;
}
}
AlertDialog mAlertDialog = null;
mAlertDialog = new AlertDialog.Builder(mActivity)
.setTitle(mResources.getString(R.string.agentweb_tips))
.setMessage(mResources.getString(R.string.agentweb_honeycomblow))
.setNegativeButton(mResources.getString(R.string.agentweb_download), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (dialog != null) {
dialog.dismiss();
}
if (callback != null) {
callback.handleMessage(Message.obtain());
}
}
})//
.setPositiveButton(mResources.getString(R.string.agentweb_cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (dialog != null) {
dialog.dismiss();
}
}
}).create();
mAlertDialog.show();
}
private void showChooserInternal(String[] ways, final Handler.Callback callback) {
Activity mActivity;
if ((mActivity = this.mActivity) == null || mActivity.isFinishing()) {
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (mActivity.isDestroyed()) {
return;
}
}
mAlertDialog = new AlertDialog.Builder(mActivity)
.setSingleChoiceItems(ways, -1, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
LogUtils.i(TAG, "which:" + which);
if (callback != null) {
Message mMessage = Message.obtain();
mMessage.what = which;
callback.handleMessage(mMessage);
}
}
}).setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
dialog.dismiss();
if (callback != null) {
callback.handleMessage(Message.obtain(null, -1));
}
}
}).create();
mAlertDialog.show();
}
private void onJsConfirmInternal(String message, JsResult jsResult) {
LogUtils.i(TAG, "activity:" + mActivity.hashCode() + " ");
Activity mActivity = this.mActivity;
if (mActivity == null || mActivity.isFinishing()) {
toCancelJsresult(jsResult);
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (mActivity.isDestroyed()) {
toCancelJsresult(jsResult);
return;
}
}
if (mConfirmDialog == null) {
mConfirmDialog = new AlertDialog.Builder(mActivity)
.setMessage(message)
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
toDismissDialog(mConfirmDialog);
toCancelJsresult(mJsResult);
}
})//
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
toDismissDialog(mConfirmDialog);
if (mJsResult != null) {
mJsResult.confirm();
}
}
})
.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
dialog.dismiss();
toCancelJsresult(mJsResult);
}
})
.create();
}
mConfirmDialog.setMessage(message);
this.mJsResult = jsResult;
mConfirmDialog.show();
}
private void onJsPromptInternal(String message, String defaultValue, JsPromptResult jsPromptResult) {
Activity mActivity = this.mActivity;
if (mActivity == null || mActivity.isFinishing()) {
jsPromptResult.cancel();
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (mActivity.isDestroyed()) {
jsPromptResult.cancel();
return;
}
}
if (mPromptDialog == null) {
final EditText et = new EditText(mActivity);
et.setText(defaultValue);
mPromptDialog = new AlertDialog.Builder(mActivity)
.setView(et)
.setTitle(message)
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
toDismissDialog(mPromptDialog);
toCancelJsresult(mJsPromptResult);
}
})//
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
toDismissDialog(mPromptDialog);
if (mJsPromptResult != null) {
mJsPromptResult.confirm(et.getText().toString());
}
}
})
.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
dialog.dismiss();
toCancelJsresult(mJsPromptResult);
}
})
.create();
}
this.mJsPromptResult = jsPromptResult;
mPromptDialog.show();
}
@Override
public void onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult jsPromptResult) {
onJsPromptInternal(message, defaultValue, jsPromptResult);
}
@Override
public void onMainFrameError(WebView view, int errorCode, String description, String failingUrl) {
LogUtils.i(TAG, "mWebParentLayout onMainFrameError:" + mWebParentLayout);
if (mWebParentLayout != null) {
mWebParentLayout.showPageMainFrameError();
}
}
@Override
public void onShowMainFrame() {
if (mWebParentLayout != null) {
mWebParentLayout.hideErrorLayout();
}
}
@Override
public void onLoading(String msg) {
Activity mActivity;
if ((mActivity = this.mActivity) == null || mActivity.isFinishing()) {
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (mActivity.isDestroyed()) {
return;
}
}
if (mProgressDialog == null) {
mProgressDialog = new ProgressDialog(mActivity);
}
mProgressDialog.setCancelable(false);
mProgressDialog.setCanceledOnTouchOutside(false);
mProgressDialog.setMessage(msg);
mProgressDialog.show();
}
@Override
public void onCancelLoading() {
Activity mActivity;
if ((mActivity = this.mActivity) == null || mActivity.isFinishing()) {
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (mActivity.isDestroyed()) {
return;
}
}
if (mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
}
mProgressDialog = null;
}
@Override
public void onShowMessage(String message, String from) {
if (!TextUtils.isEmpty(from) && from.contains("performDownload")) {
return;
}
AgentWebUtils.toastShowShort(mActivity.getApplicationContext(), message);
}
@Override
public void onPermissionsDeny(String[] permissions, String permissionType, String action) {
// AgentWebUtils.toastShowShort(mActivity.getApplicationContext(), "权限被冻结");
}
@Override
public void onShowSslCertificateErrorDialog(final WebView view, final SslErrorHandler handler, final SslError error) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mActivity);
String sslErrorMessage;
switch (error.getPrimaryError()) {
case SslError.SSL_UNTRUSTED:
sslErrorMessage = mActivity.getString(R.string.agentweb_message_show_ssl_untrusted);
break;
case SslError.SSL_EXPIRED:
sslErrorMessage = mActivity.getString(R.string.agentweb_message_show_ssl_expired);
break;
case SslError.SSL_IDMISMATCH:
sslErrorMessage = mActivity.getString(R.string.agentweb_message_show_ssl_hostname_mismatch);
break;
case SslError.SSL_NOTYETVALID:
sslErrorMessage = mActivity.getString(R.string.agentweb_message_show_ssl_not_yet_valid);
break;
default:
sslErrorMessage = mActivity.getString(R.string.agentweb_message_show_ssl_error);
}
sslErrorMessage += mActivity.getString(R.string.agentweb_message_show_continue);
alertDialog.setTitle(mActivity.getString(R.string.agentweb_title_ssl_error));
alertDialog.setMessage(sslErrorMessage);
alertDialog.setPositiveButton(R.string.agentweb_continue, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// Ignore SSL certificate errors
handler.proceed();
}
});
alertDialog.setNegativeButton(R.string.agentweb_cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
handler.cancel();
}
});
alertDialog.show();
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onPermissionRequest(final PermissionRequest request) {
final String[] resources = request.getResources();
Set<String> resourcesSet = new HashSet<>(Arrays.asList(resources));
ArrayList<String> permissions = new ArrayList<>(resourcesSet.size());
if (resourcesSet.contains(PermissionRequest.RESOURCE_VIDEO_CAPTURE)) {
permissions.add(Manifest.permission.CAMERA);
}
if (resourcesSet.contains(PermissionRequest.RESOURCE_AUDIO_CAPTURE)) {
permissions.add(Manifest.permission.RECORD_AUDIO);
}
if(permissions.isEmpty()){
request.grant(resources);
return;
}
final List<String> denyPermission = AgentWebUtils.getDeniedPermissions(mActivity, permissions.toArray(new String[]{}));
if (denyPermission.isEmpty()) {
request.grant(resources);
} else {
Action action = Action.createPermissionsAction(denyPermission.toArray(new String[]{}));
action.setPermissionListener(new AgentActionFragment.PermissionListener() {
@Override
public void onRequestPermissionsResult(@NonNull String[] permissions, @NonNull int[] grantResults, Bundle extras) {
List<String> deny = AgentWebUtils.getDeniedPermissions(mActivity, denyPermission.toArray(new String[]{}));
if (deny.isEmpty()) {
request.grant(resources);
} else {
request.deny();
}
}
});
AgentActionFragment.start(mActivity, action);
}
}
private void toCancelJsresult(JsResult result) {
if (result != null) {
result.cancel();
}
}
@Override
protected void bindSupportWebParent(WebParentLayout webParentLayout, Activity activity) {
this.mActivity = activity;
this.mWebParentLayout = webParentLayout;
mResources = this.mActivity.getResources();
}
}
================================================
FILE: agentweb-core/src/main/java/com/just/agentweb/DefaultWebClient.java
================================================
/*
* Copyright (C) Justson(https://github.com/Justson/AgentWeb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
package com.just.agentweb;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import androidx.annotation.RequiresApi;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.HttpAuthHandler;
import android.webkit.SslErrorHandler;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.alipay.sdk.app.H5PayCallback;
import com.alipay.sdk.app.PayTask;
import com.alipay.sdk.util.H5PayResultModel;
import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author cenxiaozhong
* @since 3.0.0
*/
public class DefaultWebClient extends MiddlewareWebClientBase {
/**
* Activity's WeakReference
*/
private WeakReference<Activity> mWeakReference = null;
/**
* 缩放
*/
private static final int CONSTANTS_ABNORMAL_BIG = 7;
/**
* WebViewClient
*/
private WebViewClient mWebViewClient;
/**
* mWebClientHelper
*/
private boolean webClientHelper = true;
/**
* intent ' s scheme
*/
public static final String INTENT_SCHEME = "intent://";
/**
* Wechat pay scheme ,用于唤醒微信支付
*/
public static final String WEBCHAT_PAY_SCHEME = "weixin://wap/pay?";
/**
* 支付宝
*/
public static final String ALIPAYS_SCHEME = "alipays://";
/**
* http scheme
*/
public static final String HTTP_SCHEME = "http://";
/**
* https scheme
*/
public static final String HTTPS_SCHEME = "https://";
/**
* true 表示当前应用内依赖了 alipay library , false 反之
*/
private static final boolean HAS_ALIPAY_LIB;
/**
* WebViewClient's tag 用于打印
*/
private static final String TAG = DefaultWebClient.class.getSimpleName();
/**
* 直接打开其他页面
*/
public static final int DERECT_OPEN_OTHER_PAGE = 1001;
/**
* 弹窗咨询用户是否前往其他页面
*/
public static final int ASK_USER_O
gitextract_lyaxu09n/ ├── .github/ │ └── FUNDING.yml ├── .gitignore ├── LICENSE ├── README.md ├── agentweb-core/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ ├── providedLibs/ │ │ └── alipaySdk-20180601.jar │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── com/ │ │ └── just/ │ │ └── agentweb/ │ │ └── ExampleInstrumentedTest.java │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── just/ │ │ │ └── agentweb/ │ │ │ ├── AbsAgentWebSettings.java │ │ │ ├── AbsAgentWebUIController.java │ │ │ ├── Action.java │ │ │ ├── AgentActionFragment.java │ │ │ ├── AgentWeb.java │ │ │ ├── AgentWebCompat.java │ │ │ ├── AgentWebConfig.java │ │ │ ├── AgentWebFileProvider.java │ │ │ ├── AgentWebJsInterfaceCompat.java │ │ │ ├── AgentWebPermissions.java │ │ │ ├── AgentWebSettingsImpl.java │ │ │ ├── AgentWebUIControllerImplBase.java │ │ │ ├── AgentWebUtils.java │ │ │ ├── AgentWebView.java │ │ │ ├── BaseIndicatorSpec.java │ │ │ ├── BaseIndicatorView.java │ │ │ ├── BaseJsAccessEntrace.java │ │ │ ├── DefaultChromeClient.java │ │ │ ├── DefaultDesignUIController.java │ │ │ ├── DefaultDownloadImpl.java │ │ │ ├── DefaultUIController.java │ │ │ ├── DefaultWebClient.java │ │ │ ├── DefaultWebCreator.java │ │ │ ├── DefaultWebLifeCycleImpl.java │ │ │ ├── EventHandlerImpl.java │ │ │ ├── EventInterceptor.java │ │ │ ├── HookManager.java │ │ │ ├── HttpHeaders.java │ │ │ ├── IAgentWebSettings.java │ │ │ ├── IEventHandler.java │ │ │ ├── IUrlLoader.java │ │ │ ├── IVideo.java │ │ │ ├── IWebIndicator.java │ │ │ ├── IWebLayout.java │ │ │ ├── IndicatorController.java │ │ │ ├── IndicatorHandler.java │ │ │ ├── JsAccessEntrace.java │ │ │ ├── JsAccessEntraceImpl.java │ │ │ ├── JsBaseInterfaceHolder.java │ │ │ ├── JsCallJava.java │ │ │ ├── JsCallback.java │ │ │ ├── JsInterfaceHolder.java │ │ │ ├── JsInterfaceHolderImpl.java │ │ │ ├── JsInterfaceObjectException.java │ │ │ ├── LayoutParamsOffer.java │ │ │ ├── LogUtils.java │ │ │ ├── LollipopFixedWebView.java │ │ │ ├── MiddlewareWebChromeBase.java │ │ │ ├── MiddlewareWebClientBase.java │ │ │ ├── NestedScrollAgentWebView.java │ │ │ ├── PermissionInterceptor.java │ │ │ ├── ProcessUtils.java │ │ │ ├── Provider.java │ │ │ ├── QuickCallJs.java │ │ │ ├── RomUtils.java │ │ │ ├── UrlCommonException.java │ │ │ ├── UrlLoaderImpl.java │ │ │ ├── VideoImpl.java │ │ │ ├── WebChromeClient.java │ │ │ ├── WebChromeClientDelegate.java │ │ │ ├── WebCreator.java │ │ │ ├── WebIndicator.java │ │ │ ├── WebLifeCycle.java │ │ │ ├── WebListenerManager.java │ │ │ ├── WebParentLayout.java │ │ │ ├── WebSecurityCheckLogic.java │ │ │ ├── WebSecurityController.java │ │ │ ├── WebSecurityControllerImpl.java │ │ │ ├── WebSecurityLogicImpl.java │ │ │ ├── WebViewClient.java │ │ │ └── WebViewClientDelegate.java │ │ └── res/ │ │ ├── layout/ │ │ │ └── agentweb_error_page.xml │ │ ├── values/ │ │ │ ├── colors.xml │ │ │ ├── ids.xml │ │ │ ├── strings.xml │ │ │ └── style.xml │ │ ├── values-zh/ │ │ │ └── strings.xml │ │ └── xml/ │ │ └── web_files_public.xml │ └── test/ │ └── java/ │ └── com/ │ └── just/ │ └── agentweb/ │ └── ExampleUnitTest.java ├── agentweb-filechooser/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── com/ │ │ └── just/ │ │ └── agentweb/ │ │ └── filechooser/ │ │ └── ExampleInstrumentedTest.java │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── just/ │ │ │ └── agentweb/ │ │ │ └── filechooser/ │ │ │ ├── FileChooser.java │ │ │ ├── FileCompressor.java │ │ │ └── FileParcel.java │ │ └── res/ │ │ └── values/ │ │ └── strings.xml │ └── test/ │ └── java/ │ └── com/ │ └── just/ │ └── agentweb/ │ └── filechooser/ │ └── ExampleUnitTest.java ├── agentweb.apk ├── build.gradle ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat ├── jitpack.yml ├── releasenote.md ├── sample/ │ ├── .gitignore │ ├── build.gradle │ ├── keystore/ │ │ └── keystore.jks │ ├── keystore.jks │ ├── libs/ │ │ └── alipaySdk-20180601.jar │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── com/ │ │ └── just/ │ │ └── agentweb/ │ │ └── sample/ │ │ └── ExampleInstrumentedTest.java │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── assets/ │ │ │ ├── js_interaction/ │ │ │ │ ├── button.css │ │ │ │ └── hello.html │ │ │ ├── jsbridge/ │ │ │ │ └── demo.html │ │ │ ├── sms/ │ │ │ │ └── sms.html │ │ │ └── upload_file/ │ │ │ ├── event.js │ │ │ ├── jsuploadfile.html │ │ │ ├── upload.css │ │ │ └── uploadfile.html │ │ ├── java/ │ │ │ └── com/ │ │ │ └── just/ │ │ │ └── agentweb/ │ │ │ └── sample/ │ │ │ ├── activity/ │ │ │ │ ├── AutoHidenToolbarActivity.java │ │ │ │ ├── BaseWebActivity.java │ │ │ │ ├── CommonActivity.java │ │ │ │ ├── ContainerActivity.java │ │ │ │ ├── EasyWebActivity.java │ │ │ │ ├── ExternalActivity.java │ │ │ │ ├── MainActivity.java │ │ │ │ ├── NativeDownloadActivity.java │ │ │ │ ├── RemoteWebViewlActivity.java │ │ │ │ └── WebActivity.java │ │ │ ├── api/ │ │ │ │ └── Api.java │ │ │ ├── app/ │ │ │ │ └── App.java │ │ │ ├── base/ │ │ │ │ ├── BaseAgentWebActivity.java │ │ │ │ ├── BaseAgentWebFragment.java │ │ │ │ └── FragmentKeyDown.java │ │ │ ├── behavior/ │ │ │ │ └── BottomNavigationViewBehavior.java │ │ │ ├── client/ │ │ │ │ ├── MiddlewareChromeClient.java │ │ │ │ ├── MiddlewareWebViewClient.java │ │ │ │ └── SonicWebViewClient.java │ │ │ ├── common/ │ │ │ │ ├── AndroidInterface.java │ │ │ │ ├── CommonWebChromeClient.java │ │ │ │ ├── CustomSettings.java │ │ │ │ ├── FragmentKeyDown.java │ │ │ │ ├── GuideItemEntity.java │ │ │ │ └── UIController.java │ │ │ ├── fragment/ │ │ │ │ ├── AgentWebFragment.java │ │ │ │ ├── BounceWebFragment.java │ │ │ │ ├── CustomIndicatorFragment.java │ │ │ │ ├── CustomSettingsFragment.java │ │ │ │ ├── CustomWebViewFragment.java │ │ │ │ ├── EasyWebFragment.java │ │ │ │ ├── JsAgentWebFragment.java │ │ │ │ ├── JsbridgeWebFragment.java │ │ │ │ ├── SmartRefreshWebFragment.java │ │ │ │ └── VasSonicFragment.java │ │ │ ├── provider/ │ │ │ │ ├── ServiceProvider.java │ │ │ │ └── WebServiceProvider.java │ │ │ ├── service/ │ │ │ │ └── WebService.java │ │ │ ├── sonic/ │ │ │ │ ├── DefaultSonicRuntimeImpl.java │ │ │ │ ├── SonicImpl.java │ │ │ │ ├── SonicJavaScriptInterface.java │ │ │ │ ├── SonicSessionClientImpl.java │ │ │ │ └── SonicWebViewClient.java │ │ │ ├── utils/ │ │ │ │ ├── FileUtils.java │ │ │ │ ├── ProcessUtils.java │ │ │ │ └── WebCompat.java │ │ │ └── widget/ │ │ │ ├── CommonIndicator.java │ │ │ ├── CoolIndicatorLayout.java │ │ │ ├── SmartRefreshWebLayout.java │ │ │ └── WebLayout.java │ │ └── res/ │ │ ├── drawable/ │ │ │ ├── btn_shape.xml │ │ │ ├── btn_shape_s.xml │ │ │ ├── ic_baseline_search_24.xml │ │ │ ├── indicator_shape.xml │ │ │ ├── iv_back_selector.xml │ │ │ └── selector_drawable_for_btn.xml │ │ ├── drawable-v21/ │ │ │ ├── ripple_for_btn.xml │ │ │ └── selector_drawable_for_btn.xml │ │ ├── layout/ │ │ │ ├── activity_auto_hiden_toolbar.xml │ │ │ ├── activity_common.xml │ │ │ ├── activity_main.xml │ │ │ ├── activity_native_download.xml │ │ │ ├── activity_web.xml │ │ │ ├── fragment_agentweb.xml │ │ │ ├── fragment_js.xml │ │ │ ├── fragment_srl_web.xml │ │ │ ├── fragment_twk_web.xml │ │ │ ├── listview_main.xml │ │ │ ├── markdown_view.xml │ │ │ ├── recyclerview_item_download.xml │ │ │ └── toorbar_main.xml │ │ ├── menu/ │ │ │ └── toolbar_menu.xml │ │ ├── values/ │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ └── xml/ │ │ └── network_security_config.xml │ └── test/ │ └── java/ │ └── com/ │ └── just/ │ └── agentweb/ │ └── sample/ │ └── ExampleUnitTest.java └── settings.gradle
SYMBOL INDEX (1227 symbols across 131 files)
FILE: agentweb-core/src/androidTest/java/com/just/agentweb/ExampleInstrumentedTest.java
class ExampleInstrumentedTest (line 17) | @RunWith(AndroidJUnit4.class)
method useAppContext (line 19) | @Test
FILE: agentweb-core/src/main/java/com/just/agentweb/AbsAgentWebSettings.java
class AbsAgentWebSettings (line 34) | public abstract class AbsAgentWebSettings implements IAgentWebSettings, ...
method getInstance (line 42) | public static AbsAgentWebSettings getInstance() {
method AbsAgentWebSettings (line 46) | public AbsAgentWebSettings() {
method bindAgentWeb (line 49) | final void bindAgentWeb(AgentWeb agentWeb) {
method bindAgentWebSupport (line 54) | protected abstract void bindAgentWebSupport(AgentWeb agentWeb);
method toSetting (line 56) | @Override
method settings (line 62) | private void settings(WebView webView) {
method getWebSettings (line 126) | @Override
method setWebChromeClient (line 131) | @Override
method setWebViewClient (line 137) | @Override
method setDownloader (line 143) | @Override
FILE: agentweb-core/src/main/java/com/just/agentweb/AbsAgentWebUIController.java
class AbsAgentWebUIController (line 36) | public abstract class AbsAgentWebUIController {
method create (line 58) | protected AbsAgentWebUIController create() {
method getDelegate (line 62) | protected AbsAgentWebUIController getDelegate() {
method bindWebParent (line 70) | final synchronized void bindWebParent(WebParentLayout webParentLayout,...
method toDismissDialog (line 79) | protected void toDismissDialog(Dialog dialog) {
method toShowDialog (line 85) | protected void toShowDialog(Dialog dialog) {
method bindSupportWebParent (line 91) | protected abstract void bindSupportWebParent(WebParentLayout webParent...
method onJsAlert (line 100) | public abstract void onJsAlert(WebView view, String url, String message);
method onOpenPagePrompt (line 109) | public abstract void onOpenPagePrompt(WebView view, String url, Handle...
method onJsConfirm (line 119) | public abstract void onJsConfirm(WebView view, String url, String mess...
method onSelectItemsPrompt (line 121) | public abstract void onSelectItemsPrompt(WebView view, String url, Str...
method onForceDownloadAlert (line 129) | public abstract void onForceDownloadAlert(String url, Handler.Callback...
method onJsPrompt (line 140) | public abstract void onJsPrompt(WebView view, String url, String messa...
method onMainFrameError (line 150) | public abstract void onMainFrameError(WebView view, int errorCode, Str...
method onShowMainFrame (line 155) | public abstract void onShowMainFrame();
method onLoading (line 162) | public abstract void onLoading(String msg);
method onCancelLoading (line 167) | public abstract void onCancelLoading();
method onShowMessage (line 173) | public abstract void onShowMessage(String message, String intent);
method onPermissionsDeny (line 182) | public abstract void onPermissionsDeny(String[] permissions, String pe...
method onShowSslCertificateErrorDialog (line 190) | public abstract void onShowSslCertificateErrorDialog(WebView view, Ssl...
method onPermissionRequest (line 196) | public abstract void onPermissionRequest(PermissionRequest request);
FILE: agentweb-core/src/main/java/com/just/agentweb/Action.java
class Action (line 31) | public final class Action {
method Action (line 46) | public Action() {
method getPermissions (line 49) | public ArrayList<String> getPermissions() {
method setPermissions (line 53) | public void setPermissions(ArrayList<String> permissions) {
method setPermissions (line 57) | public void setPermissions(String[] permissions) {
method getAction (line 61) | public int getAction() {
method setAction (line 65) | public void setAction(int action) {
method getFromIntention (line 70) | public int getFromIntention() {
method createPermissionsAction (line 74) | public static Action createPermissionsAction(String[] permissions) {
method setFromIntention (line 82) | public Action setFromIntention(int fromIntention) {
method getRationaleListener (line 87) | public AgentActionFragment.RationaleListener getRationaleListener() {
method setRationaleListener (line 91) | public void setRationaleListener(AgentActionFragment.RationaleListener...
method getPermissionListener (line 95) | public AgentActionFragment.PermissionListener getPermissionListener() {
method setPermissionListener (line 99) | public void setPermissionListener(AgentActionFragment.PermissionListen...
method getChooserListener (line 103) | public AgentActionFragment.ChooserListener getChooserListener() {
method setChooserListener (line 107) | public void setChooserListener(AgentActionFragment.ChooserListener cho...
method getIntent (line 111) | public Intent getIntent() {
method getUri (line 115) | public Uri getUri() {
method setUri (line 119) | public void setUri(Uri uri) {
method setIntent (line 123) | public void setIntent(Intent intent) {
FILE: agentweb-core/src/main/java/com/just/agentweb/AgentActionFragment.java
class AgentActionFragment (line 44) | public final class AgentActionFragment extends Fragment {
method start (line 53) | public static void start(Activity activity, Action action) {
method AgentActionFragment (line 68) | public AgentActionFragment() {
method resetAction (line 71) | private void resetAction() {
method onCreate (line 77) | @Override
method onViewCreated (line 88) | @Override
method runAction (line 93) | private void runAction() {
method choose (line 115) | private void choose() {
method chooserActionCallback (line 135) | private void chooserActionCallback(int resultCode, Intent data) {
method onActivityResult (line 142) | @Override
method requestPermission (line 157) | @RequiresApi(api = Build.VERSION_CODES.M)
method captureCamera (line 182) | private void captureCamera() {
method recordVideo (line 208) | private void recordVideo() {
method onRequestPermissionsResult (line 237) | @Override
type RationaleListener (line 247) | public interface RationaleListener {
method onRationaleResult (line 248) | void onRationaleResult(boolean showRationale, Bundle extras);
type PermissionListener (line 251) | public interface PermissionListener {
method onRequestPermissionsResult (line 252) | void onRequestPermissionsResult(@NonNull String[] permissions, @NonN...
type ChooserListener (line 255) | public interface ChooserListener {
method onChoiceResult (line 256) | void onChoiceResult(int requestCode, int resultCode, Intent data);
method onDestroy (line 259) | @Override
FILE: agentweb-core/src/main/java/com/just/agentweb/AgentWeb.java
class AgentWeb (line 43) | public final class AgentWeb {
method AgentWeb (line 178) | private AgentWeb(AgentBuilder agentBuilder) {
method getPermissionInterceptor (line 221) | public PermissionInterceptor getPermissionInterceptor() {
method getWebLifeCycle (line 225) | public WebLifeCycle getWebLifeCycle() {
method getJsAccessEntrace (line 229) | public JsAccessEntrace getJsAccessEntrace() {
method clearWebCache (line 238) | public AgentWeb clearWebCache() {
method with (line 248) | public static AgentBuilder with(@NonNull Activity activity) {
method with (line 255) | public static AgentBuilder with(@NonNull Fragment fragment) {
method handleKeyEvent (line 263) | public boolean handleKeyEvent(int keyCode, KeyEvent keyEvent) {
method back (line 270) | public boolean back() {
method getWebCreator (line 278) | public WebCreator getWebCreator() {
method getIEventHandler (line 282) | public IEventHandler getIEventHandler() {
method getAgentWebSettings (line 287) | public IAgentWebSettings getAgentWebSettings() {
method getIndicatorController (line 291) | public IndicatorController getIndicatorController() {
method getJsInterfaceHolder (line 295) | public JsInterfaceHolder getJsInterfaceHolder() {
method getUrlLoader (line 299) | public IUrlLoader getUrlLoader() {
method destroy (line 303) | public void destroy() {
class PreAgentWeb (line 307) | public static class PreAgentWeb {
method PreAgentWeb (line 311) | PreAgentWeb(AgentWeb agentWeb) {
method ready (line 315) | public PreAgentWeb ready() {
method get (line 323) | public AgentWeb get() {
method go (line 328) | public AgentWeb go(@Nullable String url) {
method doSafeCheck (line 336) | private void doSafeCheck() {
method doCompat (line 344) | private void doCompat() {
method configWebCreator (line 348) | private WebCreator configWebCreator(BaseIndicatorView progressView, in...
method go (line 358) | private AgentWeb go(String url) {
method getInterceptor (line 367) | private EventInterceptor getInterceptor() {
method init (line 377) | private void init() {
method getIVideo (line 382) | private IVideo getIVideo() {
method getWebViewClient (line 386) | private WebViewClient getWebViewClient() {
method ready (line 419) | private AgentWeb ready() {
method getChromeClient (line 447) | private WebChromeClient getChromeClient() {
type SecurityType (line 481) | public enum SecurityType {
class AgentBuilder (line 485) | public static final class AgentBuilder {
method AgentBuilder (line 522) | public AgentBuilder(@NonNull Activity activity, @NonNull Fragment fr...
method AgentBuilder (line 528) | public AgentBuilder(@NonNull Activity activity) {
method setAgentWebParent (line 534) | public IndicatorBuilder setAgentWebParent(@NonNull ViewGroup v, @Non...
method setAgentWebParent (line 540) | public IndicatorBuilder setAgentWebParent(@NonNull ViewGroup v, int ...
method buildAgentWeb (line 547) | private PreAgentWeb buildAgentWeb() {
method addJavaObject (line 554) | private void addJavaObject(String key, Object o) {
method addHeader (line 561) | private void addHeader(String baseUrl, String k, String v) {
method addHeader (line 568) | private void addHeader(String baseUrl, Map<String, String> headers) {
class IndicatorBuilder (line 576) | public static class IndicatorBuilder {
method IndicatorBuilder (line 579) | public IndicatorBuilder(AgentBuilder agentBuilder) {
method useDefaultIndicator (line 583) | public CommonBuilder useDefaultIndicator(int color) {
method useDefaultIndicator (line 589) | public CommonBuilder useDefaultIndicator() {
method closeIndicator (line 594) | public CommonBuilder closeIndicator() {
method setCustomIndicator (line 601) | public CommonBuilder setCustomIndicator(@NonNull BaseIndicatorView v) {
method useDefaultIndicator (line 613) | public CommonBuilder useDefaultIndicator(@ColorInt int color, int he...
class CommonBuilder (line 620) | public static class CommonBuilder {
method CommonBuilder (line 623) | public CommonBuilder(AgentBuilder agentBuilder) {
method setEventHanadler (line 627) | public CommonBuilder setEventHanadler(@Nullable IEventHandler iEvent...
method closeWebViewClientHelper (line 632) | public CommonBuilder closeWebViewClientHelper() {
method setWebChromeClient (line 637) | public CommonBuilder setWebChromeClient(@Nullable com.just.agentweb....
method setWebViewClient (line 642) | public CommonBuilder setWebViewClient(@Nullable com.just.agentweb.We...
method useMiddlewareWebClient (line 647) | public CommonBuilder useMiddlewareWebClient(@NonNull MiddlewareWebCl...
method useMiddlewareWebChrome (line 660) | public CommonBuilder useMiddlewareWebChrome(@NonNull MiddlewareWebCh...
method setMainFrameErrorView (line 673) | public CommonBuilder setMainFrameErrorView(@NonNull View view) {
method setMainFrameErrorView (line 678) | public CommonBuilder setMainFrameErrorView(@LayoutRes int errorLayou...
method setAgentWebWebSettings (line 684) | public CommonBuilder setAgentWebWebSettings(@Nullable IAgentWebSetti...
method createAgentWeb (line 689) | public PreAgentWeb createAgentWeb() {
method addJavascriptInterface (line 694) | public CommonBuilder addJavascriptInterface(@NonNull String name, @N...
method setSecurityType (line 699) | public CommonBuilder setSecurityType(@NonNull SecurityType type) {
method setWebView (line 704) | public CommonBuilder setWebView(@Nullable WebView webView) {
method setWebLayout (line 709) | public CommonBuilder setWebLayout(@Nullable IWebLayout iWebLayout) {
method additionalHttpHeader (line 714) | public CommonBuilder additionalHttpHeader(String baseUrl, String k, ...
method additionalHttpHeader (line 719) | public CommonBuilder additionalHttpHeader(String baseUrl, Map<String...
method setPermissionInterceptor (line 724) | public CommonBuilder setPermissionInterceptor(@Nullable PermissionIn...
method setAgentWebUIController (line 729) | public CommonBuilder setAgentWebUIController(@Nullable AgentWebUICon...
method setOpenOtherPageWays (line 734) | public CommonBuilder setOpenOtherPageWays(@Nullable DefaultWebClient...
method interceptUnkownUrl (line 739) | public CommonBuilder interceptUnkownUrl() {
method isInterceptUnkownUrl (line 744) | public CommonBuilder isInterceptUnkownUrl(boolean isInterceptUnkownU...
method getActivity (line 750) | Activity getActivity() {
class PermissionInterceptorWrapper (line 754) | private static final class PermissionInterceptorWrapper implements Per...
method PermissionInterceptorWrapper (line 758) | private PermissionInterceptorWrapper(PermissionInterceptor permissio...
method intercept (line 762) | @Override
FILE: agentweb-core/src/main/java/com/just/agentweb/AgentWebCompat.java
class AgentWebCompat (line 20) | public class AgentWebCompat {
method setDataDirectorySuffix (line 29) | public static void setDataDirectorySuffix(Context context) {
method tryLockOrRecreateFile (line 72) | @TargetApi(Build.VERSION_CODES.P)
method createFile (line 91) | private static void createFile(File file, boolean deleted){
FILE: agentweb-core/src/main/java/com/just/agentweb/AgentWebConfig.java
class AgentWebConfig (line 37) | public class AgentWebConfig {
method getCookiesByUrl (line 78) | public static String getCookiesByUrl(String url) {
method debug (line 82) | public static void debug() {
method removeExpiredCookies (line 92) | public static void removeExpiredCookies() {
method removeAllCookies (line 103) | public static void removeAllCookies() {
method removeSessionCookies (line 108) | public static void removeSessionCookies() {
method syncCookie (line 118) | public static void syncCookie(String url, String cookies) {
method removeSessionCookies (line 126) | public static void removeSessionCookies(ValueCallback<Boolean> callbac...
method getCachePath (line 148) | public static String getCachePath(Context context) {
method getExternalCachePath (line 156) | public static String getExternalCachePath(Context context) {
method removeAllCookies (line 162) | public static void removeAllCookies(@Nullable ValueCallback<Boolean> c...
method clearDiskCache (line 181) | public static synchronized void clearDiskCache(Context context) {
method initCookiesManager (line 197) | static synchronized void initCookiesManager(Context context) {
method createCookiesSyncInstance (line 204) | private static void createCookiesSyncInstance(Context context) {
method toSyncCookies (line 210) | private static void toSyncCookies() {
method getDatabasesCachePath (line 223) | static String getDatabasesCachePath(Context context) {
method getDefaultIgnoreCallback (line 227) | private static ValueCallback<Boolean> getDefaultIgnoreCallback() {
FILE: agentweb-core/src/main/java/com/just/agentweb/AgentWebFileProvider.java
class AgentWebFileProvider (line 28) | public class AgentWebFileProvider extends FileProvider {
method attachInfo (line 30) | @Override
FILE: agentweb-core/src/main/java/com/just/agentweb/AgentWebJsInterfaceCompat.java
class AgentWebJsInterfaceCompat (line 30) | public class AgentWebJsInterfaceCompat {
method AgentWebJsInterfaceCompat (line 36) | AgentWebJsInterfaceCompat(AgentWeb agentWeb, Activity activity) {
method uploadFile (line 41) | @JavascriptInterface
method uploadFile (line 46) | @JavascriptInterface
FILE: agentweb-core/src/main/java/com/just/agentweb/AgentWebPermissions.java
class AgentWebPermissions (line 27) | public class AgentWebPermissions {
method emptyMediaPermission (line 57) | private static void emptyMediaPermission() {
method emptyCameraPermission (line 61) | private static void emptyCameraPermission() {
method dontAskUnnecessaryPermissions (line 65) | public static void dontAskUnnecessaryPermissions() {
FILE: agentweb-core/src/main/java/com/just/agentweb/AgentWebSettingsImpl.java
class AgentWebSettingsImpl (line 30) | public class AgentWebSettingsImpl extends AbsAgentWebSettings {
method bindAgentWebSupport (line 33) | @Override
method setDownloader (line 38) | @Override
method getActivityByContext (line 49) | private Activity getActivityByContext(Context context) {
FILE: agentweb-core/src/main/java/com/just/agentweb/AgentWebUIControllerImplBase.java
class AgentWebUIControllerImplBase (line 34) | public class AgentWebUIControllerImplBase extends AbsAgentWebUIController {
method build (line 36) | public static AbsAgentWebUIController build() {
method onJsAlert (line 40) | @Override
method onOpenPagePrompt (line 45) | @Override
method onJsConfirm (line 50) | @Override
method onSelectItemsPrompt (line 55) | @Override
method onForceDownloadAlert (line 60) | @Override
method onJsPrompt (line 65) | @Override
method onMainFrameError (line 70) | @Override
method onShowMainFrame (line 75) | @Override
method onLoading (line 80) | @Override
method onCancelLoading (line 85) | @Override
method onShowMessage (line 91) | @Override
method onPermissionsDeny (line 96) | @Override
method onShowSslCertificateErrorDialog (line 101) | @Override
method onPermissionRequest (line 106) | @Override
method bindSupportWebParent (line 111) | @Override
FILE: agentweb-core/src/main/java/com/just/agentweb/AgentWebUtils.java
class AgentWebUtils (line 92) | public class AgentWebUtils {
method AgentWebUtils (line 97) | private AgentWebUtils() {
method dp2px (line 101) | public static int dp2px(Context context, float dipValue) {
method clearWebView (line 106) | static final void clearWebView(WebView m) {
method getAgentWebFilePath (line 131) | public static String getAgentWebFilePath(Context context) {
method createFileByName (line 149) | public static File createFileByName(Context context, String name, bool...
method checkNetworkType (line 166) | public static int checkNetworkType(Context context) {
method getAvailableStorage (line 204) | public static long getAvailableStorage() {
method getUriFromFile (line 218) | public static Uri getUriFromFile(Context context, File file) {
method getUriFromFileForN (line 228) | static Uri getUriFromFileForN(Context context, File file) {
method setIntentDataAndType (line 234) | static void setIntentDataAndType(Context context,
method setIntentData (line 251) | static void setIntentData(Context context,
method getDiskExternalCacheDir (line 266) | static String getDiskExternalCacheDir(Context context) {
method grantPermissions (line 274) | static void grantPermissions(Context context, Intent intent, Uri uri, ...
method getMIMEType (line 289) | private static String getMIMEType(File f) {
method show (line 322) | static void show(View parent,
method dismiss (line 344) | static void dismiss() {
method checkWifi (line 351) | public static boolean checkWifi(Context context) {
method checkNetwork (line 360) | public static boolean checkNetwork(Context context) {
method isOverriedMethod (line 369) | static boolean isOverriedMethod(Object currentObject, String methodNam...
method isExistMethod (line 390) | static Method isExistMethod(Object o, String methodName, Class... claz...
method clearAgentWebCache (line 408) | static void clearAgentWebCache(Context context) {
method clearWebViewAllCache (line 418) | static void clearWebViewAllCache(Context context, WebView webView) {
method clearWebViewAllCache (line 437) | static void clearWebViewAllCache(Context context) {
method clearCacheFolder (line 445) | static int clearCacheFolder(final File dir, final int numDays) {
method clearCache (line 476) | static void clearCache(final Context context, final int numDays) {
method uriToPath (line 482) | public static String[] uriToPath(Activity activity, Uri[] uris) {
method getRealPathBelowVersion (line 503) | private static String getRealPathBelowVersion(Context context, Uri uri) {
method createImageFile (line 521) | public static File createImageFile(Context context) {
method createVideoFile (line 534) | static File createVideoFile(Context context){
method closeIO (line 548) | public static void closeIO(Closeable closeable) {
method getFileAbsolutePath (line 558) | @TargetApi(19)
method getDataColumn (line 613) | static String getDataColumn(Context context, Uri uri, String selection...
method isExternalStorageDocument (line 634) | static boolean isExternalStorageDocument(Uri uri) {
method isDownloadsDocument (line 642) | static boolean isDownloadsDocument(Uri uri) {
method isMediaDocument (line 650) | static boolean isMediaDocument(Uri uri) {
method isGooglePhotosUri (line 658) | static boolean isGooglePhotosUri(Uri uri) {
method getInstallApkIntentCompat (line 662) | static Intent getInstallApkIntentCompat(Context context, File file) {
method getCommonFileIntentCompat (line 668) | public static Intent getCommonFileIntentCompat(Context context, File f...
method getIntentCaptureCompat (line 674) | static Intent getIntentCaptureCompat(Context context, File file) {
method getIntentVideoCompat (line 682) | static Intent getIntentVideoCompat(Context context, File file){
method isJson (line 691) | static boolean isJson(String target) {
method isUIThread (line 710) | public static boolean isUIThread() {
method isEmptyCollection (line 714) | static boolean isEmptyCollection(Collection collection) {
method isEmptyMap (line 718) | static boolean isEmptyMap(Map map) {
method toastShowShort (line 723) | static void toastShowShort(Context context, String msg) {
method getUIControllerAndShowMessage (line 732) | @Deprecated
method hasPermission (line 744) | public static boolean hasPermission(@NonNull Context context, @NonNull...
method hasPermission (line 748) | public static boolean hasPermission(@NonNull Context context, @NonNull...
method getDeniedPermissions (line 769) | public static List<String> getDeniedPermissions(Activity activity, Str...
method getAgentWebUIControllerByWebView (line 783) | public static AbsAgentWebUIController getAgentWebUIControllerByWebView...
method getApplicationName (line 789) | public static String getApplicationName(Context context) {
method getWebParentLayoutByWebView (line 803) | static WebParentLayout getWebParentLayoutByWebView(WebView webView) {
method runInUiThread (line 829) | public static void runInUiThread(Runnable runnable) {
method showFileChooserCompat (line 836) | public static boolean showFileChooserCompat(Activity activity,
method md5 (line 905) | public static String md5(String str) {
FILE: agentweb-core/src/main/java/com/just/agentweb/AgentWebView.java
class AgentWebView (line 52) | public class AgentWebView extends LollipopFixedWebView {
method AgentWebView (line 60) | public AgentWebView(Context context) {
method AgentWebView (line 64) | public AgentWebView(Context context, AttributeSet attrs) {
method addJavascriptInterface (line 79) | @Override
method addJavascriptInterfaceSupport (line 103) | protected void addJavascriptInterfaceSupport(Object interfaceObj, Stri...
method setWebChromeClient (line 106) | @Override
method setWebChromeClientSupport (line 115) | protected final void setWebChromeClientSupport(WebChromeClient client) {
method setWebViewClient (line 118) | @Override
method setWebViewClientSupport (line 126) | public final void setWebViewClientSupport(WebViewClient client) {
method startActionMode (line 129) | @Override
method destroy (line 134) | @Override
method clearHistory (line 153) | @Override
method isWebViewPackageException (line 160) | public static Pair<Boolean, String> isWebViewPackageException(Throwabl...
method setOverScrollMode (line 173) | @Override
method isPrivateBrowsingEnabled (line 188) | @Override
method addInjectJavaScript (line 205) | public void addInjectJavaScript(String javaScript) {
method injectJavaScript (line 213) | private void injectJavaScript() {
method injectExtraJavaScript (line 219) | private void injectExtraJavaScript() {
method buildNotRepeatInjectJS (line 232) | public String buildNotRepeatInjectJS(String key, String js) {
method buildTryCatchInjectJS (line 253) | public String buildTryCatchInjectJS(String js) {
class AgentWebClient (line 262) | public static class AgentWebClient extends MiddlewareWebClientBase {
method AgentWebClient (line 266) | private AgentWebClient(AgentWebView agentWebView) {
method onPageStarted (line 271) | @Override
method onPageFinished (line 287) | @Override
class AgentWebChrome (line 299) | public static class AgentWebChrome extends MiddlewareWebChromeBase {
method AgentWebChrome (line 303) | private AgentWebChrome(AgentWebView agentWebView) {
method onReceivedTitle (line 307) | @Override
method onProgressChanged (line 313) | @Override
method onJsPrompt (line 328) | @Override
class FixedOnReceivedTitle (line 350) | private static class FixedOnReceivedTitle {
method setWebChromeClient (line 354) | public void setWebChromeClient(WebChromeClient webChromeClient) {
method onPageStarted (line 358) | public void onPageStarted() {
method onPageFinished (line 362) | public void onPageFinished(WebView view) {
method onReceivedTitle (line 381) | public void onReceivedTitle() {
method fixedStillAttached (line 387) | private void fixedStillAttached() {
method releaseConfigCallback (line 399) | private void releaseConfigCallback() {
method trySetWebDebuggEnabled (line 444) | @TargetApi(19)
method removeSearchBoxJavaBridge (line 459) | @TargetApi(11)
method fixedAccessibilityInjectorException (line 476) | protected void fixedAccessibilityInjectorException() {
method fixedAccessibilityInjectorExceptionForOnPageFinished (line 485) | protected void fixedAccessibilityInjectorExceptionForOnPageFinished(St...
method isAccessibilityEnabled (line 509) | private boolean isAccessibilityEnabled() {
method setAccessibilityEnabled (line 514) | private void setAccessibilityEnabled(boolean enabled) {
method resetAccessibilityEnabled (line 528) | private void resetAccessibilityEnabled() {
FILE: agentweb-core/src/main/java/com/just/agentweb/BaseIndicatorSpec.java
type BaseIndicatorSpec (line 25) | public interface BaseIndicatorSpec {
method show (line 27) | void show();
method hide (line 29) | void hide();
method reset (line 31) | void reset();
method setProgress (line 33) | void setProgress(int newProgress);
FILE: agentweb-core/src/main/java/com/just/agentweb/BaseIndicatorView.java
class BaseIndicatorView (line 30) | public abstract class BaseIndicatorView extends FrameLayout implements B...
method BaseIndicatorView (line 31) | public BaseIndicatorView(Context context) {
method BaseIndicatorView (line 35) | public BaseIndicatorView(Context context, @Nullable AttributeSet attrs) {
method BaseIndicatorView (line 39) | public BaseIndicatorView(Context context, @Nullable AttributeSet attrs...
method reset (line 43) | @Override
method setProgress (line 47) | @Override
method show (line 51) | @Override
method hide (line 55) | @Override
FILE: agentweb-core/src/main/java/com/just/agentweb/BaseJsAccessEntrace.java
class BaseJsAccessEntrace (line 28) | public abstract class BaseJsAccessEntrace implements JsAccessEntrace {
method BaseJsAccessEntrace (line 31) | BaseJsAccessEntrace(WebView webView){
method callJs (line 34) | @Override
method callJs (line 42) | @Override
method loadJs (line 47) | private void loadJs(String js) {
method evaluateJs (line 50) | private void evaluateJs(String js, final ValueCallback<String>callback){
method quickCallJs (line 62) | @Override
method concat (line 74) | private String concat(String...params){
method quickCallJs (line 90) | @Override
method quickCallJs (line 95) | @Override
FILE: agentweb-core/src/main/java/com/just/agentweb/DefaultChromeClient.java
class DefaultChromeClient (line 54) | public class DefaultChromeClient extends MiddlewareWebChromeBase {
method DefaultChromeClient (line 116) | DefaultChromeClient(Activity activity,
method onProgressChanged (line 133) | @Override
method onReceivedTitle (line 141) | @Override
method onJsAlert (line 148) | @Override
method onReceivedIcon (line 158) | @Override
method onGeolocationPermissionsHidePrompt (line 163) | @Override
method onGeolocationPermissionsShowPrompt (line 169) | @Override
method onGeolocationPermissionsShowPromptInternal (line 174) | private void onGeolocationPermissionsShowPromptInternal(String origin,...
method onRequestPermissionsResult (line 201) | @Override
method onJsPrompt (line 226) | @Override
method onJsConfirm (line 240) | @Override
method onPermissionRequest (line 248) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
method onPermissionRequestCanceled (line 278) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
method onExceededDatabaseQuota (line 284) | @Override
method onShowFileChooser (line 290) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
method openFileChooserAboveL (line 297) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
method openFileChooser (line 325) | @Override
method openFileChooser (line 333) | @Override
method openFileChooser (line 340) | @Override
method createAndOpenCommonFileChooser (line 347) | private void createAndOpenCommonFileChooser(ValueCallback valueCallbac...
method onConsoleMessage (line 367) | @Override
method onShowCustomView (line 373) | @Override
method onHideCustomView (line 380) | @Override
FILE: agentweb-core/src/main/java/com/just/agentweb/DefaultDesignUIController.java
class DefaultDesignUIController (line 46) | public class DefaultDesignUIController extends DefaultUIController {
method onJsAlert (line 54) | @Override
method onJsAlertInternal (line 59) | private void onJsAlertInternal(WebView view, String message) {
method onJsConfirm (line 85) | @Override
method onSelectItemsPrompt (line 90) | @Override
method onForceDownloadAlert (line 95) | @Override
method showChooserInternal (line 100) | private void showChooserInternal(WebView view, String url, final Strin...
method getAdapter (line 132) | private RecyclerView.Adapter getAdapter(final String[] ways, final Han...
class BottomSheetHolder (line 166) | private static class BottomSheetHolder extends RecyclerView.ViewHolder {
method BottomSheetHolder (line 168) | public BottomSheetHolder(View itemView) {
method onJsPrompt (line 174) | @Override
method bindSupportWebParent (line 179) | @Override
method onShowMessage (line 187) | @Override
FILE: agentweb-core/src/main/java/com/just/agentweb/DefaultDownloadImpl.java
class DefaultDownloadImpl (line 42) | public class DefaultDownloadImpl implements android.webkit.DownloadListe...
method DefaultDownloadImpl (line 69) | protected DefaultDownloadImpl(Activity activity, WebView webView, Perm...
method onDownloadStart (line 87) | @Override
method onDownloadStartInternal (line 101) | protected void onDownloadStartInternal(String url, String userAgent, S...
method createResourceRequest (line 115) | protected ResourceRequest createResourceRequest(String url) {
method preDownload (line 120) | protected void preDownload(String url) {
method isForceRequest (line 130) | protected boolean isForceRequest(String url) {
method forceDownload (line 138) | protected void forceDownload(final String url) {
method showDialog (line 144) | protected void showDialog(final String url) {
method createCallback (line 155) | protected Handler.Callback createCallback(final String url) {
method performDownload (line 165) | protected void performDownload(String url) {
method taskEnqueue (line 187) | protected void taskEnqueue(ResourceRequest resourceRequest) {
method create (line 197) | public static DefaultDownloadImpl create(@NonNull Activity activity,
FILE: agentweb-core/src/main/java/com/just/agentweb/DefaultUIController.java
class DefaultUIController (line 53) | public class DefaultUIController extends AbsAgentWebUIController {
method onJsAlert (line 66) | @Override
method onOpenPagePrompt (line 71) | @Override
method onJsConfirm (line 110) | @Override
method onSelectItemsPrompt (line 115) | @Override
method onForceDownloadAlert (line 120) | @Override
method onForceDownloadAlertInternal (line 125) | private void onForceDownloadAlertInternal(final Handler.Callback callb...
method showChooserInternal (line 162) | private void showChooserInternal(String[] ways, final Handler.Callback...
method onJsConfirmInternal (line 197) | private void onJsConfirmInternal(String message, JsResult jsResult) {
method onJsPromptInternal (line 247) | private void onJsPromptInternal(String message, String defaultValue, J...
method onJsPrompt (line 296) | @Override
method onMainFrameError (line 301) | @Override
method onShowMainFrame (line 310) | @Override
method onLoading (line 317) | @Override
method onCancelLoading (line 338) | @Override
method onShowMessage (line 355) | @Override
method onPermissionsDeny (line 363) | @Override
method onShowSslCertificateErrorDialog (line 368) | @Override
method onPermissionRequest (line 410) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
method toCancelJsresult (line 449) | private void toCancelJsresult(JsResult result) {
method bindSupportWebParent (line 456) | @Override
FILE: agentweb-core/src/main/java/com/just/agentweb/DefaultWebClient.java
class DefaultWebClient (line 60) | public class DefaultWebClient extends MiddlewareWebClientBase {
method DefaultWebClient (line 170) | DefaultWebClient(Builder builder) {
method shouldOverrideUrlLoading (line 185) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
method shouldInterceptRequest (line 225) | @Override
method onReceivedHttpAuthRequest (line 230) | @Override
method deepLink (line 235) | private boolean deepLink(String url) {
method shouldInterceptRequest (line 271) | @Override
method shouldOverrideUrlLoading (line 276) | @Override
method queryActiviesNumber (line 316) | private int queryActiviesNumber(String url) {
method handleIntentUrl (line 333) | private void handleIntentUrl(String intentUrl) {
method lookupResolveInfo (line 350) | private ResolveInfo lookupResolveInfo(String url) {
method lookup (line 369) | private boolean lookup(String url) {
method isAlipay (line 392) | private boolean isAlipay(final WebView view, String url) {
method handleCommonLink (line 434) | private boolean handleCommonLink(String url) {
method onPageStarted (line 457) | @Override
method onReceivedSslError (line 466) | @Override
method onReceivedError (line 482) | @Override
method doUpdateVisitedHistory (line 497) | @Override
method onReceivedError (line 505) | @TargetApi(Build.VERSION_CODES.M)
method onMainFrameError (line 531) | private void onMainFrameError(WebView view, int errorCode, String desc...
method onPageFinished (line 554) | @Override
method shouldOverrideKeyEvent (line 573) | @Override
method startActivity (line 579) | private void startActivity(String url) {
method onReceivedHttpError (line 596) | @Override
method onScaleChanged (line 602) | @Override
method getCallback (line 610) | private Handler.Callback getCallback(final String url) {
method createBuilder (line 630) | public static Builder createBuilder() {
class Builder (line 634) | public static class Builder {
method setActivity (line 643) | public Builder setActivity(Activity activity) {
method setClient (line 648) | public Builder setClient(WebViewClient client) {
method setWebClientHelper (line 653) | public Builder setWebClientHelper(boolean webClientHelper) {
method setPermissionInterceptor (line 658) | public Builder setPermissionInterceptor(PermissionInterceptor permis...
method setWebView (line 663) | public Builder setWebView(WebView webView) {
method setInterceptUnkownUrl (line 668) | public Builder setInterceptUnkownUrl(boolean interceptUnkownScheme) {
method setUrlHandleWays (line 673) | public Builder setUrlHandleWays(int urlHandleWays) {
method build (line 678) | public DefaultWebClient build() {
type OpenOtherPageWays (line 683) | public static enum OpenOtherPageWays {
method OpenOtherPageWays (line 698) | OpenOtherPageWays(int code) {
FILE: agentweb-core/src/main/java/com/just/agentweb/DefaultWebCreator.java
class DefaultWebCreator (line 37) | public class DefaultWebCreator implements WebCreator {
method DefaultWebCreator (line 70) | protected DefaultWebCreator(@NonNull Activity activity,
method DefaultWebCreator (line 99) | protected DefaultWebCreator(@NonNull Activity activity, @Nullable View...
method DefaultWebCreator (line 120) | protected DefaultWebCreator(@NonNull Activity activity, @Nullable View...
method setWebView (line 132) | public void setWebView(WebView webView) {
method getFrameLayout (line 136) | public FrameLayout getFrameLayout() {
method getTargetProgress (line 141) | public View getTargetProgress() {
method setTargetProgress (line 145) | public void setTargetProgress(View targetProgress) {
method create (line 149) | @Override
method getWebView (line 169) | @Override
method getWebParentLayout (line 174) | @Override
method getWebViewType (line 179) | @Override
method createLayout (line 184) | private ViewGroup createLayout() {
method webLayout (line 222) | private View webLayout() {
method createWebView (line 235) | private WebView createWebView() {
method offer (line 250) | @Override
FILE: agentweb-core/src/main/java/com/just/agentweb/DefaultWebLifeCycleImpl.java
class DefaultWebLifeCycleImpl (line 27) | public class DefaultWebLifeCycleImpl implements WebLifeCycle {
method DefaultWebLifeCycleImpl (line 29) | DefaultWebLifeCycleImpl(WebView webView) {
method onResume (line 33) | @Override
method onPause (line 43) | @Override
method onDestroy (line 53) | @Override
FILE: agentweb-core/src/main/java/com/just/agentweb/EventHandlerImpl.java
class EventHandlerImpl (line 31) | public class EventHandlerImpl implements IEventHandler {
method getInstantce (line 35) | public static final EventHandlerImpl getInstantce(WebView view, EventI...
method EventHandlerImpl (line 39) | public EventHandlerImpl(WebView webView, EventInterceptor eventInterce...
method onKeyDown (line 44) | @Override
method back (line 52) | @Override
FILE: agentweb-core/src/main/java/com/just/agentweb/EventInterceptor.java
type EventInterceptor (line 24) | public interface EventInterceptor {
method event (line 25) | boolean event();
FILE: agentweb-core/src/main/java/com/just/agentweb/HookManager.java
class HookManager (line 24) | public class HookManager {
method hookAgentWeb (line 26) | public static AgentWeb hookAgentWeb(AgentWeb agentWeb, AgentWeb.AgentB...
method permissionHook (line 30) | public static boolean permissionHook(String url,String[]permissions){
FILE: agentweb-core/src/main/java/com/just/agentweb/HttpHeaders.java
class HttpHeaders (line 31) | public class HttpHeaders {
method create (line 32) | public static HttpHeaders create() {
method HttpHeaders (line 38) | HttpHeaders() {
method getHeaders (line 42) | public Map<String, String> getHeaders(String url) {
method additionalHttpHeader (line 52) | public void additionalHttpHeader(String url, String k, String v) {
method additionalHttpHeaders (line 67) | public void additionalHttpHeaders(String url, Map<String, String> head...
method removeHttpHeader (line 80) | public void removeHttpHeader(String url, String k) {
method isEmptyHeaders (line 92) | public boolean isEmptyHeaders(String url) {
method getHeaders (line 98) | public Map<String, Map<String, String>> getHeaders() {
method subBaseUrl (line 102) | private String subBaseUrl(String originUrl) {
method toString (line 119) | @Override
FILE: agentweb-core/src/main/java/com/just/agentweb/IAgentWebSettings.java
type IAgentWebSettings (line 26) | public interface IAgentWebSettings<T extends android.webkit.WebSettings> {
method toSetting (line 28) | IAgentWebSettings toSetting(WebView webView);
method getWebSettings (line 30) | T getWebSettings();
FILE: agentweb-core/src/main/java/com/just/agentweb/IEventHandler.java
type IEventHandler (line 25) | public interface IEventHandler {
method onKeyDown (line 27) | boolean onKeyDown(int keyCode, KeyEvent event);
method back (line 29) | boolean back();
FILE: agentweb-core/src/main/java/com/just/agentweb/IUrlLoader.java
type IUrlLoader (line 27) | public interface IUrlLoader {
method loadUrl (line 30) | void loadUrl(String url);
method loadUrl (line 32) | void loadUrl(String url, Map<String, String> headers);
method reload (line 34) | void reload();
method loadData (line 36) | void loadData(String data, String mimeType, String encoding);
method stopLoading (line 38) | void stopLoading();
method loadDataWithBaseURL (line 40) | void loadDataWithBaseURL(String baseUrl, String data,
method postUrl (line 43) | void postUrl(String url, byte[] params);
method getHttpHeaders (line 45) | HttpHeaders getHttpHeaders();
FILE: agentweb-core/src/main/java/com/just/agentweb/IVideo.java
type IVideo (line 28) | public interface IVideo {
method onShowCustomView (line 31) | void onShowCustomView(View view, WebChromeClient.CustomViewCallback ca...
method onHideCustomView (line 34) | void onHideCustomView();
method isVideoState (line 37) | boolean isVideoState();
FILE: agentweb-core/src/main/java/com/just/agentweb/IWebIndicator.java
type IWebIndicator (line 25) | public interface IWebIndicator<T extends BaseIndicatorSpec> {
method offer (line 28) | T offer();
FILE: agentweb-core/src/main/java/com/just/agentweb/IWebLayout.java
type IWebLayout (line 33) | public interface IWebLayout<T extends WebView,V extends ViewGroup> {
method getLayout (line 39) | @NonNull V getLayout();
method getWebView (line 45) | @Nullable T getWebView();
FILE: agentweb-core/src/main/java/com/just/agentweb/IndicatorController.java
type IndicatorController (line 26) | public interface IndicatorController {
method progress (line 28) | void progress(WebView v, int newProgress);
method offerIndicator (line 30) | BaseIndicatorSpec offerIndicator();
method showIndicator (line 32) | void showIndicator();
method setProgress (line 34) | void setProgress(int newProgress);
method finish (line 36) | void finish();
FILE: agentweb-core/src/main/java/com/just/agentweb/IndicatorHandler.java
class IndicatorHandler (line 26) | public class IndicatorHandler implements IndicatorController {
method progress (line 29) | @Override
method offerIndicator (line 45) | @Override
method reset (line 50) | public void reset() {
method finish (line 57) | @Override
method setProgress (line 64) | @Override
method showIndicator (line 71) | @Override
method getInstance (line 79) | static IndicatorHandler getInstance() {
method inJectIndicator (line 84) | IndicatorHandler inJectIndicator(BaseIndicatorSpec baseIndicatorSpec) {
FILE: agentweb-core/src/main/java/com/just/agentweb/JsAccessEntrace.java
type JsAccessEntrace (line 26) | public interface JsAccessEntrace extends QuickCallJs {
method callJs (line 29) | void callJs(String js, ValueCallback<String> callback);
method callJs (line 31) | void callJs(String js);
FILE: agentweb-core/src/main/java/com/just/agentweb/JsAccessEntraceImpl.java
class JsAccessEntraceImpl (line 30) | public class JsAccessEntraceImpl extends BaseJsAccessEntrace {
method getInstance (line 35) | public static JsAccessEntraceImpl getInstance(WebView webView) {
method JsAccessEntraceImpl (line 39) | private JsAccessEntraceImpl(WebView webView) {
method safeCallJs (line 44) | private void safeCallJs(final String s, final ValueCallback valueCallb...
method callJs (line 53) | @Override
FILE: agentweb-core/src/main/java/com/just/agentweb/JsBaseInterfaceHolder.java
class JsBaseInterfaceHolder (line 30) | public abstract class JsBaseInterfaceHolder implements JsInterfaceHolder {
method JsBaseInterfaceHolder (line 35) | protected JsBaseInterfaceHolder(WebCreator webCreator, AgentWeb.Securi...
method checkObject (line 40) | @Override
method checkSecurity (line 66) | protected boolean checkSecurity() {
FILE: agentweb-core/src/main/java/com/just/agentweb/JsCallJava.java
class JsCallJava (line 30) | public class JsCallJava {
method JsCallJava (line 44) | public JsCallJava(Object interfaceObj, String interfaceName) {
method genJavaMethodSign (line 89) | private String genJavaMethodSign(Method method) {
method getPreloadInterfaceJs (line 123) | public String getPreloadInterfaceJs() {
method call (line 127) | public String call(WebView webView, JSONObject jsonObject) {
method getReturn (line 205) | private String getReturn(JSONObject reqJson, int stateCode, Object res...
method promptMsgFormat (line 226) | private static String promptMsgFormat(String object, String method, St...
method isSafeWebViewCallMsg (line 243) | static boolean isSafeWebViewCallMsg(String message) {
method getMsgJSONObject (line 247) | static JSONObject getMsgJSONObject(String message) {
method getInterfacedName (line 259) | static String getInterfacedName(JSONObject jsonObject) {
FILE: agentweb-core/src/main/java/com/just/agentweb/JsCallback.java
class JsCallback (line 29) | public class JsCallback {
method JsCallback (line 37) | public JsCallback(WebView view, String injectedName, int index) {
method apply (line 49) | public void apply (Object... args) throws JsCallbackException {
method isJavaScriptObject (line 83) | private boolean isJavaScriptObject(Object obj) {
method setPermanent (line 106) | public void setPermanent (boolean value) {
class JsCallbackException (line 110) | public static class JsCallbackException extends Exception {
method JsCallbackException (line 111) | public JsCallbackException (String msg) {
FILE: agentweb-core/src/main/java/com/just/agentweb/JsInterfaceHolder.java
type JsInterfaceHolder (line 26) | public interface JsInterfaceHolder {
method addJavaObjects (line 28) | JsInterfaceHolder addJavaObjects(Map<String, Object> maps);
method addJavaObject (line 30) | JsInterfaceHolder addJavaObject(String k, Object v);
method checkObject (line 32) | boolean checkObject(Object v);
FILE: agentweb-core/src/main/java/com/just/agentweb/JsInterfaceHolderImpl.java
class JsInterfaceHolderImpl (line 29) | public class JsInterfaceHolderImpl extends JsBaseInterfaceHolder {
method getJsInterfaceHolder (line 36) | static JsInterfaceHolderImpl getJsInterfaceHolder(WebCreator webCreato...
method JsInterfaceHolderImpl (line 40) | JsInterfaceHolderImpl(WebCreator webCreator, AgentWeb.SecurityType sec...
method addJavaObjects (line 47) | @Override
method addJavaObject (line 66) | @Override
method addJavaObjectDirect (line 80) | private JsInterfaceHolder addJavaObjectDirect(String k, Object v) {
FILE: agentweb-core/src/main/java/com/just/agentweb/JsInterfaceObjectException.java
class JsInterfaceObjectException (line 25) | public class JsInterfaceObjectException extends RuntimeException {
method JsInterfaceObjectException (line 26) | JsInterfaceObjectException(String msg){
FILE: agentweb-core/src/main/java/com/just/agentweb/LayoutParamsOffer.java
type LayoutParamsOffer (line 26) | public interface LayoutParamsOffer<T extends FrameLayout.LayoutParams> {
method offerLayoutParams (line 28) | T offerLayoutParams();
FILE: agentweb-core/src/main/java/com/just/agentweb/LogUtils.java
class LogUtils (line 26) | class LogUtils {
method isDebug (line 30) | static boolean isDebug() {
method i (line 34) | static void i(String tag, String message) {
method v (line 41) | static void v(String tag, String message) {
method safeCheckCrash (line 49) | static void safeCheckCrash(String tag, String msg, Throwable tr) {
method e (line 57) | static void e(String tag, String msg, Throwable tr) {
method e (line 61) | static void e(String tag, String message) {
FILE: agentweb-core/src/main/java/com/just/agentweb/LollipopFixedWebView.java
class LollipopFixedWebView (line 14) | @SuppressWarnings("unused")
method LollipopFixedWebView (line 16) | public LollipopFixedWebView(Context context) {
method LollipopFixedWebView (line 20) | public LollipopFixedWebView(Context context, AttributeSet attrs) {
method LollipopFixedWebView (line 24) | public LollipopFixedWebView(Context context, AttributeSet attrs, int d...
method LollipopFixedWebView (line 28) | @TargetApi(Build.VERSION_CODES.LOLLIPOP)
method LollipopFixedWebView (line 33) | public LollipopFixedWebView(Context context, AttributeSet attrs, int d...
method getFixedContext (line 37) | public static Context getFixedContext(Context context) {
FILE: agentweb-core/src/main/java/com/just/agentweb/MiddlewareWebChromeBase.java
class MiddlewareWebChromeBase (line 26) | public class MiddlewareWebChromeBase extends WebChromeClientDelegate {
method MiddlewareWebChromeBase (line 30) | protected MiddlewareWebChromeBase(WebChromeClient webChromeClient) {
method MiddlewareWebChromeBase (line 34) | protected MiddlewareWebChromeBase() {
method setDelegate (line 38) | @Override
method enq (line 43) | final MiddlewareWebChromeBase enq(MiddlewareWebChromeBase middlewareWe...
method next (line 50) | final MiddlewareWebChromeBase next() {
FILE: agentweb-core/src/main/java/com/just/agentweb/MiddlewareWebClientBase.java
class MiddlewareWebClientBase (line 26) | public class MiddlewareWebClientBase extends WebViewClientDelegate {
method MiddlewareWebClientBase (line 30) | MiddlewareWebClientBase(MiddlewareWebClientBase client) {
method MiddlewareWebClientBase (line 35) | protected MiddlewareWebClientBase(WebViewClient client) {
method MiddlewareWebClientBase (line 39) | protected MiddlewareWebClientBase() {
method next (line 43) | final MiddlewareWebClientBase next() {
method setDelegate (line 47) | @Override
method enq (line 53) | final MiddlewareWebClientBase enq(MiddlewareWebClientBase middleWrareW...
FILE: agentweb-core/src/main/java/com/just/agentweb/NestedScrollAgentWebView.java
class NestedScrollAgentWebView (line 32) | public class NestedScrollAgentWebView extends AgentWebView implements Ne...
method NestedScrollAgentWebView (line 40) | public NestedScrollAgentWebView(Context context) {
method NestedScrollAgentWebView (line 45) | public NestedScrollAgentWebView(Context context, AttributeSet attrs) {
method init (line 50) | private void init() {
method onTouchEvent (line 55) | @Override
method setNestedScrollingEnabled (line 106) | @Override
method isNestedScrollingEnabled (line 111) | @Override
method startNestedScroll (line 116) | @Override
method stopNestedScroll (line 121) | @Override
method hasNestedScrollingParent (line 126) | @Override
method dispatchNestedScroll (line 131) | @Override
method dispatchNestedPreScroll (line 136) | @Override
method dispatchNestedFling (line 141) | @Override
method dispatchNestedPreFling (line 146) | @Override
FILE: agentweb-core/src/main/java/com/just/agentweb/PermissionInterceptor.java
type PermissionInterceptor (line 23) | public interface PermissionInterceptor {
method intercept (line 24) | boolean intercept(String url, String[] permissions, String action);
FILE: agentweb-core/src/main/java/com/just/agentweb/ProcessUtils.java
class ProcessUtils (line 18) | class ProcessUtils {
method getCurrentProcessName (line 20) | static String getCurrentProcessName(Context context) {
method getCurrentProcessNameByFile (line 29) | private static String getCurrentProcessNameByFile() {
method getCurrentProcessNameByAms (line 42) | private static String getCurrentProcessNameByAms(Context context) {
method getCurrentProcessNameByReflect (line 58) | private static String getCurrentProcessNameByReflect(Context context) {
FILE: agentweb-core/src/main/java/com/just/agentweb/Provider.java
type Provider (line 24) | public interface Provider<T> {
method provide (line 25) | T provide();
FILE: agentweb-core/src/main/java/com/just/agentweb/QuickCallJs.java
type QuickCallJs (line 29) | public interface QuickCallJs {
method quickCallJs (line 30) | @RequiresApi(Build.VERSION_CODES.KITKAT)
method quickCallJs (line 33) | void quickCallJs(String method, String... params);
method quickCallJs (line 35) | void quickCallJs(String method);
FILE: agentweb-core/src/main/java/com/just/agentweb/RomUtils.java
class RomUtils (line 25) | public final class RomUtils {
method RomUtils (line 33) | private RomUtils() {
method isHuawei (line 42) | public static boolean isHuawei() {
method getRomInfo (line 51) | public static RomInfo getRomInfo() {
method isRightRom (line 73) | private static boolean isRightRom(final String brand, final String man...
method getManufacturer (line 82) | private static String getManufacturer() {
method getBrand (line 92) | private static String getBrand() {
method getRomVersion (line 102) | private static String getRomVersion(final String propertyName) {
method getSystemProperty (line 121) | private static String getSystemProperty(final String name) {
method getSystemPropertyByShell (line 132) | private static String getSystemPropertyByShell(final String propName) {
method getSystemPropertyByStream (line 153) | private static String getSystemPropertyByStream(final String key) {
method getSystemPropertyByReflect (line 165) | private static String getSystemPropertyByReflect(String key) {
class RomInfo (line 175) | public static class RomInfo {
method getName (line 179) | public String getName() {
method getVersion (line 183) | public String getVersion() {
method toString (line 187) | @Override
FILE: agentweb-core/src/main/java/com/just/agentweb/UrlCommonException.java
class UrlCommonException (line 22) | public class UrlCommonException extends RuntimeException {
method UrlCommonException (line 24) | public UrlCommonException() {
method UrlCommonException (line 27) | public UrlCommonException(String msg) {
FILE: agentweb-core/src/main/java/com/just/agentweb/UrlLoaderImpl.java
class UrlLoaderImpl (line 29) | public class UrlLoaderImpl implements IUrlLoader {
method UrlLoaderImpl (line 35) | UrlLoaderImpl(WebView webView, HttpHeaders httpHeaders) {
method safeLoadUrl (line 47) | private void safeLoadUrl(final String url) {
method safeReload (line 56) | private void safeReload() {
method loadUrl (line 65) | @Override
method loadUrl (line 70) | @Override
method reload (line 89) | @Override
method loadData (line 103) | @Override
method stopLoading (line 117) | @Override
method loadDataWithBaseURL (line 131) | @Override
method postUrl (line 145) | @Override
method getHttpHeaders (line 159) | @Override
FILE: agentweb-core/src/main/java/com/just/agentweb/VideoImpl.java
class VideoImpl (line 37) | public class VideoImpl implements IVideo, EventInterceptor {
method VideoImpl (line 48) | public VideoImpl(Activity mActivity, WebView webView) {
method onShowCustomView (line 54) | @Override
method onHideCustomView (line 97) | @Override
method isVideoState (line 127) | @Override
method event (line 132) | @Override
FILE: agentweb-core/src/main/java/com/just/agentweb/WebChromeClient.java
class WebChromeClient (line 8) | public class WebChromeClient extends MiddlewareWebChromeBase{
method WebChromeClient (line 9) | public WebChromeClient() {
FILE: agentweb-core/src/main/java/com/just/agentweb/WebChromeClientDelegate.java
class WebChromeClientDelegate (line 42) | public class WebChromeClientDelegate extends WebChromeClient {
method getDelegate (line 45) | protected WebChromeClient getDelegate() {
method WebChromeClientDelegate (line 49) | public WebChromeClientDelegate(WebChromeClient webChromeClient) {
method setDelegate (line 53) | void setDelegate(WebChromeClient delegate) {
method onProgressChanged (line 57) | @Override
method onReceivedTitle (line 66) | @Override
method onReceivedIcon (line 75) | @Override
method onReceivedTouchIconUrl (line 84) | @Override
method onShowCustomView (line 94) | @Override
method onShowCustomView (line 104) | @Override
method onHideCustomView (line 115) | @Override
method onCreateWindow (line 124) | @Override
method onRequestFocus (line 133) | @Override
method onCloseWindow (line 142) | @Override
method onJsAlert (line 151) | @Override
method onJsConfirm (line 160) | @Override
method onJsPrompt (line 169) | @Override
method onJsBeforeUnload (line 178) | @Override
method onExceededDatabaseQuota (line 187) | @Override
method onGeolocationPermissionsShowPrompt (line 203) | @Override
method onGeolocationPermissionsHidePrompt (line 220) | @Override
method onPermissionRequest (line 231) | @Override
method onPermissionRequestCanceled (line 241) | @Override
method onJsTimeout (line 252) | @Override
method onConsoleMessage (line 260) | @Override
method onConsoleMessage (line 270) | @Override
method getDefaultVideoPoster (line 281) | @Override
method getVideoLoadingProgressView (line 289) | @Override
method getVisitedHistory (line 297) | @Override
method onShowFileChooser (line 306) | @Override
method openFileChooser (line 324) | public void openFileChooser(ValueCallback<Uri> uploadFile, String acce...
method openFileChooser (line 333) | public void openFileChooser(ValueCallback<Uri> valueCallback) {
method openFileChooser (line 343) | public void openFileChooser(ValueCallback valueCallback, String accept...
method commonRefect (line 348) | private void commonRefect(WebChromeClient o, String mothed, Object[] o...
FILE: agentweb-core/src/main/java/com/just/agentweb/WebCreator.java
type WebCreator (line 25) | public interface WebCreator extends IWebIndicator {
method create (line 26) | WebCreator create();
method getWebView (line 28) | WebView getWebView();
method getWebParentLayout (line 30) | FrameLayout getWebParentLayout();
method getWebViewType (line 32) | int getWebViewType();
FILE: agentweb-core/src/main/java/com/just/agentweb/WebIndicator.java
class WebIndicator (line 38) | public class WebIndicator extends BaseIndicatorView implements BaseIndic...
method WebIndicator (line 92) | public WebIndicator(Context context) {
method WebIndicator (line 96) | public WebIndicator(Context context, @Nullable AttributeSet attrs) {
method WebIndicator (line 100) | public WebIndicator(Context context, @Nullable AttributeSet attrs, int...
method init (line 105) | private void init(Context context, AttributeSet attrs, int defStyleAtt...
method setColor (line 116) | public void setColor(int color) {
method setColor (line 121) | public void setColor(String color) {
method onMeasure (line 125) | @Override
method onDraw (line 142) | @Override
method dispatchDraw (line 146) | @Override
method show (line 151) | @Override
method onSizeChanged (line 160) | @Override
method setProgress (line 180) | public void setProgress(float progress) {
method hide (line 192) | @Override
method startAnim (line 197) | private void startAnim(boolean isFinished) {
method onAnimationUpdate (line 253) | @Override
method onAnimationEnd (line 262) | @Override
method onDetachedFromWindow (line 268) | @Override
method doEnd (line 280) | private void doEnd() {
method reset (line 289) | @Override
method setProgress (line 297) | @Override
method offerLayoutParams (line 303) | @Override
FILE: agentweb-core/src/main/java/com/just/agentweb/WebLifeCycle.java
type WebLifeCycle (line 24) | public interface WebLifeCycle {
method onResume (line 25) | void onResume();
method onPause (line 26) | void onPause();
method onDestroy (line 27) | void onDestroy();
FILE: agentweb-core/src/main/java/com/just/agentweb/WebListenerManager.java
type WebListenerManager (line 29) | public interface WebListenerManager {
method setWebChromeClient (line 30) | WebListenerManager setWebChromeClient(WebView webview, WebChromeClient...
method setWebViewClient (line 31) | WebListenerManager setWebViewClient(WebView webView, WebViewClient web...
method setDownloader (line 32) | WebListenerManager setDownloader(WebView webView, DownloadListener dow...
FILE: agentweb-core/src/main/java/com/just/agentweb/WebParentLayout.java
class WebParentLayout (line 39) | public class WebParentLayout extends FrameLayout implements Provider<Abs...
method WebParentLayout (line 50) | WebParentLayout(@NonNull Context context) {
method WebParentLayout (line 55) | WebParentLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
method WebParentLayout (line 59) | WebParentLayout(@NonNull Context context, @Nullable AttributeSet attrs...
method bindController (line 67) | void bindController(AbsAgentWebUIController agentWebUIController) {
method showPageMainFrameError (line 72) | void showPageMainFrameError() {
method createErrorLayout (line 88) | private void createErrorLayout() {
method hideErrorLayout (line 139) | void hideErrorLayout() {
method setErrorView (line 146) | void setErrorView(@NonNull View errorView) {
method setErrorLayoutRes (line 150) | void setErrorLayoutRes(@LayoutRes int resLayout, @IdRes int id) {
method provide (line 161) | @Override
method bindWebView (line 167) | void bindWebView(WebView view) {
method getWebView (line 173) | WebView getWebView() {
FILE: agentweb-core/src/main/java/com/just/agentweb/WebSecurityCheckLogic.java
type WebSecurityCheckLogic (line 26) | public interface WebSecurityCheckLogic {
method dealHoneyComb (line 27) | void dealHoneyComb(WebView view);
method dealJsInterface (line 28) | void dealJsInterface(ArrayMap<String, Object> objects,AgentWeb.Securit...
FILE: agentweb-core/src/main/java/com/just/agentweb/WebSecurityController.java
type WebSecurityController (line 22) | public interface WebSecurityController<T> {
method check (line 23) | void check(T t);
FILE: agentweb-core/src/main/java/com/just/agentweb/WebSecurityControllerImpl.java
class WebSecurityControllerImpl (line 27) | public class WebSecurityControllerImpl implements WebSecurityController<...
method WebSecurityControllerImpl (line 33) | public WebSecurityControllerImpl(WebView view, ArrayMap<String, Object...
method check (line 39) | @Override
FILE: agentweb-core/src/main/java/com/just/agentweb/WebSecurityLogicImpl.java
class WebSecurityLogicImpl (line 28) | public class WebSecurityLogicImpl implements WebSecurityCheckLogic {
method getInstance (line 32) | public static WebSecurityLogicImpl getInstance(int webViewType) {
method WebSecurityLogicImpl (line 36) | public WebSecurityLogicImpl(int webViewType) {
method dealHoneyComb (line 40) | @TargetApi(Build.VERSION_CODES.HONEYCOMB)
method dealJsInterface (line 51) | @Override
FILE: agentweb-core/src/main/java/com/just/agentweb/WebViewClient.java
class WebViewClient (line 8) | public class WebViewClient extends MiddlewareWebClientBase {
method WebViewClient (line 9) | public WebViewClient() {
FILE: agentweb-core/src/main/java/com/just/agentweb/WebViewClientDelegate.java
class WebViewClientDelegate (line 37) | public class WebViewClientDelegate extends WebViewClient {
method WebViewClientDelegate (line 42) | WebViewClientDelegate(WebViewClient client) {
method getDelegate (line 46) | protected WebViewClient getDelegate() {
method setDelegate (line 50) | void setDelegate(WebViewClient delegate) {
method shouldOverrideUrlLoading (line 54) | @Deprecated
method shouldOverrideUrlLoading (line 63) | @Override
method onPageStarted (line 71) | @Override
method onPageFinished (line 80) | @Override
method onLoadResource (line 89) | @Override
method onPageCommitVisible (line 98) | @Override
method shouldInterceptRequest (line 107) | @Override
method shouldInterceptRequest (line 117) | @Override
method onTooManyRedirects (line 126) | @Override
method onReceivedError (line 137) | @Override
method onReceivedError (line 148) | @Override
method onReceivedHttpError (line 157) | @Override
method onFormResubmission (line 167) | @Override
method doUpdateVisitedHistory (line 178) | @Override
method onReceivedSslError (line 188) | @Override
method onReceivedClientCertRequest (line 198) | @Override
method onReceivedHttpAuthRequest (line 207) | @Override
method shouldOverrideKeyEvent (line 217) | @Override
method onUnhandledKeyEvent (line 225) | @Override
method onScaleChanged (line 235) | @Override
method onReceivedLoginRequest (line 244) | @Override
FILE: agentweb-core/src/test/java/com/just/agentweb/ExampleUnitTest.java
class ExampleUnitTest (line 12) | public class ExampleUnitTest {
method addition_isCorrect (line 13) | @Test
FILE: agentweb-filechooser/src/androidTest/java/com/just/agentweb/filechooser/ExampleInstrumentedTest.java
class ExampleInstrumentedTest (line 17) | @RunWith(AndroidJUnit4.class)
method useAppContext (line 19) | @Test
FILE: agentweb-filechooser/src/main/java/com/just/agentweb/filechooser/FileChooser.java
class FileChooser (line 77) | public class FileChooser {
method FileChooser (line 144) | public FileChooser(Builder builder) {
method openFileChooser (line 162) | public void openFileChooser() {
method fileChooser (line 176) | private void fileChooser() {
method chooserAction (line 191) | private void chooserAction() {
method getFileChooserIntent (line 206) | private Intent getFileChooserIntent() {
method getChooserListener (line 240) | private AgentActionFragment.ChooserListener getChooserListener() {
method openFileChooserInternal (line 251) | private void openFileChooserInternal() {
method getCallBack (line 293) | private Handler.Callback getCallBack() {
method onCameraAction (line 316) | private void onCameraAction() {
method checkNeedPermission (line 341) | private List<String> checkNeedPermission() {
method openCameraAction (line 354) | private void openCameraAction() {
method onRequestPermissionsResult (line 367) | @Override
method permissionResult (line 377) | private void permissionResult(boolean grant, int fromIntention) {
method onIntentResult (line 412) | public void onIntentResult(int requestCode, int resultCode, Intent dat...
method cancel (line 470) | private void cancel() {
method belowLollipopUriCallback (line 500) | private void belowLollipopUriCallback(Intent data) {
method processData (line 519) | private Uri[] processData(Intent data) {
method convertFileAndCallback (line 547) | private void convertFileAndCallback(final Uri[] uris) {
method fileCompressAndValuesCallback (line 589) | private static void fileCompressAndValuesCallback(final Uri[] datas, f...
method fileCompressAndValuesCallback (line 601) | private static void fileCompressAndValuesCallback(final Uri datas, fin...
method aboveLollipopCheckFilesAndCallback (line 624) | private void aboveLollipopCheckFilesAndCallback(final Uri[] datas, boo...
class AboveLCallback (line 667) | private static final class AboveLCallback implements Handler.Callback {
method AboveLCallback (line 672) | private AboveLCallback(ValueCallback<Uri[]> valueCallbacks, Uri[] ur...
method handleMessage (line 678) | @Override
method safeHandleMessage (line 690) | private void safeHandleMessage(Message msg) {
class WaitPhotoRunnable (line 701) | private static final class WaitPhotoRunnable implements Runnable {
method WaitPhotoRunnable (line 705) | private WaitPhotoRunnable(String path, Handler.Callback callback) {
method run (line 710) | @Override
method convertFile (line 750) | public static Queue<FileParcel> convertFile(String[] paths) throws Exc...
class EncodeFileRunnable (line 781) | static class EncodeFileRunnable implements Runnable {
method EncodeFileRunnable (line 788) | public EncodeFileRunnable(String filePath, Queue<FileParcel> queue, ...
method run (line 796) | @Override
method convertFileParcelObjectsToJson (line 831) | static String convertFileParcelObjectsToJson(Collection<FileParcel> co...
class CovertFileThread (line 853) | static class CovertFileThread implements Runnable {
method CovertFileThread (line 858) | private CovertFileThread(JsChannelCallback JsChannelCallback, String...
method run (line 863) | @Override
class JsChannelCallback (line 883) | static class JsChannelCallback {
method JsChannelCallback (line 886) | JsChannelCallback(Handler.Callback callback) {
method create (line 890) | public static JsChannelCallback create(Handler.Callback callback) {
method call (line 894) | void call(String value) {
method newBuilder (line 901) | public static Builder newBuilder(Activity activity, WebView webView) {
class Builder (line 905) | public static final class Builder {
method setAcceptType (line 917) | public Builder setAcceptType(String acceptType) {
method setPermissionInterceptor (line 922) | public Builder setPermissionInterceptor(PermissionInterceptor permis...
method setActivity (line 927) | public Builder setActivity(Activity activity) {
method setUriValueCallback (line 932) | public Builder setUriValueCallback(ValueCallback<Uri> uriValueCallba...
method setUriValueCallbacks (line 939) | public Builder setUriValueCallbacks(ValueCallback<Uri[]> uriValueCal...
method setFileChooserParams (line 947) | public Builder setFileChooserParams(WebChromeClient.FileChooserParam...
method setJsChannelCallback (line 952) | public Builder setJsChannelCallback(Handler.Callback jsChannelCallba...
method setWebView (line 961) | public Builder setWebView(WebView webView) {
method build (line 967) | public FileChooser build() {
FILE: agentweb-filechooser/src/main/java/com/just/agentweb/filechooser/FileCompressor.java
class FileCompressor (line 13) | public class FileCompressor implements Serializable {
method FileCompressor (line 18) | FileCompressor() {
method getInstance (line 21) | public static final FileCompressor getInstance() {
method registerFileCompressEngine (line 33) | public void registerFileCompressEngine(FileCompressEngine valueCallbac...
method unregisterFileCompressEngine (line 37) | public void unregisterFileCompressEngine(FileCompressEngine valueCallb...
method fileCompress (line 41) | void fileCompress(String type, Uri[] uri, ValueCallback<Uri[]> callbac...
type FileCompressEngine (line 49) | public interface FileCompressEngine {
method compressFile (line 50) | void compressFile(String type, Uri[] uri, ValueCallback<Uri[]> callb...
FILE: agentweb-filechooser/src/main/java/com/just/agentweb/filechooser/FileParcel.java
class FileParcel (line 26) | public class FileParcel implements Parcelable {
method FileParcel (line 32) | protected FileParcel(Parcel in) {
method FileParcel (line 38) | public FileParcel(int id, String contentPath, String fileBase64) {
method createFromParcel (line 46) | @Override
method newArray (line 51) | @Override
method getId (line 57) | public int getId() {
method setId (line 61) | public void setId(int id) {
method getContentPath (line 65) | public String getContentPath() {
method setContentPath (line 69) | public void setContentPath(String contentPath) {
method getFileBase64 (line 73) | public String getFileBase64() {
method setFileBase64 (line 77) | public void setFileBase64(String fileBase64) {
method describeContents (line 81) | @Override
method writeToParcel (line 86) | @Override
method toString (line 93) | @Override
FILE: agentweb-filechooser/src/test/java/com/just/agentweb/filechooser/ExampleUnitTest.java
class ExampleUnitTest (line 12) | public class ExampleUnitTest {
method addition_isCorrect (line 13) | @Test
FILE: sample/src/androidTest/java/com/just/agentweb/sample/ExampleInstrumentedTest.java
class ExampleInstrumentedTest (line 17) | @RunWith(AndroidJUnit4.class)
method useAppContext (line 19) | @Test
FILE: sample/src/main/assets/upload_file/event.js
function bindEvent (line 2) | function bindEvent(element, eventName, func) {
function unBindEvent (line 32) | function unBindEvent(element, eventName, func) {
FILE: sample/src/main/java/com/just/agentweb/sample/activity/AutoHidenToolbarActivity.java
class AutoHidenToolbarActivity (line 17) | public class AutoHidenToolbarActivity extends AppCompatActivity implemen...
method onCreate (line 39) | @Override
method initView (line 63) | private void initView() {
method onClick (line 76) | @Override
method onKeyDown (line 102) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/activity/BaseWebActivity.java
class BaseWebActivity (line 33) | public class BaseWebActivity extends AppCompatActivity {
method onCreate (line 43) | @Override
method shouldOverrideUrlLoading (line 94) | @Override
method onPageStarted (line 99) | @Override
method onReceivedTitle (line 106) | @Override
method getUrl (line 115) | public String getUrl() {
method showDialog (line 120) | private void showDialog() {
method onKeyDown (line 148) | @Override
method onPause (line 157) | @Override
method onResume (line 164) | @Override
method onActivityResult (line 170) | @Override
method onDestroy (line 178) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/activity/CommonActivity.java
class CommonActivity (line 47) | public class CommonActivity extends AppCompatActivity {
method onCreate (line 54) | @Override
method openFragment (line 69) | private void openFragment(int key) {
method onActivityResult (line 167) | @Override
method onKeyDown (line 174) | @Override
method onDestroy (line 193) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/activity/ContainerActivity.java
class ContainerActivity (line 15) | public class ContainerActivity extends AppCompatActivity {
method onCreate (line 17) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/activity/EasyWebActivity.java
class EasyWebActivity (line 23) | public class EasyWebActivity extends BaseAgentWebActivity {
method onCreate (line 27) | @Override
method getAgentWebParent (line 50) | @NonNull
method onKeyDown (line 56) | @Override
method getIndicatorColor (line 65) | @Override
method setTitle (line 70) | @Override
method getIndicatorHeight (line 81) | @Override
method getUrl (line 86) | @Nullable
FILE: sample/src/main/java/com/just/agentweb/sample/activity/ExternalActivity.java
class ExternalActivity (line 12) | public class ExternalActivity extends WebActivity {
method onCreate (line 16) | @Override
method getUrl (line 21) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/activity/MainActivity.java
class MainActivity (line 31) | public class MainActivity extends AppCompatActivity {
method onCreate (line 90) | @RequiresApi(api = Build.VERSION_CODES.KITKAT)
method onReady (line 138) | @MainThread
method doClick (line 146) | private void doClick(int position) {
method onDestroy (line 247) | @Override
class MainAdapter (line 253) | public class MainAdapter extends BaseAdapter {
method getCount (line 255) | @Override
method getItem (line 260) | @Override
method getItemId (line 265) | @Override
method getView (line 270) | @Override
class ViewHolder (line 290) | class ViewHolder {
FILE: sample/src/main/java/com/just/agentweb/sample/activity/NativeDownloadActivity.java
class NativeDownloadActivity (line 57) | public class NativeDownloadActivity extends AppCompatActivity {
method onCreate (line 64) | @Override
class NativeDownloadAdapter (line 181) | private class NativeDownloadAdapter extends RecyclerView.Adapter<Nativ...
method onCreateViewHolder (line 182) | @NonNull
method onBindViewHolder (line 189) | @Override
method getItemCount (line 315) | @Override
method byte2FitMemorySize (line 321) | private static String byte2FitMemorySize(final long byteNum) {
class NativeDownloadViewHolder (line 335) | private class NativeDownloadViewHolder extends RecyclerView.ViewHolder {
method NativeDownloadViewHolder (line 341) | public NativeDownloadViewHolder(@NonNull View itemView) {
class DownloadBean (line 351) | public static class DownloadBean extends DownloadTask {
method DownloadBean (line 355) | public DownloadBean(String title, String imageUrl, String url) {
method setDownloadListenerAdapter (line 361) | @Override
method setUrl (line 366) | @Override
method setContext (line 371) | @Override
method setEnableIndicator (line 376) | @Override
method setRetry (line 381) | @Override
method setQuickProgress (line 386) | @Override
method autoOpenIgnoreMD5 (line 391) | @Override
class RoundTransform (line 397) | public static class RoundTransform implements com.squareup.picasso.Tra...
method RoundTransform (line 401) | public RoundTransform(Context context) {
method transform (line 405) | @Override
method key (line 430) | @Override
method createDatasource (line 437) | public void createDatasource() {
method dp2px (line 574) | public static int dp2px(Context context, float dpValue) {
method onDestroy (line 579) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/activity/RemoteWebViewlActivity.java
class RemoteWebViewlActivity (line 20) | public class RemoteWebViewlActivity extends WebActivity {
method onCreate (line 24) | @Override
method sayYes (line 36) | private void sayYes() {
method getUrl (line 42) | @Override
method loadNewUrl (line 56) | @Route("/load/newUrl")
method onDestroy (line 63) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/activity/WebActivity.java
class WebActivity (line 9) | public class WebActivity extends BaseWebActivity {
method getUrl (line 11) | @Override
method onStart (line 16) | @Override
method onResume (line 21) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/api/Api.java
type Api (line 8) | public interface Api {
method onReady (line 10) | void onReady();
FILE: sample/src/main/java/com/just/agentweb/sample/app/App.java
class App (line 16) | public class App extends Application {
method onCreate (line 18) | @Override
method attachBaseContext (line 53) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/base/BaseAgentWebActivity.java
class BaseAgentWebActivity (line 33) | public abstract class BaseAgentWebActivity extends AppCompatActivity {
method onCreate (line 41) | @Override
method setContentView (line 47) | @Override
method setContentView (line 53) | @Override
method buildAgentWeb (line 59) | protected void buildAgentWeb() {
method getErrorLayoutEntity (line 85) | protected @NonNull
method getAgentWeb (line 93) | protected AgentWeb getAgentWeb() {
class ErrorLayoutEntity (line 98) | protected static class ErrorLayoutEntity {
method setLayoutRes (line 102) | public void setLayoutRes(int layoutRes) {
method setReloadId (line 109) | public void setReloadId(int reloadId) {
method onKeyDown (line 117) | @Override
method onPause (line 126) | @Override
method onResume (line 135) | @Override
method onActivityResult (line 143) | @Override
method onDestroy (line 149) | @Override
method getUrl (line 158) | protected
method getAgentWebSettings (line 164) | public @Nullable
method getAgentWebParent (line 169) | protected abstract @NonNull
method getWebChromeClient (line 172) | protected @Nullable
method getIndicatorColor (line 177) | protected @ColorInt
method getIndicatorHeight (line 182) | protected int getIndicatorHeight() {
method getWebViewClient (line 186) | protected @Nullable
method getWebView (line 192) | protected @Nullable
method getWebLayout (line 197) | protected @Nullable
method getPermissionInterceptor (line 202) | protected @Nullable
method getAgentWebUIController (line 207) | public @Nullable
method getOpenOtherAppWay (line 212) | public @Nullable
method getMiddleWareWebChrome (line 217) | protected @NonNull
method setTitle (line 228) | protected void setTitle(WebView view, String title) {
method getMiddleWareWebClient (line 232) | protected @NonNull
FILE: sample/src/main/java/com/just/agentweb/sample/base/BaseAgentWebFragment.java
class BaseAgentWebFragment (line 30) | public abstract class BaseAgentWebFragment extends Fragment {
method onViewCreated (line 38) | @Override
method setTitle (line 64) | protected void setTitle(WebView view, String title) {
method getErrorLayoutEntity (line 68) | protected @NonNull
method getAgentWebUIController (line 76) | protected @Nullable
class ErrorLayoutEntity (line 81) | protected static class ErrorLayoutEntity {
method setLayoutRes (line 85) | public void setLayoutRes(int layoutRes) {
method setReloadId (line 92) | public void setReloadId(int reloadId) {
method onPause (line 100) | @Override
method onResume (line 109) | @Override
method onActivityResult (line 118) | @Override
method getUrl (line 124) | protected @Nullable
method onDestroy (line 129) | @Override
method getAgentWebSettings (line 137) | protected @Nullable
method getWebChromeClient (line 142) | protected @Nullable
method getAgentWebParent (line 147) | protected abstract @NonNull
method getIndicatorColor (line 150) | protected @ColorInt
method getIndicatorHeight (line 155) | protected int getIndicatorHeight() {
method getWebViewClient (line 159) | protected @Nullable
method getWebView (line 164) | protected @Nullable
method getWebLayout (line 169) | protected @Nullable
method getPermissionInterceptor (line 174) | protected @Nullable
method getMiddleWareWebChrome (line 179) | protected @NonNull
method getMiddleWareWebClient (line 190) | protected @NonNull
FILE: sample/src/main/java/com/just/agentweb/sample/base/FragmentKeyDown.java
type FragmentKeyDown (line 10) | public interface FragmentKeyDown {
method onFragmentKeyDown (line 12) | boolean onFragmentKeyDown(int keyCode, KeyEvent event);
FILE: sample/src/main/java/com/just/agentweb/sample/behavior/BottomNavigationViewBehavior.java
class BottomNavigationViewBehavior (line 33) | public class BottomNavigationViewBehavior extends CoordinatorLayout.Beha...
method BottomNavigationViewBehavior (line 34) | public BottomNavigationViewBehavior() {
method BottomNavigationViewBehavior (line 37) | public BottomNavigationViewBehavior(Context context, AttributeSet attr...
method onLayoutChild (line 41) | @Override
method layoutDependsOn (line 48) | @Override
method onDependentViewChanged (line 53) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/client/MiddlewareChromeClient.java
class MiddlewareChromeClient (line 13) | public class MiddlewareChromeClient extends MiddlewareWebChromeBase {
method MiddlewareChromeClient (line 14) | public MiddlewareChromeClient() {
method onJsAlert (line 16) | @Override
method onProgressChanged (line 22) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/client/MiddlewareWebViewClient.java
class MiddlewareWebViewClient (line 34) | public class MiddlewareWebViewClient extends MiddlewareWebClientBase {
method MiddlewareWebViewClient (line 36) | public MiddlewareWebViewClient() {
method shouldOverrideUrlLoading (line 41) | @Override
method shouldOverrideUrlLoading (line 48) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/client/SonicWebViewClient.java
class SonicWebViewClient (line 15) | public class SonicWebViewClient extends MiddlewareWebClientBase {
method SonicWebViewClient (line 19) | public SonicWebViewClient(SonicSession sonicSession) {
method onPageFinished (line 23) | @Override
method shouldInterceptRequest (line 31) | @TargetApi(21)
method shouldInterceptRequest (line 36) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/common/AndroidInterface.java
class AndroidInterface (line 17) | public class AndroidInterface {
method AndroidInterface (line 23) | public AndroidInterface(AgentWeb agent, Context context) {
method callAndroid (line 30) | @JavascriptInterface
FILE: sample/src/main/java/com/just/agentweb/sample/common/CommonWebChromeClient.java
class CommonWebChromeClient (line 13) | public class CommonWebChromeClient extends WebChromeClient {
method onProgressChanged (line 14) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/common/CustomSettings.java
class CustomSettings (line 18) | public class CustomSettings extends AbsAgentWebSettings {
method CustomSettings (line 20) | public CustomSettings(Activity activity) {
method bindAgentWebSupport (line 28) | @Override
method toSetting (line 34) | @Override
method setDownloader (line 53) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/common/FragmentKeyDown.java
type FragmentKeyDown (line 10) | public interface FragmentKeyDown {
method onFragmentKeyDown (line 12) | boolean onFragmentKeyDown(int keyCode, KeyEvent event);
FILE: sample/src/main/java/com/just/agentweb/sample/common/GuideItemEntity.java
class GuideItemEntity (line 24) | public class GuideItemEntity {
method GuideItemEntity (line 30) | public GuideItemEntity(String guideTitle, int guideDictionary) {
method getGuideTitle (line 36) | public String getGuideTitle() {
method setGuideTitle (line 40) | public void setGuideTitle(String guideTitle) {
method getGuideDictionary (line 44) | public int getGuideDictionary() {
method setGuideDictionary (line 48) | public void setGuideDictionary(int guideDictionary) {
FILE: sample/src/main/java/com/just/agentweb/sample/common/UIController.java
class UIController (line 18) | public class UIController extends AgentWebUIControllerImplBase {
method UIController (line 21) | public UIController(Activity activity){
method onShowMessage (line 25) | @Override
method onSelectItemsPrompt (line 31) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/fragment/AgentWebFragment.java
class AgentWebFragment (line 82) | public class AgentWebFragment extends Fragment implements FragmentKeyDow...
method getInstance (line 100) | public static AgentWebFragment getInstance(Bundle bundle) {
method onCreateView (line 111) | @Nullable
method onViewCreated (line 118) | @Override
method intercept (line 177) | @Override
method getSettings (line 188) | public IAgentWebSettings getSettings() {
method getUrl (line 255) | public String getUrl() {
method onProgressChanged (line 267) | @Override
method onReceivedTitle (line 273) | @Override
method onReceivedError (line 292) | @Override
method shouldOverrideUrlLoading (line 297) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
method shouldInterceptRequest (line 303) | @Nullable
method shouldOverrideUrlLoading (line 310) | @Override
method onPageStarted (line 324) | @Override
method onPageFinished (line 336) | @Override
method onReceivedHttpError (line 355) | @Override
method onReceivedSslError (line 362) | @Override
method onReceivedError (line 368) | @Override
method onActivityResult (line 377) | @Override
method initView (line 390) | protected void initView(View view) {
method pageNavigator (line 439) | private void pageNavigator(int tag) {
method onClick (line 446) | @Override
method openBrowser (line 479) | private void openBrowser(String targetUrl) {
method showPoPup (line 497) | private void showPoPup(View view) {
method onMenuItemClick (line 510) | @SuppressLint("NonConstantResourceId")
method loadErrorWebSite (line 559) | private void loadErrorWebSite() {
method toCleanWebCache (line 568) | private void toCleanWebCache() {
method toCopy (line 588) | private void toCopy(Context context, String text) {
method onResume (line 596) | @Override
method onPause (line 602) | @Override
method onFragmentKeyDown (line 609) | @Override
method onDestroyView (line 617) | @Override
method getMiddlewareWebClient (line 632) | protected MiddlewareWebClientBase getMiddlewareWebClient() {
method getMiddlewareWebChrome (line 670) | protected MiddlewareWebChromeBase getMiddlewareWebChrome() {
method compressFile (line 688) | @Override
method byte2FitMemorySize (line 735) | private static String byte2FitMemorySize(final long byteNum) {
FILE: sample/src/main/java/com/just/agentweb/sample/fragment/BounceWebFragment.java
class BounceWebFragment (line 24) | public class BounceWebFragment extends AgentWebFragment {
method getInstance (line 26) | public static BounceWebFragment getInstance(Bundle bundle) {
method getUrl (line 35) | @Override
method onViewCreated (line 40) | @Override
method getWebLayout (line 63) | protected IWebLayout getWebLayout() {
method addBGChild (line 67) | protected void addBGChild(FrameLayout frameLayout) {
FILE: sample/src/main/java/com/just/agentweb/sample/fragment/CustomIndicatorFragment.java
class CustomIndicatorFragment (line 19) | public class CustomIndicatorFragment extends AgentWebFragment {
method getInstance (line 20) | public static CustomIndicatorFragment getInstance(Bundle bundle) {
method onViewCreated (line 28) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/fragment/CustomSettingsFragment.java
class CustomSettingsFragment (line 13) | public class CustomSettingsFragment extends AgentWebFragment {
method getInstance (line 15) | public static AgentWebFragment getInstance(Bundle bundle) {
method getSettings (line 25) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/fragment/CustomWebViewFragment.java
class CustomWebViewFragment (line 24) | public class CustomWebViewFragment extends AgentWebFragment {
method getInstance (line 30) | public static final CustomWebViewFragment getInstance(Bundle bundle) {
method onCreateView (line 39) | @Nullable
method onViewCreated (line 45) | @Override
method updateMarkdownView (line 110) | private void updateMarkdownView() {
FILE: sample/src/main/java/com/just/agentweb/sample/fragment/EasyWebFragment.java
class EasyWebFragment (line 22) | public class EasyWebFragment extends BaseAgentWebFragment {
method getInstance (line 32) | public static EasyWebFragment getInstance(Bundle bundle) {
method onCreateView (line 41) | @Nullable
method getAgentWebParent (line 47) | @NonNull
method onViewCreated (line 53) | @Override
method initView (line 60) | protected void initView(View view) {
method pageNavigator (line 72) | private void pageNavigator(int tag) {
method onClick (line 79) | @Override
method setTitle (line 94) | @Override
method getUrl (line 105) | @Nullable
FILE: sample/src/main/java/com/just/agentweb/sample/fragment/JsAgentWebFragment.java
class JsAgentWebFragment (line 24) | public class JsAgentWebFragment extends AgentWebFragment {
method getInstance (line 26) | public static final JsAgentWebFragment getInstance(Bundle bundle) {
method onCreateView (line 37) | @Nullable
method onViewCreated (line 43) | @Override
method onClick (line 65) | @RequiresApi(api = Build.VERSION_CODES.KITKAT)
method getJson (line 97) | private String getJson(){
FILE: sample/src/main/java/com/just/agentweb/sample/fragment/JsbridgeWebFragment.java
class JsbridgeWebFragment (line 28) | public class JsbridgeWebFragment extends AgentWebFragment {
method getInstance (line 30) | public static JsbridgeWebFragment getInstance(Bundle bundle) {
method getUrl (line 42) | @Override
method onViewCreated (line 47) | @Override
method getWebViewClient (line 92) | private WebViewClient getWebViewClient() {
class Location (line 128) | static class Location {
class User (line 132) | static class User {
FILE: sample/src/main/java/com/just/agentweb/sample/fragment/SmartRefreshWebFragment.java
class SmartRefreshWebFragment (line 21) | public class SmartRefreshWebFragment extends BounceWebFragment {
method getInstance (line 23) | public static SmartRefreshWebFragment getInstance(Bundle bundle) {
method getUrl (line 35) | @Override
method onViewCreated (line 41) | @Override
method getWebLayout (line 67) | @Override
method addBGChild (line 73) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/fragment/VasSonicFragment.java
class VasSonicFragment (line 21) | public class VasSonicFragment extends AgentWebFragment {
method create (line 23) | public static VasSonicFragment create(Bundle bundle){
method onViewCreated (line 33) | @Override
method getMiddlewareWebClient (line 50) | @Override
method getUrl (line 56) | @Override
method onDestroyView (line 61) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/provider/ServiceProvider.java
class ServiceProvider (line 10) | public class ServiceProvider extends ServiceContentProvider {
FILE: sample/src/main/java/com/just/agentweb/sample/provider/WebServiceProvider.java
class WebServiceProvider (line 10) | public class WebServiceProvider extends ServiceContentProvider {
FILE: sample/src/main/java/com/just/agentweb/sample/service/WebService.java
class WebService (line 16) | public class WebService extends Service {
method onCreate (line 20) | @Override
method onBind (line 31) | @Nullable
FILE: sample/src/main/java/com/just/agentweb/sample/sonic/DefaultSonicRuntimeImpl.java
class DefaultSonicRuntimeImpl (line 37) | public class DefaultSonicRuntimeImpl extends SonicRuntime {
method DefaultSonicRuntimeImpl (line 39) | public DefaultSonicRuntimeImpl(Context context) {
method getUserAgent (line 47) | @Override
method getCurrentUserAccount (line 56) | @Override
method getCookie (line 61) | @Override
method log (line 67) | @Override
method createWebResourceResponse (line 81) | @Override
method showToast (line 90) | @Override
method notifyError (line 95) | @Override
method isSonicUrl (line 100) | @Override
method setCookie (line 105) | @Override
method isNetworkValid (line 117) | @Override
method postTaskToThread (line 122) | @Override
method getSonicCacheDir (line 128) | @Override
method getHostDirectAddress (line 141) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/sonic/SonicImpl.java
class SonicImpl (line 16) | public class SonicImpl {
method SonicImpl (line 22) | public SonicImpl(String url , Context context){
method onCreateSession (line 30) | public void onCreateSession() {
method getSonicSessionClient (line 45) | public SonicSessionClientImpl getSonicSessionClient(){
method createSonicClientMiddleWare (line 53) | public MiddlewareWebClientBase createSonicClientMiddleWare(){
method bindAgentWeb (line 57) | public void bindAgentWeb(AgentWeb agentWeb){
method destrory (line 66) | public void destrory(){
FILE: sample/src/main/java/com/just/agentweb/sample/sonic/SonicJavaScriptInterface.java
class SonicJavaScriptInterface (line 31) | public class SonicJavaScriptInterface {
method SonicJavaScriptInterface (line 41) | public SonicJavaScriptInterface(SonicSessionClientImpl sessionClient, ...
method getDiffData (line 46) | @JavascriptInterface
method getDiffData2 (line 52) | @JavascriptInterface
method getPerformance (line 76) | @JavascriptInterface
method toJsString (line 98) | private static String toJsString(String value) {
FILE: sample/src/main/java/com/just/agentweb/sample/sonic/SonicSessionClientImpl.java
class SonicSessionClientImpl (line 28) | public class SonicSessionClientImpl extends SonicSessionClient {
method bindWebView (line 32) | public void bindWebView(AgentWeb agentWeb) {
method getWebView (line 36) | public WebView getWebView() {
method loadUrl (line 40) | @Override
method loadDataWithBaseUrl (line 46) | @Override
method loadDataWithBaseUrlAndHeader (line 53) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/sonic/SonicWebViewClient.java
class SonicWebViewClient (line 15) | public class SonicWebViewClient extends MiddlewareWebClientBase {
method SonicWebViewClient (line 19) | public SonicWebViewClient(SonicSession sonicSession) {
method onPageFinished (line 23) | @Override
method shouldInterceptRequest (line 31) | @TargetApi(21)
method shouldInterceptRequest (line 37) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/utils/FileUtils.java
class FileUtils (line 8) | public class FileUtils {
method getExtensionByFilePath (line 10) | public static String getExtensionByFilePath(String filePath){
FILE: sample/src/main/java/com/just/agentweb/sample/utils/ProcessUtils.java
class ProcessUtils (line 18) | public class ProcessUtils {
method getCurrentProcessName (line 20) | public static String getCurrentProcessName(Context context) {
method getCurrentProcessNameByFile (line 29) | private static String getCurrentProcessNameByFile() {
method getCurrentProcessNameByAms (line 42) | private static String getCurrentProcessNameByAms(Context context) {
method getCurrentProcessNameByReflect (line 58) | private static String getCurrentProcessNameByReflect(Context context) {
FILE: sample/src/main/java/com/just/agentweb/sample/utils/WebCompat.java
class WebCompat (line 28) | public class WebCompat {
method setDataDirectorySuffix (line 36) | public static void setDataDirectorySuffix(Context context) {
method tryLockOrRecreateFile (line 79) | @TargetApi(Build.VERSION_CODES.P)
method createFile (line 98) | private static void createFile(File file, boolean deleted) {
method getCurrentProcessName (line 109) | private static String getCurrentProcessName(Context context) {
method getCurrentProcessNameByFile (line 118) | private static String getCurrentProcessNameByFile() {
method getCurrentProcessNameByAms (line 131) | private static String getCurrentProcessNameByAms(Context context) {
method getCurrentProcessNameByReflect (line 147) | private static String getCurrentProcessNameByReflect(Context context) {
method isHuawei (line 181) | private static boolean isHuawei() {
method getRomInfo (line 190) | private static RomInfo getRomInfo() {
method isRightRom (line 212) | private static boolean isRightRom(final String brand, final String man...
method getManufacturer (line 221) | private static String getManufacturer() {
method getBrand (line 231) | private static String getBrand() {
method getRomVersion (line 241) | private static String getRomVersion(final String propertyName) {
method getSystemProperty (line 260) | private static String getSystemProperty(final String name) {
method getSystemPropertyByShell (line 271) | private static String getSystemPropertyByShell(final String propName) {
method getSystemPropertyByStream (line 292) | private static String getSystemPropertyByStream(final String key) {
method getSystemPropertyByReflect (line 304) | private static String getSystemPropertyByReflect(String key) {
class RomInfo (line 314) | private static class RomInfo {
method getName (line 318) | public String getName() {
method getVersion (line 322) | public String getVersion() {
method toString (line 326) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/widget/CommonIndicator.java
class CommonIndicator (line 16) | public class CommonIndicator extends BaseIndicatorView {
method CommonIndicator (line 17) | public CommonIndicator(Context context) {
method CommonIndicator (line 21) | public CommonIndicator(Context context, @Nullable AttributeSet attrs) {
method CommonIndicator (line 25) | public CommonIndicator(Context context, @Nullable AttributeSet attrs, ...
method show (line 30) | @Override
method hide (line 35) | @Override
method offerLayoutParams (line 41) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/widget/CoolIndicatorLayout.java
class CoolIndicatorLayout (line 37) | public class CoolIndicatorLayout extends BaseIndicatorView {
method CoolIndicatorLayout (line 44) | public CoolIndicatorLayout(Context context) {
method CoolIndicatorLayout (line 48) | public CoolIndicatorLayout(Context context, @Nullable AttributeSet att...
method CoolIndicatorLayout (line 52) | public CoolIndicatorLayout(Context context, @Nullable AttributeSet att...
method show (line 65) | @Override
method setProgress (line 71) | @Override
method hide (line 75) | @Override
method offerLayoutParams (line 80) | @Override
FILE: sample/src/main/java/com/just/agentweb/sample/widget/SmartRefreshWebLayout.java
class SmartRefreshWebLayout (line 18) | public class SmartRefreshWebLayout implements IWebLayout {
method SmartRefreshWebLayout (line 23) | public SmartRefreshWebLayout(Activity activity){
method getLayout (line 32) | @NonNull
method getWebView (line 38) | @Nullable
FILE: sample/src/main/java/com/just/agentweb/sample/widget/WebLayout.java
class WebLayout (line 19) | public class WebLayout implements IWebLayout {
method WebLayout (line 25) | public WebLayout(Activity activity) {
method getLayout (line 32) | @NonNull
method getWebView (line 38) | @Nullable
FILE: sample/src/test/java/com/just/agentweb/sample/ExampleUnitTest.java
class ExampleUnitTest (line 12) | public class ExampleUnitTest {
method addition_isCorrect (line 13) | @Test
Condensed preview — 202 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (697K chars).
[
{
"path": ".github/FUNDING.yml",
"chars": 436,
"preview": "# These are supported funding model platforms\n\ngithub: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [u"
},
{
"path": ".gitignore",
"chars": 704,
"preview": "*.iml\n.gradle\n.idea\n/local.properties\n.DS_Store\n/build\n/captures\n.externalNativeBuild\n\n# Built application files\n# *.apk"
},
{
"path": "LICENSE",
"chars": 11360,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 2607,
"preview": "\n<div style=\"display: flex;flex-direction: row;justify-content: center\" width=\"100%\">\n <img src=\"./img/logo.png\"></"
},
{
"path": "agentweb-core/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "agentweb-core/build.gradle",
"chars": 1779,
"preview": "apply plugin: 'com.android.library'\napply plugin: 'maven-publish'\n\nandroid {\n compileSdk COMPILE_SDK_VERSION.toIntege"
},
{
"path": "agentweb-core/proguard-rules.pro",
"chars": 1019,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
},
{
"path": "agentweb-core/src/androidTest/java/com/just/agentweb/ExampleInstrumentedTest.java",
"chars": 752,
"preview": "package com.just.agentweb;\n\nimport android.content.Context;\nimport androidx.test.platform.app.InstrumentationRegistry;\ni"
},
{
"path": "agentweb-core/src/main/AndroidManifest.xml",
"chars": 532,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n <application>\n <provider\n a"
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/AbsAgentWebSettings.java",
"chars": 6036,
"preview": "/*\r\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\r\n *\r\n * Licensed under the Apache License, Version 2."
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/AbsAgentWebUIController.java",
"chars": 5410,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/Action.java",
"chars": 3543,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/AgentActionFragment.java",
"chars": 8834,
"preview": "\n/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 "
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/AgentWeb.java",
"chars": 28990,
"preview": "/*\r\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\r\n *\r\n * Licensed under the Apache License, Version 2."
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/AgentWebCompat.java",
"chars": 3347,
"preview": "package com.just.agentweb;\n\nimport android.annotation.TargetApi;\nimport android.content.Context;\nimport android.os.Build"
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/AgentWebConfig.java",
"chars": 7177,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/AgentWebFileProvider.java",
"chars": 1062,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/AgentWebJsInterfaceCompat.java",
"chars": 2156,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/AgentWebPermissions.java",
"chars": 1967,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/AgentWebSettingsImpl.java",
"chars": 1937,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/AgentWebUIControllerImplBase.java",
"chars": 3620,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/AgentWebUtils.java",
"chars": 29912,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/AgentWebView.java",
"chars": 19770,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/BaseIndicatorSpec.java",
"chars": 878,
"preview": "/*\r\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\r\n *\r\n * Licensed under the Apache License, Version 2."
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/BaseIndicatorView.java",
"chars": 1524,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/BaseJsAccessEntrace.java",
"chars": 3048,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/DefaultChromeClient.java",
"chars": 14009,
"preview": "/*\r\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\r\n *\r\n * Licensed under the Apache License, Version 2."
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/DefaultDesignUIController.java",
"chars": 7531,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/DefaultDownloadImpl.java",
"chars": 7406,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/DefaultUIController.java",
"chars": 14411,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/DefaultWebClient.java",
"chars": 19706,
"preview": "/*\r\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\r\n *\r\n * Licensed under the Apache License, Version 2."
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/DefaultWebCreator.java",
"chars": 8700,
"preview": "/*\r\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\r\n *\r\n * Licensed under the Apache License, Version 2."
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/DefaultWebLifeCycleImpl.java",
"chars": 1628,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/EventHandlerImpl.java",
"chars": 1764,
"preview": "/*\r\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\r\n *\r\n * Licensed under the Apache License, Version 2."
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/EventInterceptor.java",
"chars": 783,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/HookManager.java",
"chars": 1000,
"preview": "/*\r\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\r\n *\r\n * Licensed under the Apache License, Version 2."
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/HttpHeaders.java",
"chars": 3675,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/IAgentWebSettings.java",
"chars": 925,
"preview": "/*\r\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\r\n *\r\n * Licensed under the Apache License, Version 2."
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/IEventHandler.java",
"chars": 876,
"preview": "/*\r\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\r\n *\r\n * Licensed under the Apache License, Version 2."
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/IUrlLoader.java",
"chars": 1223,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/IVideo.java",
"chars": 967,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/IWebIndicator.java",
"chars": 818,
"preview": "/*\r\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\r\n *\r\n * Licensed under the Apache License, Version 2."
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/IWebLayout.java",
"chars": 1207,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/IndicatorController.java",
"chars": 1009,
"preview": "/*\r\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\r\n *\r\n * Licensed under the Apache License, Version 2."
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/IndicatorHandler.java",
"chars": 2022,
"preview": "/*\r\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\r\n *\r\n * Licensed under the Apache License, Version 2."
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/JsAccessEntrace.java",
"chars": 913,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/JsAccessEntraceImpl.java",
"chars": 1788,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/JsBaseInterfaceHolder.java",
"chars": 2339,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/JsCallJava.java",
"chars": 11454,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/JsCallback.java",
"chars": 3661,
"preview": "\n\n/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0"
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/JsInterfaceHolder.java",
"chars": 947,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/JsInterfaceHolderImpl.java",
"chars": 2948,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/JsInterfaceObjectException.java",
"chars": 865,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/LayoutParamsOffer.java",
"chars": 865,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/LogUtils.java",
"chars": 1666,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/LollipopFixedWebView.java",
"chars": 1624,
"preview": "package com.just.agentweb;\n\nimport android.annotation.TargetApi;\nimport android.content.Context;\nimport android.content."
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/MiddlewareWebChromeBase.java",
"chars": 1548,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/MiddlewareWebClientBase.java",
"chars": 1742,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/NestedScrollAgentWebView.java",
"chars": 5171,
"preview": "/*\n * Copyright (C) LeonDevLifeLog(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Versio"
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/PermissionInterceptor.java",
"chars": 821,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/ProcessUtils.java",
"chars": 2827,
"preview": "package com.just.agentweb;\n\nimport android.app.ActivityManager;\nimport android.app.Application;\nimport android.content.C"
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/Provider.java",
"chars": 773,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/QuickCallJs.java",
"chars": 1090,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/RomUtils.java",
"chars": 5743,
"preview": "package com.just.agentweb;\n\n\nimport android.annotation.SuppressLint;\nimport android.os.Build;\nimport android.os.Environm"
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/UrlCommonException.java",
"chars": 908,
"preview": "/*\r\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\r\n *\r\n * Licensed under the Apache License, Version 2."
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/UrlLoaderImpl.java",
"chars": 3906,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/VideoImpl.java",
"chars": 4973,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/WebChromeClient.java",
"chars": 190,
"preview": "package com.just.agentweb;\n\n/**\n * @author cenxiaozhong\n * @date 2019/4/13\n * @since 1.0.0\n */\npublic class WebChromeCli"
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/WebChromeClientDelegate.java",
"chars": 12142,
"preview": "/*\r\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\r\n *\r\n * Licensed under the Apache License, Version 2."
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/WebCreator.java",
"chars": 977,
"preview": "/*\r\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\r\n *\r\n * Licensed under the Apache License, Version 2."
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/WebIndicator.java",
"chars": 10758,
"preview": "/*\r\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\r\n *\r\n * Licensed under the Apache License, Version 2."
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/WebLifeCycle.java",
"chars": 822,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/WebListenerManager.java",
"chars": 1183,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/WebParentLayout.java",
"chars": 5215,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/WebSecurityCheckLogic.java",
"chars": 936,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/WebSecurityController.java",
"chars": 757,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/WebSecurityControllerImpl.java",
"chars": 1559,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/WebSecurityLogicImpl.java",
"chars": 2171,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/WebViewClient.java",
"chars": 188,
"preview": "package com.just.agentweb;\n\n/**\n * @author cenxiaozhong\n * @date 2019/4/13\n * @since 1.0.0\n */\npublic class WebViewClien"
},
{
"path": "agentweb-core/src/main/java/com/just/agentweb/WebViewClientDelegate.java",
"chars": 8072,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-core/src/main/res/layout/agentweb_error_page.xml",
"chars": 534,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n "
},
{
"path": "agentweb-core/src/main/res/values/colors.xml",
"chars": 190,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <color name=\"black\">#000000</color>\n <color name=\"white\">#ffff"
},
{
"path": "agentweb-core/src/main/res/values/ids.xml",
"chars": 300,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <item name=\"web_parent_layout_id\" type=\"id\"></item>\n <item nam"
},
{
"path": "agentweb-core/src/main/res/values/strings.xml",
"chars": 2123,
"preview": "<resources>\n <string name=\"agentweb_download_task_has_been_exist\">The task already exists, do not repeat click to dow"
},
{
"path": "agentweb-core/src/main/res/values/style.xml",
"chars": 318,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<resources xmlns:tools=\"http://schemas.android.com/tools\">\n\n <style name=\"act"
},
{
"path": "agentweb-core/src/main/res/values-zh/strings.xml",
"chars": 1735,
"preview": "<resources>\n <string name=\"agentweb_download_task_has_been_exist\">该任务已经存在 , 请勿重复点击下载!</string>\n <string name=\"agen"
},
{
"path": "agentweb-core/src/main/res/xml/web_files_public.xml",
"chars": 142,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<paths>\n\n <external-cache-path\n name=\"agenweb_files\"\n path=\"agen"
},
{
"path": "agentweb-core/src/test/java/com/just/agentweb/ExampleUnitTest.java",
"chars": 395,
"preview": "package com.just.agentweb;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, w"
},
{
"path": "agentweb-filechooser/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "agentweb-filechooser/build.gradle",
"chars": 1608,
"preview": "apply plugin: 'com.android.library'\napply plugin: 'maven-publish'\n\nandroid {\n compileSdk COMPILE_SDK_VERSION.toIntege"
},
{
"path": "agentweb-filechooser/proguard-rules.pro",
"chars": 825,
"preview": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguar"
},
{
"path": "agentweb-filechooser/src/androidTest/java/com/just/agentweb/filechooser/ExampleInstrumentedTest.java",
"chars": 774,
"preview": "package com.just.agentweb.filechooser;\n\nimport android.content.Context;\nimport androidx.test.platform.app.Instrumentatio"
},
{
"path": "agentweb-filechooser/src/main/AndroidManifest.xml",
"chars": 547,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n <!-- To handle the reselection within the app"
},
{
"path": "agentweb-filechooser/src/main/java/com/just/agentweb/filechooser/FileChooser.java",
"chars": 32707,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-filechooser/src/main/java/com/just/agentweb/filechooser/FileCompressor.java",
"chars": 1364,
"preview": "package com.just.agentweb.filechooser;\n\nimport android.net.Uri;\nimport android.webkit.ValueCallback;\n\nimport java.io.Ser"
},
{
"path": "agentweb-filechooser/src/main/java/com/just/agentweb/filechooser/FileParcel.java",
"chars": 2547,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "agentweb-filechooser/src/main/res/values/strings.xml",
"chars": 25,
"preview": "<resources>\n</resources>\n"
},
{
"path": "agentweb-filechooser/src/test/java/com/just/agentweb/filechooser/ExampleUnitTest.java",
"chars": 407,
"preview": "package com.just.agentweb.filechooser;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local "
},
{
"path": "build.gradle",
"chars": 1022,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n r"
},
{
"path": "gradle/wrapper/gradle-wrapper.properties",
"chars": 200,
"preview": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributi"
},
{
"path": "gradle.properties",
"chars": 1185,
"preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
},
{
"path": "gradlew",
"chars": 4975,
"preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n## Gradle onStar"
},
{
"path": "gradlew.bat",
"chars": 2404,
"preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
},
{
"path": "jitpack.yml",
"chars": 18,
"preview": "jdk:\n - openjdk17"
},
{
"path": "releasenote.md",
"chars": 1888,
"preview": "* v_5.0.0 更新\n\t* ActionActivity 重构, 使用Fragment 替代 Activity,解决多进程使用问题\n\t* 新增 WebRTC Sample\n\t* 新增 FileCompressor ,允许选择文件后对文件"
},
{
"path": "sample/.gitignore",
"chars": 14,
"preview": "/build\nmap.txt"
},
{
"path": "sample/build.gradle",
"chars": 3434,
"preview": "\napply plugin: 'com.android.application'\n\nandroid {\n compileSdk COMPILE_SDK_VERSION.toInteger()\n buildToolsVersion"
},
{
"path": "sample/proguard-rules.pro",
"chars": 3572,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
},
{
"path": "sample/src/androidTest/java/com/just/agentweb/sample/ExampleInstrumentedTest.java",
"chars": 763,
"preview": "package com.just.agentweb.sample;\n\nimport android.content.Context;\nimport androidx.test.platform.app.InstrumentationRegi"
},
{
"path": "sample/src/main/AndroidManifest.xml",
"chars": 4277,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:to"
},
{
"path": "sample/src/main/assets/js_interaction/button.css",
"chars": 1695,
"preview": "\n.button {\n color: #666;\n background-color: #EEE;\n border-color: #EEE;\n font-weight: 300;\n font-size: 16px;\n font-"
},
{
"path": "sample/src/main/assets/js_interaction/hello.html",
"chars": 2041,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n <meta http-equ"
},
{
"path": "sample/src/main/assets/jsbridge/demo.html",
"chars": 3469,
"preview": "<html>\n <head>\n <meta content=\"text/html; charset=utf-8\" http-equiv=\"content-type\">\n <title>\n "
},
{
"path": "sample/src/main/assets/sms/sms.html",
"chars": 1426,
"preview": "<html>\n<head>\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n <meta content=\"text/html\" http"
},
{
"path": "sample/src/main/assets/upload_file/event.js",
"chars": 1397,
"preview": "// ---------- 事件绑定与删除绑定 ---------- //\nfunction bindEvent(element, eventName, func) {\n var events = element['the'+even"
},
{
"path": "sample/src/main/assets/upload_file/jsuploadfile.html",
"chars": 4594,
"preview": "<!DOCTYPE html>\n<html style=\"width: 100%;height: 100%;margin: 0;padding: 0\">\n\n<head>\n <meta charset=\"UTF-8\">\n <met"
},
{
"path": "sample/src/main/assets/upload_file/upload.css",
"chars": 495,
"preview": ".file {\n position: relative;\n display: inline-block;\n background: #D0EEFF;\n border: 1px solid #99D3F5;\n b"
},
{
"path": "sample/src/main/assets/upload_file/uploadfile.html",
"chars": 6112,
"preview": "<!DOCTYPE html>\n<html style=\"width: 100%;height: 100%;margin: 0;padding: 0\">\n\n<head>\n <meta charset=\"UTF-8\">\n <met"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/activity/AutoHidenToolbarActivity.java",
"chars": 3425,
"preview": "package com.just.agentweb.sample.activity;\n\nimport android.os.Bundle;\nimport com.google.android.material.appbar.AppBarLa"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/activity/BaseWebActivity.java",
"chars": 5842,
"preview": "package com.just.agentweb.sample.activity;\n\nimport android.content.DialogInterface;\nimport android.content.Intent;\nimpor"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/activity/CommonActivity.java",
"chars": 9593,
"preview": "package com.just.agentweb.sample.activity;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport androidx.ann"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/activity/ContainerActivity.java",
"chars": 884,
"preview": "package com.just.agentweb.sample.activity;\n\nimport android.os.Bundle;\nimport androidx.annotation.Nullable;\nimport androi"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/activity/EasyWebActivity.java",
"chars": 2554,
"preview": "package com.just.agentweb.sample.activity;\n\nimport android.graphics.Color;\nimport android.os.Bundle;\nimport androidx.ann"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/activity/ExternalActivity.java",
"chars": 595,
"preview": "package com.just.agentweb.sample.activity;\n\nimport android.os.Bundle;\nimport androidx.annotation.Nullable;\nimport androi"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/activity/MainActivity.java",
"chars": 14173,
"preview": "package com.just.agentweb.sample.activity;\n\nimport android.content.Intent;\nimport android.graphics.Color;\nimport android"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/activity/NativeDownloadActivity.java",
"chars": 32571,
"preview": "package com.just.agentweb.sample.activity;\n\nimport android.content.Context;\nimport android.graphics.Bitmap;\nimport andro"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/activity/RemoteWebViewlActivity.java",
"chars": 2008,
"preview": "package com.just.agentweb.sample.activity;\n\nimport android.os.Bundle;\nimport androidx.annotation.Nullable;\nimport androi"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/activity/WebActivity.java",
"chars": 1416,
"preview": "package com.just.agentweb.sample.activity;\n\n/**\n * Created by cenxiaozhong on 2017/5/22.\n * <p>\n *\n */\n\npublic class We"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/api/Api.java",
"chars": 151,
"preview": "package com.just.agentweb.sample.api;\n\n/**\n * @author xiaozhongcen\n * @date 20-8-18\n * @since 1.0.0\n */\npublic interface"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/app/App.java",
"chars": 1679,
"preview": "package com.just.agentweb.sample.app;\n\nimport android.app.Application;\nimport android.content.Context;\nimport android.co"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/base/BaseAgentWebActivity.java",
"chars": 6445,
"preview": "package com.just.agentweb.sample.base;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport androidx.annotat"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/base/BaseAgentWebFragment.java",
"chars": 5713,
"preview": "package com.just.agentweb.sample.base;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport androidx.annotat"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/base/FragmentKeyDown.java",
"chars": 257,
"preview": "package com.just.agentweb.sample.base;\n\nimport android.view.KeyEvent;\n\n/**\n * Created by cenxiaozhong\n * source code ht"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/behavior/BottomNavigationViewBehavior.java",
"chars": 2317,
"preview": "/*\n * Copyright (C) LeonDevLifeLog(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Versio"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/client/MiddlewareChromeClient.java",
"chars": 826,
"preview": "package com.just.agentweb.sample.client;\n\nimport android.util.Log;\nimport android.webkit.JsResult;\nimport android.webkit"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/client/MiddlewareWebViewClient.java",
"chars": 1675,
"preview": "package com.just.agentweb.sample.client;\n\nimport android.util.Log;\nimport android.webkit.WebResourceRequest;\nimport andr"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/client/SonicWebViewClient.java",
"chars": 1259,
"preview": "package com.just.agentweb.sample.client;\n\nimport android.annotation.TargetApi;\nimport android.webkit.WebResourceRequest;"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/common/AndroidInterface.java",
"chars": 1091,
"preview": "package com.just.agentweb.sample.common;\n\nimport android.content.Context;\nimport android.os.Handler;\nimport android.os.L"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/common/CommonWebChromeClient.java",
"chars": 487,
"preview": "package com.just.agentweb.sample.common;\n\nimport android.util.Log;\nimport android.webkit.WebView;\n\nimport com.just.agent"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/common/CustomSettings.java",
"chars": 2189,
"preview": "package com.just.agentweb.sample.common;\n\nimport android.app.Activity;\nimport android.os.Build;\nimport android.webkit.Do"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/common/FragmentKeyDown.java",
"chars": 273,
"preview": "package com.just.agentweb.sample.common;\n\nimport android.view.KeyEvent;\n\n/**\n * Created by cenxiaozhong on 2017/5/23.\n *"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/common/GuideItemEntity.java",
"chars": 1304,
"preview": "/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 ("
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/common/UIController.java",
"chars": 2291,
"preview": "package com.just.agentweb.sample.common;\n\nimport android.app.Activity;\nimport android.os.Handler;\nimport android.util.Lo"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/fragment/AgentWebFragment.java",
"chars": 29001,
"preview": "package com.just.agentweb.sample.fragment;\n\n\nimport android.annotation.SuppressLint;\nimport android.content.ClipData;\nim"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/fragment/BounceWebFragment.java",
"chars": 2557,
"preview": "package com.just.agentweb.sample.fragment;\n\nimport android.graphics.Color;\nimport android.os.Bundle;\nimport androidx.ann"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/fragment/CustomIndicatorFragment.java",
"chars": 2044,
"preview": "package com.just.agentweb.sample.fragment;\n\nimport android.os.Bundle;\nimport androidx.annotation.Nullable;\nimport androi"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/fragment/CustomSettingsFragment.java",
"chars": 751,
"preview": "package com.just.agentweb.sample.fragment;\n\nimport android.os.Bundle;\n\nimport com.just.agentweb.IAgentWebSettings;\nimpor"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/fragment/CustomWebViewFragment.java",
"chars": 2999,
"preview": "package com.just.agentweb.sample.fragment;\n\nimport android.os.Bundle;\nimport androidx.annotation.Nullable;\nimport androi"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/fragment/EasyWebFragment.java",
"chars": 3348,
"preview": "package com.just.agentweb.sample.fragment;\n\nimport android.os.Bundle;\nimport androidx.annotation.NonNull;\nimport android"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/fragment/JsAgentWebFragment.java",
"chars": 3619,
"preview": "package com.just.agentweb.sample.fragment;\n\nimport android.os.Build;\nimport android.os.Bundle;\nimport androidx.annotatio"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/fragment/JsbridgeWebFragment.java",
"chars": 3736,
"preview": "package com.just.agentweb.sample.fragment;\n\nimport android.graphics.Bitmap;\nimport android.os.Build;\nimport android.os.B"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/fragment/SmartRefreshWebFragment.java",
"chars": 2333,
"preview": "package com.just.agentweb.sample.fragment;\n\nimport android.graphics.Color;\nimport android.os.Bundle;\nimport androidx.ann"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/fragment/VasSonicFragment.java",
"chars": 2208,
"preview": "package com.just.agentweb.sample.fragment;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport androidx.ann"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/provider/ServiceProvider.java",
"chars": 230,
"preview": "package com.just.agentweb.sample.provider;\n\nimport com.flyingpigeon.library.ServiceContentProvider;\n\n/**\n * @author xiao"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/provider/WebServiceProvider.java",
"chars": 233,
"preview": "package com.just.agentweb.sample.provider;\n\nimport com.flyingpigeon.library.ServiceContentProvider;\n\n/**\n * @author xiao"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/service/WebService.java",
"chars": 789,
"preview": "package com.just.agentweb.sample.service;\n\nimport android.app.Service;\nimport android.content.Intent;\nimport android.os."
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/sonic/DefaultSonicRuntimeImpl.java",
"chars": 4222,
"preview": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/sonic/SonicImpl.java",
"chars": 2213,
"preview": "package com.just.agentweb.sample.sonic;\n\nimport android.content.Context;\n\nimport com.just.agentweb.AgentWeb;\nimport com."
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/sonic/SonicJavaScriptInterface.java",
"chars": 4707,
"preview": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/sonic/SonicSessionClientImpl.java",
"chars": 1948,
"preview": "/*\n * Tencent is pleased to support the open source community by making VasSonic available.\n *\n * Copyright (C) 2017 THL"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/sonic/SonicWebViewClient.java",
"chars": 1259,
"preview": "package com.just.agentweb.sample.sonic;\n\nimport android.annotation.TargetApi;\nimport android.webkit.WebResourceRequest;\n"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/utils/FileUtils.java",
"chars": 424,
"preview": "package com.just.agentweb.sample.utils;\n\n/**\n * @author cenxiaozhong\n * @date 2021/11/27\n * @since 1.0.0\n */\npublic clas"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/utils/ProcessUtils.java",
"chars": 2854,
"preview": "package com.just.agentweb.sample.utils;\n\nimport android.app.ActivityManager;\nimport android.app.Application;\nimport andr"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/utils/WebCompat.java",
"chars": 11220,
"preview": "package com.just.agentweb.sample.utils;\n\nimport android.annotation.SuppressLint;\nimport android.annotation.TargetApi;\nim"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/widget/CommonIndicator.java",
"chars": 963,
"preview": "package com.just.agentweb.sample.widget;\n\nimport android.content.Context;\nimport androidx.annotation.Nullable;\nimport an"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/widget/CoolIndicatorLayout.java",
"chars": 2448,
"preview": "\n/*\n * Copyright (C) Justson(https://github.com/Justson/AgentWeb)\n *\n * Licensed under the Apache License, Version 2.0 "
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/widget/SmartRefreshWebLayout.java",
"chars": 1122,
"preview": "package com.just.agentweb.sample.widget;\n\nimport android.app.Activity;\nimport androidx.annotation.NonNull;\nimport androi"
},
{
"path": "sample/src/main/java/com/just/agentweb/sample/widget/WebLayout.java",
"chars": 1220,
"preview": "package com.just.agentweb.sample.widget;\n\nimport android.app.Activity;\nimport androidx.annotation.NonNull;\nimport androi"
},
{
"path": "sample/src/main/res/drawable/btn_shape.xml",
"chars": 256,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:"
},
{
"path": "sample/src/main/res/drawable/btn_shape_s.xml",
"chars": 250,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:"
},
{
"path": "sample/src/main/res/drawable/ic_baseline_search_24.xml",
"chars": 554,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:width=\"24dp\"\n android:height=\"24dp\"\n "
},
{
"path": "sample/src/main/res/drawable/indicator_shape.xml",
"chars": 255,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\" android:shape=\""
},
{
"path": "sample/src/main/res/drawable/iv_back_selector.xml",
"chars": 295,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n <item "
},
{
"path": "sample/src/main/res/drawable/selector_drawable_for_btn.xml",
"chars": 254,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <item a"
},
{
"path": "sample/src/main/res/drawable-v21/ripple_for_btn.xml",
"chars": 266,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ripple xmlns:android=\"http://schemas.android.com/apk/res/android\"\n androi"
},
{
"path": "sample/src/main/res/drawable-v21/selector_drawable_for_btn.xml",
"chars": 230,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ripple xmlns:android=\"http://schemas.android.com/apk/res/android\"\n androi"
},
{
"path": "sample/src/main/res/layout/activity_auto_hiden_toolbar.xml",
"chars": 2505,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android=\"http://schema"
},
{
"path": "sample/src/main/res/layout/activity_common.xml",
"chars": 262,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n a"
},
{
"path": "sample/src/main/res/layout/activity_main.xml",
"chars": 1194,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n "
},
{
"path": "sample/src/main/res/layout/activity_native_download.xml",
"chars": 1276,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n "
},
{
"path": "sample/src/main/res/layout/activity_web.xml",
"chars": 1199,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n "
},
{
"path": "sample/src/main/res/layout/fragment_agentweb.xml",
"chars": 423,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n "
},
{
"path": "sample/src/main/res/layout/fragment_js.xml",
"chars": 2248,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n "
},
{
"path": "sample/src/main/res/layout/fragment_srl_web.xml",
"chars": 1267,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.scwang.smartrefresh.layout.SmartRefreshLayout\n xmlns:android=\"http://sche"
},
{
"path": "sample/src/main/res/layout/fragment_twk_web.xml",
"chars": 723,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout\n xmlns:android=\"http://s"
},
{
"path": "sample/src/main/res/layout/listview_main.xml",
"chars": 596,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n "
},
{
"path": "sample/src/main/res/layout/markdown_view.xml",
"chars": 646,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\nxmlns:android=\"http://schemas.android.com/apk/res/android\"\nandroid:"
},
{
"path": "sample/src/main/res/layout/recyclerview_item_download.xml",
"chars": 1865,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n "
},
{
"path": "sample/src/main/res/layout/toorbar_main.xml",
"chars": 3430,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.appcompat.widget.Toolbar\n android:id=\"@+id/toolbar\"\n android:layo"
},
{
"path": "sample/src/main/res/menu/toolbar_menu.xml",
"chars": 899,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu\n xmlns:android=\"http://schemas.android.com/apk/res/android\"\n\n xmlns:a"
},
{
"path": "sample/src/main/res/values/colors.xml",
"chars": 493,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <color name=\"colorPrimary\">#393a3f</color>\n <color name=\"color"
},
{
"path": "sample/src/main/res/values/strings.xml",
"chars": 92,
"preview": "<resources>\n <string name=\"app_name\" translatable=\"false\">AgentWeb</string>\n</resources>\n"
},
{
"path": "sample/src/main/res/values/styles.xml",
"chars": 1013,
"preview": "<resources>\n\n <!-- Base application theme. -->\n <style name=\"BaseAppTheme\" parent=\"AppTheme\">\n <!-- Customi"
},
{
"path": "sample/src/main/res/xml/network_security_config.xml",
"chars": 293,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<network-security-config>\r\n <base-config cleartextTrafficPermitted=\"true\">\r\n "
},
{
"path": "sample/src/test/java/com/just/agentweb/sample/ExampleUnitTest.java",
"chars": 402,
"preview": "package com.just.agentweb.sample;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit "
},
{
"path": "settings.gradle",
"chars": 62,
"preview": "include ':sample', ':agentweb-core', ':agentweb-filechooser'\n"
}
]
// ... and 6 more files (download for full content)
About this extraction
This page contains the full source code of the Justson/AgentWeb GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 202 files (630.7 KB), approximately 155.6k tokens, and a symbol index with 1227 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.