├── .gitignore ├── README.md ├── YouzanBasicSample ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── youzanyun │ │ └── sdk │ │ └── sample │ │ └── basic │ │ ├── KaeConfig.java │ │ ├── MainActivity.java │ │ ├── MyApplication.java │ │ ├── WebViewFragment.java │ │ ├── YouzanActivity.java │ │ └── YouzanFragment.java │ └── res │ ├── layout │ ├── activity_main.xml │ ├── activity_placeholder.xml │ └── fragment_youzan.xml │ ├── menu │ └── menu_youzan_share.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml │ └── xml │ └── network_security_config.xml ├── YouzanX5Sample ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── youzanyun │ │ └── sdk │ │ └── sample │ │ ├── MyApplication.kt │ │ ├── cache │ │ ├── OfflineYouzanWebView.kt │ │ ├── WebResource.java │ │ ├── WebViewCache.java │ │ ├── WebViewCacheImpl.java │ │ ├── api │ │ │ └── FastOpenApi.java │ │ ├── config │ │ │ ├── CacheConfig.java │ │ │ ├── DefaultMimeTypeFilter.java │ │ │ ├── FastCacheMode.java │ │ │ └── MimeTypeFilter.java │ │ ├── cookie │ │ │ ├── CookieInterceptor.java │ │ │ ├── CookieJarImpl.java │ │ │ ├── CookieStore.java │ │ │ ├── CookieStrategy.java │ │ │ ├── FastCookieManager.java │ │ │ ├── MemoryCookieStore.java │ │ │ ├── PersistentCookieStore.java │ │ │ └── SerializableCookie.java │ │ ├── loader │ │ │ ├── DefaultResourceLoader.java │ │ │ ├── OkHttpResourceLoader.java │ │ │ ├── ResourceLoader.java │ │ │ └── SourceRequest.java │ │ ├── offline │ │ │ ├── CacheRequest.java │ │ │ ├── Chain.java │ │ │ ├── DefaultRemoteResourceInterceptor.java │ │ │ ├── DefaultWebResponseGenerator.java │ │ │ ├── Destroyable.java │ │ │ ├── DiskResourceInterceptor.java │ │ │ ├── ForceRemoteResourceInterceptor.java │ │ │ ├── MemResourceInterceptor.java │ │ │ ├── OfflineServer.java │ │ │ ├── OfflineServerImpl.java │ │ │ ├── PhraseList.java │ │ │ ├── ResourceInterceptor.java │ │ │ └── WebResourceResponseGenerator.java │ │ └── okhttp │ │ │ └── OkHttpClientProvider.java │ │ ├── config │ │ └── KaeConfig.kt │ │ ├── helper │ │ ├── LoginHelper.kt │ │ └── YouzanHelper.kt │ │ └── x5 │ │ ├── LoginActivity.kt │ │ ├── LogoutFragment.kt │ │ ├── MainActivity.kt │ │ ├── SplashActivity.kt │ │ ├── WebViewFragment.java │ │ ├── YouzanActivity.kt │ │ └── YouzanFragment.kt │ └── res │ ├── drawable-xxhdpi │ ├── ic_launcher.png │ └── refresh.png │ ├── layout │ ├── activity_login.xml │ ├── activity_main.xml │ ├── activity_placeholder.xml │ ├── activity_splash.xml │ ├── fg_logout.xml │ └── fragment_youzan.xml │ ├── menu │ └── menu_youzan_share.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml │ └── xml │ └── network_security_config.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Android template 3 | # Built application files 4 | *.apk 5 | *.ap_ 6 | 7 | # Files for the Dalvik VM 8 | *.dex 9 | 10 | # Java class files 11 | *.class 12 | 13 | # Generated files 14 | bin/ 15 | gen/ 16 | 17 | # Gradle files 18 | .gradle/ 19 | build/ 20 | 21 | #demo jar 22 | sample/libs/ 23 | 24 | # idea 25 | .idea/ 26 | *.iml 27 | 28 | # Local configuration file (sdk path, etc) 29 | local.properties 30 | 31 | # Proguard folder generated by Eclipse 32 | proguard/ 33 | 34 | # Log Files 35 | *.log 36 | 37 | # Android Studio Navigation editor temp files 38 | .navigation/ 39 | 40 | #infer 41 | infer-out/ 42 | 43 | .gradletasknamecache 44 | captures/ 45 | 46 | #debug jar 47 | /jar/debug 48 | 49 | YouzanSDKAndroidAPI/ 50 | 51 | #Local test repo 52 | repo/ 53 | core/project.properties 54 | 55 | demo/nativedemo/libs/ 56 | 57 | 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![License MIT](https://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://github.com/youzan/SigmaTableViewModel/blob/master/LICENSE)  2 | [![Platform](https://img.shields.io/badge/platform-Android-yellow.svg)](https://www.android.com) 3 | 4 | [集成腾讯X5内核的开店SDK][![Release](https://api.bintray.com/packages/youzanyun/maven/x5sdk/images/download.png)](https://bintray.com/youzanyun/maven/) 5 | (注意:如果从原生WebView的SDK版本升级到X5内核的SDK版本时,务必查看[相关文档](https://github.com/youzan/YouzanMobileSDK-Android/wiki/%E5%9F%BA%E4%BA%8E%E5%8E%9F%E7%94%9FWebView%E7%9A%84%E5%BC%80%E5%BA%97SDK%E5%88%87%E6%8D%A2%E5%88%B0X5%E7%89%88%E6%9C%AC%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9)) 6 | 7 | 8 | [基于原生WebView的开店SDK][![Release](https://api.bintray.com/packages/youzanyun/maven/basic/images/download.png)](https://bintray.com/youzanyun/maven/)不建议继续使用 9 | 10 |

11 | 有赞logo 12 |

13 | 14 | ## 有赞云App SDK(Android端) 15 | 16 | 为了满足移动应用搭建商城的需求,有赞云将有赞积累多年的电商交易系统开放,移动开发者**通过一个 SDK 便可以在 App 内集成有赞提供的整个交易服务**,除了享受完善的商城功能、丰富的营销玩法,更有有赞强劲的技术及服务作保障,实现低成本、高效率、强融合的移动电商方案,快速获得 App 流量的商业化变现。该SDK基于 WebView 将有赞提供的 HTML5 页面嵌入到 App 中,基于此提供帐号打通、资产合并、客服 IM、多渠道支付、营销能力开放等 App 应用特色功能,更拥有媲美原生页面的性能。 17 | 18 | ### X5内核版本开店SDK(推荐使用) 19 | 依托腾讯浏览服务的开店SDK,加载速度更快,兼容性与安全性更好,视频性能更出色。安装包大约增加400k。**特别建议在App开店中需要播放视频(例如知识付费)的开发者使用此版本** 20 | 21 | ### 系统原生WebView(不建议继续使用) 22 | 基于系统原生WebView提供服务,在兼容性与性能上比X5内核版本较差,不建议继续使用。 23 | 24 | 25 | 对接过程中有任何问题、需求、建议,或是想了解 AppSDK 更多玩法,欢迎联系有赞青溪,yuzan_qingxi(微信)。 26 | 27 | ## 引入 28 | 29 | 在项目根目录的build.gradle中声明maven仓库, 如下所示: 30 | 31 | ``` groove 32 | allprojects { 33 | repositories { 34 | jcenter() 35 | maven { url 'http://maven.youzanyun.com/repository/maven-releases' } 36 | } 37 | } 38 | ``` 39 | 40 | 在子项目build.gradle的dependencies中根据需求引入依赖: 41 | 42 | 基于腾讯x5内核的开店SDK: 43 | ``` groovy 44 | implementation 'com.youzanyun.open.mobile:x5sdk:最新版本',{ 45 | exclude group: 'com.youzan.mobile', module: 'x5official' 46 | } 47 | ``` 48 | 基于Android原生WebView的开店SDK: 49 | ``` groovy 50 | implementation 'com.youzanyun.open.mobile:basic:最新版本' 51 | ``` 52 | 53 | ## 文档 54 | 55 | * [开发文档](https://github.com/youzan/YouzanMobileSDK-Android/wiki) 56 | * [X5版本SDK更新文档](https://github.com/youzan/YouzanMobileSDK-Android/wiki/%E6%9B%B4%E6%96%B0%E8%AF%B4%E6%98%8E-X5%E5%86%85%E6%A0%B8%E7%89%88%E6%9C%AC) 57 | * [原生内核版本SDK更新文档](https://github.com/youzan/YouzanMobileSDK-Android/wiki/%E6%9B%B4%E6%96%B0%E8%AF%B4%E6%98%8E-%E5%8E%9F%E7%94%9F%E5%86%85%E6%A0%B8%E7%89%88%E6%9C%AC) 58 | * [常见问题](https://github.com/youzan/YouzanMobileSDK-Android/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98) 59 | 60 | ## 交流&反馈 61 | 62 | * [有赞官方论坛](https://bbs.youzan.com/forum-98-1.html) 63 | * [github issue](https://github.com/youzan/YouzanMobileSDK-Android/issues) 64 | 65 | ## License 66 | [MIT](https://zh.wikipedia.org/wiki/MIT%E8%A8%B1%E5%8F%AF%E8%AD%89) 67 | 68 | -------------------------------------------------------------------------------- /YouzanBasicSample/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /YouzanBasicSample/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 youzanyun.com, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | apply plugin: 'com.android.application' 18 | def switchDep = "../../deploy/switchDep.gradle" 19 | 20 | if (file(switchDep).exists()) { 21 | apply from: switchDep 22 | } else { 23 | println("switchDep 文件不存在") 24 | } 25 | 26 | android { 27 | compileSdkVersion 28 28 | 29 | defaultConfig { 30 | applicationId "com.youzanyun.sdk.sample.basic" 31 | minSdkVersion 16 32 | targetSdkVersion 28 33 | versionCode 1 34 | versionName "1.0" 35 | } 36 | buildTypes { 37 | release { 38 | minifyEnabled false 39 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 40 | } 41 | } 42 | 43 | compileOptions { 44 | sourceCompatibility JavaVersion.VERSION_1_8 45 | targetCompatibility JavaVersion.VERSION_1_8 46 | } 47 | 48 | } 49 | 50 | repositories { 51 | flatDir { 52 | dirs 'libs' 53 | } 54 | } 55 | dependencies { 56 | implementation fileTree(include: ['*.jar'], dir: 'libs') 57 | testImplementation 'junit:junit:4.12' 58 | testImplementation('com.android.support.test.espresso:espresso-core:3.0.1', { 59 | exclude group: 'com.android.support', module: 'support-annotations' 60 | }) 61 | //basic版本 62 | implementation("com.youzanyun.open.mobile:basic:7.15.1") 63 | implementation 'com.android.support:appcompat-v7:28.0.0' 64 | 65 | implementation "com.alibaba:fastjson:1.2.78" 66 | } 67 | -------------------------------------------------------------------------------- /YouzanBasicSample/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/qbeenslee/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | 27 | # Youzan SDK 28 | -dontwarn com.youzan.androidsdk.*** 29 | -keep class com.youzan.androidsdk.**{*;} 30 | 31 | # OkHttp 32 | -dontwarn okhttp3.** 33 | -dontwarn okio.** 34 | -dontwarn com.squareup.okhttp.** 35 | -keep class okio.**{*;} 36 | -keep class com.squareup.okhttp.** { *; } 37 | -keep interface com.squareup.okhttp.** { *; } 38 | 39 | -dontwarn java.nio.file.* 40 | -dontwarn javax.annotation.** 41 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement 42 | 43 | # Image Loader 44 | -keep class com.squareup.picasso.Picasso 45 | -keep class com.android.volley.toolbox.Volley 46 | -keep class com.bumptech.glide.Glide 47 | -keep class com.nostra13.universalimageloader.core.ImageLoader 48 | -keep class com.facebook.drawee.backends.pipeline.Fresco -------------------------------------------------------------------------------- /YouzanBasicSample/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /YouzanBasicSample/src/main/java/com/youzanyun/sdk/sample/basic/KaeConfig.java: -------------------------------------------------------------------------------- 1 | package com.youzanyun.sdk.sample.basic; 2 | 3 | /** 4 | * auther: liusaideng 5 | * created on : 2024/7/2 19:44 6 | * desc: 7 | */ 8 | public class KaeConfig { 9 | // public static String URL_MAIN = "https://shop139935761.m.youzan.com/wscshop/showcase/homepage?kdt_id=139743593"; 10 | // public static String URL_MAIN = "https://shop143703561.youzan.com/v2/showcase/homepage?alias=b0hB2PIg6s&dc_ps=3626055956015745029.300001"; 11 | public static String URL_MAIN = "https://shop141337475.m.youzan.com/wscshop/showcase/homepage?kdt_id=141145307"; 12 | 13 | } -------------------------------------------------------------------------------- /YouzanBasicSample/src/main/java/com/youzanyun/sdk/sample/basic/MainActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 youzanyun.com, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.youzanyun.sdk.sample.basic; 18 | 19 | import android.app.Activity; 20 | import android.content.Intent; 21 | import android.os.Bundle; 22 | import android.view.View; 23 | 24 | import com.youzan.androidsdk.YouzanSDK; 25 | 26 | 27 | public class MainActivity extends Activity implements View.OnClickListener { 28 | 29 | @Override 30 | protected void onCreate(Bundle savedInstanceState) { 31 | super.onCreate(savedInstanceState); 32 | setContentView(R.layout.activity_main); 33 | findViewById(R.id.button_open).setOnClickListener(this); 34 | findViewById(R.id.button_clear).setOnClickListener(this); 35 | } 36 | 37 | @Override 38 | public void onClick(View v) { 39 | switch (v.getId()) { 40 | case R.id.button_open: 41 | //店铺链接, 可以从有赞后台`店铺=>店铺概况=>访问店铺`复制到相应的链接,这里是一个测试链接 42 | // gotoActivity("https://shop16911610.m.youzan.com/wscshop/showcase/homepage?kdt_id=16719442"); 43 | gotoActivity(KaeConfig.URL_MAIN); 44 | break; 45 | case R.id.button_clear: 46 | YouzanSDK.userLogout(this); 47 | break; 48 | default: 49 | break; 50 | } 51 | } 52 | 53 | private void gotoActivity(String url){ 54 | Intent intent = new Intent(this, YouzanActivity.class); 55 | intent.putExtra(YouzanActivity.KEY_URL, url); 56 | startActivity(intent); 57 | } 58 | } -------------------------------------------------------------------------------- /YouzanBasicSample/src/main/java/com/youzanyun/sdk/sample/basic/MyApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 youzanyun.com, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.youzanyun.sdk.sample.basic; 18 | 19 | import android.app.Application; 20 | 21 | import com.youzan.androidsdk.InitCallBack; 22 | import com.youzan.androidsdk.InitConfig; 23 | import com.youzan.androidsdk.YouzanSDK; 24 | import com.youzan.androidsdk.basic.YouzanBasicSDKAdapter; 25 | import com.youzan.androidsdk.basic.YouzanPreloader; 26 | 27 | 28 | public class MyApplication extends Application { 29 | @Override 30 | public void onCreate() { 31 | super.onCreate(); 32 | 33 | // 初始化SDK 34 | //appkey:可以前往有赞开放平台申请 35 | YouzanSDK.isDebug(true); 36 | YouzanSDK.init(this, new InitConfig.Builder() 37 | .clientId("0073bccbaf5369028a") 38 | .appkey("") 39 | .initCallBack(new InitCallBack() { 40 | @Override 41 | public void readyCallBack(boolean ready, String message) { 42 | } 43 | }) 44 | .adapter(new YouzanBasicSDKAdapter()) 45 | .build() 46 | ); 47 | 48 | YouzanPreloader.preloadHtml(this, KaeConfig.URL_MAIN); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /YouzanBasicSample/src/main/java/com/youzanyun/sdk/sample/basic/WebViewFragment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.youzanyun.sdk.sample.basic; 18 | 19 | import android.os.Bundle; 20 | import android.support.annotation.IdRes; 21 | import android.support.annotation.LayoutRes; 22 | import android.support.v4.app.Fragment; 23 | import android.view.LayoutInflater; 24 | import android.view.View; 25 | import android.view.ViewGroup; 26 | 27 | import com.youzan.androidsdk.basic.YouzanBrowser; 28 | 29 | 30 | /** 31 | * A fragment that displays a WebView. 32 | * The WebView is automically paused or resumed when the Fragment is paused or resumed. 33 | */ 34 | public abstract class WebViewFragment extends Fragment { 35 | private YouzanBrowser mWebView; 36 | private boolean mIsWebViewAvailable; 37 | 38 | public WebViewFragment() { 39 | } 40 | 41 | /** 42 | * Called to instantiate the view. Creates and returns the WebView. 43 | */ 44 | @Override 45 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 46 | if (mWebView != null) { 47 | mWebView.destroy(); 48 | } 49 | View contentView = inflater.inflate(getLayoutId(), container, false); 50 | mWebView = (YouzanBrowser) contentView.findViewById(getWebViewId()); 51 | mIsWebViewAvailable = true; 52 | return contentView; 53 | } 54 | 55 | /** 56 | * @return The id of WebView in layout 57 | */ 58 | @IdRes 59 | protected abstract int getWebViewId(); 60 | 61 | /** 62 | * @return the layout id for Fragment 63 | */ 64 | @LayoutRes 65 | protected abstract int getLayoutId(); 66 | 67 | /** 68 | * Called when the fragment is visible to the user and actively running. Resumes the WebView. 69 | */ 70 | @Override 71 | public void onPause() { 72 | super.onPause(); 73 | mWebView.onPause(); 74 | } 75 | 76 | /** 77 | * Called when the fragment is no longer resumed. Pauses the WebView. 78 | */ 79 | @Override 80 | public void onResume() { 81 | mWebView.onResume(); 82 | super.onResume(); 83 | } 84 | 85 | /** 86 | * Called when the WebView has been detached from the fragment. 87 | * The WebView is no longer available after this time. 88 | */ 89 | @Override 90 | public void onDestroyView() { 91 | mIsWebViewAvailable = false; 92 | super.onDestroyView(); 93 | } 94 | 95 | /** 96 | * Called when the fragment is no longer in use. Destroys the internal state of the WebView. 97 | */ 98 | @Override 99 | public void onDestroy() { 100 | if (mWebView != null) { 101 | mWebView.destroy(); 102 | mWebView = null; 103 | } 104 | super.onDestroy(); 105 | } 106 | 107 | /** 108 | * Take care of popping the fragment back stack or finishing the activity 109 | * as appropriate. 110 | * 111 | * @return True if the host application wants to handle back press by itself, otherwise return false. 112 | */ 113 | public boolean onBackPressed() { 114 | return false; 115 | } 116 | 117 | /** 118 | * Gets the WebView. 119 | */ 120 | public YouzanBrowser getWebView() { 121 | return mIsWebViewAvailable ? mWebView : null; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /YouzanBasicSample/src/main/java/com/youzanyun/sdk/sample/basic/YouzanActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 youzanyun.com, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.youzanyun.sdk.sample.basic; 18 | 19 | import android.os.Bundle; 20 | import android.support.annotation.Nullable; 21 | import android.support.v7.app.AppCompatActivity; 22 | 23 | 24 | public class YouzanActivity extends AppCompatActivity { 25 | public static final String KEY_URL = "url"; 26 | private YouzanFragment mFragment; 27 | 28 | 29 | @Override 30 | protected void onCreate(@Nullable Bundle savedInstanceState) { 31 | super.onCreate(savedInstanceState); 32 | setContentView(R.layout.activity_placeholder); 33 | mFragment = new YouzanFragment(); 34 | mFragment.setArguments(getIntent().getExtras()); 35 | 36 | getSupportFragmentManager() 37 | .beginTransaction() 38 | .replace(R.id.placeholder, mFragment) 39 | .commitAllowingStateLoss(); 40 | } 41 | 42 | @Override 43 | public void onBackPressed() { 44 | if (mFragment == null || !mFragment.onBackPressed()) { 45 | super.onBackPressed(); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /YouzanBasicSample/src/main/java/com/youzanyun/sdk/sample/basic/YouzanFragment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 youzanyun.com, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.youzanyun.sdk.sample.basic; 18 | 19 | 20 | import static android.app.Activity.RESULT_OK; 21 | 22 | import android.content.ActivityNotFoundException; 23 | import android.content.Context; 24 | import android.content.Intent; 25 | import android.net.http.SslError; 26 | import android.os.Build; 27 | import android.os.Bundle; 28 | import android.support.annotation.Nullable; 29 | import android.support.annotation.RequiresApi; 30 | import android.support.v4.widget.SwipeRefreshLayout; 31 | import android.support.v7.widget.Toolbar; 32 | import android.view.MenuItem; 33 | import android.view.View; 34 | import android.webkit.SslErrorHandler; 35 | import android.webkit.WebView; 36 | import android.webkit.WebViewClient; 37 | import android.widget.Toast; 38 | 39 | import com.google.gson.Gson; 40 | import com.youzan.androidsdk.YouzanLog; 41 | import com.youzan.androidsdk.YouzanSDK; 42 | import com.youzan.androidsdk.YouzanToken; 43 | import com.youzan.androidsdk.YzLoginCallback; 44 | import com.youzan.androidsdk.basic.YouzanBrowser; 45 | import com.youzan.androidsdk.basic.compat.CompatWebChromeClient; 46 | import com.youzan.androidsdk.basic.compat.VideoCallback; 47 | import com.youzan.androidsdk.basic.compat.WebChromeClientConfig; 48 | import com.youzan.androidsdk.event.AbsAuthEvent; 49 | import com.youzan.androidsdk.event.AbsCheckAuthMobileEvent; 50 | import com.youzan.androidsdk.event.AbsChooserEvent; 51 | import com.youzan.androidsdk.event.AbsPaymentFinishedEvent; 52 | import com.youzan.androidsdk.event.AbsShareEvent; 53 | import com.youzan.androidsdk.event.AbsStateEvent; 54 | import com.youzan.androidsdk.model.goods.GoodsShareModel; 55 | import com.youzan.androidsdk.model.trade.TradePayFinishedModel; 56 | 57 | 58 | /** 59 | * 这里使用{@link WebViewFragment}对{@link android.webkit.WebView}生命周期有更好的管控. 60 | */ 61 | public class YouzanFragment extends WebViewFragment implements SwipeRefreshLayout.OnRefreshListener { 62 | private YouzanBrowser mView; 63 | private SwipeRefreshLayout mRefreshLayout; 64 | private Toolbar mToolbar; 65 | private static final int CODE_REQUEST_LOGIN = 0x1000; 66 | 67 | @Override 68 | public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 69 | super.onViewCreated(view, savedInstanceState); 70 | setupViews(view); 71 | setupYouzan(); 72 | 73 | final String url = getArguments().getString(YouzanActivity.KEY_URL); 74 | mView.loadUrl(url); 75 | //加载H5时,开启默认loading 76 | //设置自定义loading图片 77 | // mView.setLoadingImage(R.mipmap.ic_launcher); 78 | } 79 | 80 | private void setupViews(View contentView) { 81 | //WebView 82 | mView = getWebView(); 83 | 84 | mToolbar = (Toolbar) contentView.findViewById(R.id.toolbar); 85 | // mRefreshLayout = (SwipeRefreshLayout) contentView.findViewById(R.id.swipe); 86 | 87 | //分享按钮 88 | mToolbar.setTitle(R.string.loading_page); 89 | mToolbar.inflateMenu(R.menu.menu_youzan_share); 90 | mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { 91 | @Override 92 | public boolean onMenuItemClick(MenuItem item) { 93 | switch (item.getItemId()) { 94 | case R.id.action_share: 95 | mView.sharePage(); 96 | return true; 97 | default: 98 | return false; 99 | } 100 | } 101 | }); 102 | 103 | //刷新 104 | // mRefreshLayout.setOnRefreshListener(this); 105 | // mRefreshLayout.setColorSchemeColors(Color.BLUE, Color.RED); 106 | // mRefreshLayout.setEnabled(false); 107 | 108 | mView.setWebViewClient(new WebViewClient() { 109 | 110 | 111 | @Override 112 | public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { 113 | // 接入是需手动处理此部分证书逻辑 114 | handler.proceed(); 115 | } 116 | 117 | @RequiresApi(api = Build.VERSION_CODES.KITKAT) 118 | @Override 119 | public void onPageFinished(WebView view, String url) { 120 | super.onPageFinished(view, url); 121 | } 122 | }); 123 | 124 | mView.setWebChromeClient(new CompatWebChromeClient( 125 | new WebChromeClientConfig( 126 | true, new VideoCallback() { 127 | @Override 128 | public void onVideoCallback(boolean b) { 129 | Toast.makeText(getActivity(), "" + b, Toast.LENGTH_SHORT).show(); 130 | } 131 | 132 | 133 | } 134 | ) 135 | ) { 136 | @Override 137 | public void onReceivedTitle(WebView view, String title) { 138 | super.onReceivedTitle(view, title); 139 | } 140 | }); 141 | 142 | } 143 | 144 | private void setupYouzan() { 145 | mView.subscribe(new AbsCheckAuthMobileEvent(){}); 146 | //认证事件, 回调表示: 需要需要新的认证信息传入 147 | mView.subscribe(new AbsAuthEvent() { 148 | 149 | @Override 150 | public void call(Context context, boolean needLogin) { 151 | /** 152 | * 建议实现逻辑: 153 | * 154 | * 判断App内的用户是否登录? 155 | * => 已登录: 请求带用户角色的认证信息(login接口); 156 | * => 未登录: needLogin为true, 唤起App内登录界面, 请求带用户角色的认证信息(login接口); 157 | * => 未登录: needLogin为false, 请求不带用户角色的认证信息(initToken接口). 158 | * 159 | * 服务端接入文档: https://www.youzanyun.com/docs/guide/appsdk/683 160 | */ 161 | //TODO 自行编码实现. 具体可参考开发文档中的伪代码实现 162 | //TODO 手机号自己填入 163 | YouzanSDK.yzlogin("31467761", "https://cdn.daddylab.com/Upload/android/20210113/021119/au9j4d6aed5xfweg.jpeg?w=1080&h=1080", "", "一百亿养乐多", "0", new YzLoginCallback() { 164 | @Override 165 | public void onSuccess(YouzanToken youzanToken) { 166 | mView.post(new Runnable() { 167 | @Override 168 | public void run() { 169 | mView.sync(youzanToken); 170 | } 171 | }); 172 | } 173 | 174 | @Override 175 | public void onFail(String s) { 176 | 177 | } 178 | }); 179 | } 180 | }); 181 | mView.subscribe(new AbsCheckAuthMobileEvent() {}); 182 | //文件选择事件, 回调表示: 发起文件选择. (如果app内使用的是系统默认的文件选择器, 该事件可以直接删除) 183 | mView.subscribe(new AbsChooserEvent() { 184 | @Override 185 | public void call(Context context, Intent intent, int requestCode) throws ActivityNotFoundException { 186 | startActivityForResult(intent, requestCode); 187 | } 188 | }); 189 | 190 | //页面状态事件, 回调表示: 页面加载完成 191 | mView.subscribe(new AbsStateEvent() { 192 | @Override 193 | public void call(Context context) { 194 | mToolbar.setTitle(mView.getTitle()); 195 | 196 | //停止刷新 197 | // mRefreshLayout.setRefreshing(false); 198 | // mRefreshLayout.setEnabled(true); 199 | } 200 | }); 201 | //分享事件, 回调表示: 获取到当前页面的分享信息数据 202 | mView.subscribe(new AbsShareEvent() { 203 | @Override 204 | public void call(Context context, GoodsShareModel data) { 205 | /** 206 | * 在获取数据后, 可以使用其他分享SDK来提高分享体验. 207 | * 这里调用系统分享来简单演示分享的过程. 208 | */ 209 | String content = data.getDesc() + data.getLink(); 210 | Intent sendIntent = new Intent(); 211 | sendIntent.setAction(Intent.ACTION_SEND); 212 | sendIntent.putExtra(Intent.EXTRA_TEXT, content); 213 | sendIntent.putExtra(Intent.EXTRA_SUBJECT, data.getTitle()); 214 | sendIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 215 | sendIntent.setType("text/plain"); 216 | startActivity(sendIntent); 217 | } 218 | }); 219 | 220 | mView.subscribe(new AbsPaymentFinishedEvent() { 221 | @Override 222 | public void call(Context context, TradePayFinishedModel tradePayFinishedModel) { 223 | 224 | } 225 | }); 226 | } 227 | 228 | 229 | @Override 230 | protected int getWebViewId() { 231 | //YouzanBrowser在布局文件中的id 232 | return R.id.view; 233 | } 234 | 235 | 236 | @Override 237 | protected int getLayoutId() { 238 | //布局文件 239 | return R.layout.fragment_youzan; 240 | } 241 | 242 | @Override 243 | public boolean onBackPressed() { 244 | //页面回退 245 | return getWebView().pageGoBack(); 246 | } 247 | 248 | @Override 249 | public void onRefresh() { 250 | //重新加载页面 251 | mView.reload(); 252 | } 253 | 254 | @Override 255 | public void onActivityResult(int requestCode, int resultCode, Intent data) { 256 | super.onActivityResult(requestCode, resultCode, data); 257 | if (CODE_REQUEST_LOGIN == requestCode) {// 如果是登录事件返回 258 | if (resultCode == RESULT_OK) { 259 | // 登录成功设置token 260 | 261 | } else { 262 | // 登录失败 263 | mView.syncNot(); 264 | } 265 | } else { 266 | // 文件选择事件处理。 267 | mView.receiveFile(requestCode, data); 268 | } 269 | } 270 | } 271 | 272 | -------------------------------------------------------------------------------- /YouzanBasicSample/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 24 | 25 |