├── .gitignore ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── zgcwkj │ │ ├── bllcode │ │ ├── CommonHelp.java │ │ ├── CookieHep.java │ │ ├── DialogLoading.java │ │ ├── QLongHelp.java │ │ └── SqliteHelp.java │ │ ├── getcks │ │ ├── MainActivity.java │ │ ├── StaticObj.java │ │ ├── browser │ │ │ ├── BrowserFragment.java │ │ │ ├── BrowserHandler.java │ │ │ └── BrowserViewModel.java │ │ ├── dialogs │ │ │ ├── QLConfigDialog.java │ │ │ └── WebDataDialog.java │ │ └── web │ │ │ ├── WebDataAdapter.java │ │ │ ├── WebFragment.java │ │ │ ├── WebHandler.java │ │ │ └── WebViewModel.java │ │ └── models │ │ ├── QLData.java │ │ └── WebData.java │ └── res │ ├── drawable │ ├── ic_launcher.png │ ├── ic_launcher_round.png │ ├── ico_browser.png │ ├── ico_delete.png │ ├── ico_edit.png │ └── ico_web.png │ ├── layout │ ├── activity_main.xml │ ├── fragment_browser.xml │ ├── fragment_web.xml │ ├── web_input_data.xml │ ├── web_input_qldata.xml │ └── web_listview_data.xml │ ├── menu │ ├── menu_browser.xml │ ├── menu_nav_bottom.xml │ └── menu_web.xml │ ├── navigation │ └── navigation_main.xml │ ├── values-en │ └── strings.xml │ ├── values-night │ ├── colors.xml │ └── themes.xml │ └── values │ ├── colors.xml │ ├── strings.xml │ └── themes.xml ├── build.gradle ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── imgs ├── 001.jpg ├── 002.jpg ├── 003.jpg ├── 004.jpg └── logo.png ├── php ├── README.md └── open │ ├── auth │ └── token.php │ ├── comm.php │ ├── envs.php │ └── envs │ └── enable.php └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # ---> Android 2 | # Gradle files 3 | .DS_Store 4 | .gradle/ 5 | build/ 6 | 7 | # Local configuration file (sdk path, etc) 8 | local.properties 9 | 10 | # Log/OS Files 11 | *.log 12 | 13 | # Android Studio generated files and folders 14 | captures/ 15 | .externalNativeBuild/ 16 | .cxx/ 17 | *.apk 18 | output.json 19 | 20 | # IntelliJ 21 | *.iml 22 | .idea/ 23 | 24 | # Keystore files 25 | *.jks 26 | *.keystore 27 | 28 | # Google Services (e.g. APIs or Firebase) 29 | google-services.json 30 | 31 | # Android Profiling 32 | *.hprof 33 | 34 | # ---> VisualStudioCode 35 | .vs/ 36 | .vscode/* 37 | !.vscode/settings.json 38 | !.vscode/tasks.json 39 | !.vscode/launch.json 40 | !.vscode/extensions.json 41 | !.vscode/*.code-snippets 42 | 43 | # Local History for Visual Studio Code 44 | .history/ 45 | 46 | # Built Visual Studio Code Extensions 47 | *.vsix 48 | 49 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 GetCookies by zgcwkjOpenProject 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Android_GetCookies 2 | 3 | 调用安卓内置浏览器,访问网站并获取Cookie。 4 | 5 | # 图片预览 6 | 7 | ![001](imgs/001.jpg?20250210) 8 | 9 | ![002](imgs/002.jpg?20250210) 10 | 11 | ![003](imgs/003.jpg?20250210) 12 | 13 | ![004](imgs/004.jpg?20250210) 14 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /debug 3 | /release 4 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libs.plugins.androidApplication) 3 | } 4 | 5 | android { 6 | namespace 'com.zgcwkj.getcks' 7 | compileSdk 34 8 | 9 | defaultConfig { 10 | applicationId "com.zgcwkj.getcks" 11 | minSdk 23 12 | targetSdk 34 13 | versionCode 25021301 14 | versionName "1.1" 15 | } 16 | 17 | buildTypes { 18 | release { 19 | // 代码混淆 20 | minifyEnabled true 21 | 22 | // 移除没用的资源文件 23 | shrinkResources true 24 | 25 | // 关闭调试选项 26 | debuggable false 27 | 28 | // Includes the default ProGuard rules files that are packaged with 29 | // the Android Gradle plugin. To learn more, go to the section about 30 | // R8 configuration files. 31 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 32 | } 33 | } 34 | 35 | signingConfigs { 36 | debug { 37 | v1SigningEnabled true 38 | v2SigningEnabled true 39 | } 40 | release { 41 | v1SigningEnabled true 42 | v2SigningEnabled true 43 | } 44 | } 45 | 46 | packagingOptions { 47 | exclude "DebugProbesKt.bin" 48 | } 49 | 50 | compileOptions { 51 | sourceCompatibility JavaVersion.VERSION_17 52 | targetCompatibility JavaVersion.VERSION_17 53 | } 54 | } 55 | 56 | dependencies { 57 | implementation libs.material 58 | implementation libs.navigation.ui 59 | implementation libs.navigation.fragment 60 | implementation libs.okhttps.gson 61 | } 62 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | 23 | # Gson 反射结构 24 | -keepattributes Signature 25 | -keep class com.google.gson.reflect.TypeToken { *; } 26 | -keep class * extends com.google.gson.reflect.TypeToken 27 | -keepattributes AnnotationDefault,RuntimeVisibleAnnotations 28 | 29 | # 数据实体对象结构 30 | -keep class com.zgcwkj.models.** { *; } 31 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 15 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/zgcwkj/bllcode/CommonHelp.java: -------------------------------------------------------------------------------- 1 | package com.zgcwkj.bllcode; 2 | 3 | import android.content.ClipData; 4 | import android.content.ClipboardManager; 5 | import android.content.Context; 6 | import android.os.Handler; 7 | 8 | import com.zgcwkj.getcks.StaticObj; 9 | 10 | import java.io.File; 11 | import java.io.FileInputStream; 12 | import java.io.FileOutputStream; 13 | import java.io.IOException; 14 | import java.math.BigInteger; 15 | import java.security.MessageDigest; 16 | import java.security.NoSuchAlgorithmException; 17 | 18 | public class CommonHelp { 19 | 20 | //复制到剪切板 21 | public static void copyToClipboard(Context context, String text, Handler handler) { 22 | text = text.trim(); 23 | var clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); 24 | var clip = ClipData.newPlainText("label", text); 25 | clipboard.setPrimaryClip(clip); 26 | //发送消息 27 | if (handler != null) { 28 | StaticObj.sendMsg(handler, 1); 29 | } 30 | } 31 | 32 | //获取Data目录 33 | public static String getDataPath(Context context) { 34 | var dataDir = context.getDataDir(); 35 | var appDataDirPath = dataDir.getAbsolutePath(); 36 | return appDataDirPath; 37 | } 38 | 39 | //复制文件 40 | public static boolean copyFile(String oldPath, String newPath) { 41 | try { 42 | var oldFile = new File(oldPath); 43 | var oldFileIs = new FileInputStream(oldFile); 44 | var newFile = new File(newPath); 45 | var deleteCkOk = newFile.delete();//删除目标位置的文件 46 | var newFileOs = new FileOutputStream(newFile); 47 | var buffer = new byte[1024]; 48 | int length; 49 | while ((length = oldFileIs.read(buffer)) > 0) { 50 | newFileOs.write(buffer, 0, length); 51 | } 52 | if (oldFileIs != null) oldFileIs.close(); 53 | if (newFileOs != null) newFileOs.close(); 54 | } catch (IOException e) { 55 | return false; 56 | } 57 | return true; 58 | } 59 | 60 | //删除文件夹(递归) 61 | public static boolean deleteFiles(File folder) { 62 | if (folder != null && folder.isDirectory()) { 63 | var files = folder.listFiles(); 64 | if (files != null) { 65 | for (var file : files) { 66 | if (file.isDirectory()) { 67 | //递归调用删除子文件夹 68 | deleteFiles(file); 69 | } else { 70 | file.delete(); 71 | } 72 | } 73 | } 74 | return folder.delete(); 75 | } 76 | return false; 77 | } 78 | 79 | //获取MD5值 80 | public static String getMd5(String value) { 81 | var valueMd5 = "zgcwkj"; 82 | try { 83 | var md = MessageDigest.getInstance("MD5"); 84 | md.update(value.getBytes()); 85 | valueMd5 = new BigInteger(1, md.digest()).toString(16); 86 | } catch (NoSuchAlgorithmException e) { 87 | } 88 | return valueMd5; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /app/src/main/java/com/zgcwkj/bllcode/CookieHep.java: -------------------------------------------------------------------------------- 1 | package com.zgcwkj.bllcode; 2 | 3 | import android.content.Context; 4 | import android.os.Handler; 5 | import android.webkit.CookieManager; 6 | import android.widget.Toast; 7 | 8 | import com.zgcwkj.getcks.StaticObj; 9 | import com.zgcwkj.models.WebData; 10 | 11 | import java.io.File; 12 | import java.util.ArrayList; 13 | 14 | public class CookieHep { 15 | //获取 Cookie 16 | public static String getCookie(Context context, WebData data, Handler handler) { 17 | var isCopy = false; 18 | if (data == null || data.getId().isEmpty()) { 19 | isCopy = true; 20 | data = SqliteHelp.GetWebData(); 21 | } 22 | //浏览器的CK 23 | var cookieManager = CookieManager.getInstance(); 24 | cookieManager.setAcceptCookie(true); 25 | var cookieStr = cookieManager.getCookie(data.getWeburl()); 26 | if (cookieStr == null) cookieStr = ""; 27 | if (cookieStr.isEmpty() && !isCopy) return ""; 28 | var cookies = cookieStr.split(";"); 29 | //准备数据 30 | var getCookieKey = data.getCookiekey(); 31 | if (!getCookieKey.equals("")) { 32 | var cookieStrBuilder = new StringBuilder(); 33 | //要取出匹配Cookie的值 34 | var cookieKeys = getCookieKey.split(";"); 35 | for (var cookieKey : cookieKeys) {//要匹配的Key 36 | cookieKey = cookieKey.trim();//前后去空格 37 | if (cookieKey.isEmpty()) continue; 38 | var matched = false;//记录是否被匹配到 39 | for (var item : cookies) {//存储的CK 40 | item = item.trim();//前后去空格 41 | if (item.isEmpty()) continue; 42 | var leftKey = item.split("="); 43 | if (leftKey.length > 0 && leftKey[0].equals(cookieKey)) { 44 | cookieStrBuilder.append(item).append(";"); 45 | matched = true; 46 | break; 47 | } 48 | } 49 | //匹配不到时,直接存储到要推送的记录里 50 | if (!matched) { 51 | cookieStrBuilder.append(cookieKey).append(";"); 52 | } 53 | } 54 | cookieStr = cookieStrBuilder.toString(); 55 | } 56 | //清理两端空格 57 | cookieStr = cookieStr.trim(); 58 | //是否复制 59 | if (isCopy) { 60 | //将内容复制到剪切板 61 | if (!cookieStr.isEmpty()) { 62 | //显示 63 | StaticObj.dialogLoading = DialogLoading.build(context); 64 | StaticObj.dialogLoading.show(); 65 | var qlData = QLongHelp.getData(context); 66 | if (qlData.getWeburl().isEmpty()) { 67 | //传到剪切板 68 | CommonHelp.copyToClipboard(context, cookieStr, handler); 69 | } else { 70 | //传到青龙 71 | QLongHelp.saveCookie(context, qlData, cookieStr, data.getRemark(), handler); 72 | } 73 | } else { 74 | Toast.makeText(context, "内容为空", Toast.LENGTH_SHORT).show(); 75 | } 76 | } 77 | //返回状态 78 | return cookieStr; 79 | } 80 | 81 | //设置Cookie 82 | public static boolean setCookie(Context context, WebData data) { 83 | //选中新数据 84 | data.setIsselect(true); 85 | SqliteHelp.SaveWebData(data); 86 | //返回状态 87 | return true; 88 | } 89 | 90 | //清楚无关的缓存 91 | public static boolean clearHistory(Context context) { 92 | var dataPath = CommonHelp.getDataPath(context); 93 | var keyList = new ArrayList(); 94 | var dataList = SqliteHelp.GetWebDatas(); 95 | for (var item : dataList) { 96 | var dataKey = CommonHelp.getMd5(item.getId()); 97 | keyList.add("app_webview_" + dataKey); 98 | } 99 | var dataDir = new File(dataPath); 100 | if (dataDir.exists() && dataDir.isDirectory()) { 101 | // 遍历数据目录 102 | var files = dataDir.listFiles(); 103 | if (files == null) return false; 104 | for (var file : files) { 105 | if (file.isDirectory()) { 106 | var fileName = file.getName(); 107 | if (fileName.contains("app_webview_")) { 108 | if (!keyList.contains(file.getName())) { 109 | //递归删除文件夹 110 | CommonHelp.deleteFiles(file); 111 | } 112 | } 113 | } 114 | } 115 | return true; 116 | } 117 | return false; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /app/src/main/java/com/zgcwkj/bllcode/DialogLoading.java: -------------------------------------------------------------------------------- 1 | package com.zgcwkj.bllcode; 2 | 3 | import android.app.AlertDialog; 4 | import android.content.Context; 5 | import android.graphics.Color; 6 | import android.view.Gravity; 7 | import android.view.ViewGroup; 8 | import android.view.WindowManager; 9 | import android.widget.LinearLayout; 10 | import android.widget.ProgressBar; 11 | import android.widget.TextView; 12 | 13 | import com.zgcwkj.getcks.R; 14 | 15 | /** 16 | * 加载层 17 | */ 18 | public class DialogLoading { 19 | private final Context mContext; 20 | public boolean start = false; 21 | private AlertDialog dialog; 22 | 23 | public DialogLoading(Context mContext) { 24 | this.mContext = mContext; 25 | } 26 | 27 | /** 28 | * 获取一个单例 29 | */ 30 | public static DialogLoading build(Context mContext) { 31 | var dialogLoading = new DialogLoading(mContext); 32 | return dialogLoading; 33 | } 34 | 35 | /** 36 | * 显示 37 | */ 38 | public void show() { 39 | //防止重复弹出 40 | if (start) return; 41 | start = true; 42 | //弹窗 43 | var llPadding = 30; 44 | var ll = new LinearLayout(mContext); 45 | ll.setOrientation(LinearLayout.HORIZONTAL); 46 | ll.setPadding(llPadding, llPadding, llPadding, llPadding); 47 | ll.setGravity(Gravity.CENTER); 48 | LinearLayout.LayoutParams llParam = new LinearLayout.LayoutParams( 49 | LinearLayout.LayoutParams.WRAP_CONTENT, 50 | LinearLayout.LayoutParams.WRAP_CONTENT); 51 | llParam.gravity = Gravity.CENTER; 52 | ll.setLayoutParams(llParam); 53 | // 54 | var progressBar = new ProgressBar(mContext); 55 | progressBar.setIndeterminate(true); 56 | progressBar.setPadding(0, 0, llPadding, 0); 57 | progressBar.setLayoutParams(llParam); 58 | // 59 | llParam = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 60 | ViewGroup.LayoutParams.WRAP_CONTENT); 61 | llParam.gravity = Gravity.CENTER; 62 | var tvText = new TextView(mContext); 63 | tvText.setText(R.string.appLoading); 64 | tvText.setTextColor(Color.parseColor("#000000")); 65 | tvText.setTextSize(20); 66 | tvText.setLayoutParams(llParam); 67 | // 68 | ll.addView(progressBar); 69 | ll.addView(tvText); 70 | // 71 | var builder = new AlertDialog.Builder(mContext); 72 | builder.setCancelable(true); 73 | builder.setView(ll); 74 | //捕获按钮事件 75 | builder.setOnKeyListener((dialogInterface, keyCode, keyEvent) -> { 76 | return true; 77 | }); 78 | // 79 | dialog = builder.create(); 80 | dialog.setCanceledOnTouchOutside(false); 81 | dialog.show(); 82 | var window = dialog.getWindow(); 83 | if (window != null) { 84 | var layoutParams = new WindowManager.LayoutParams(); 85 | layoutParams.copyFrom(dialog.getWindow().getAttributes()); 86 | layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT; 87 | layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT; 88 | dialog.getWindow().setAttributes(layoutParams); 89 | } 90 | } 91 | 92 | /** 93 | * 关闭 94 | */ 95 | public void close() { 96 | //防止重复弹出 97 | start = false; 98 | //关闭 99 | dialog.dismiss(); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /app/src/main/java/com/zgcwkj/bllcode/QLongHelp.java: -------------------------------------------------------------------------------- 1 | package com.zgcwkj.bllcode; 2 | 3 | import android.content.Context; 4 | import android.os.Handler; 5 | 6 | import com.google.gson.Gson; 7 | import com.zgcwkj.getcks.StaticObj; 8 | import com.zgcwkj.models.QLData; 9 | 10 | import java.io.BufferedReader; 11 | import java.io.File; 12 | import java.io.FileReader; 13 | import java.io.FileWriter; 14 | import java.io.IOException; 15 | 16 | import cn.zhxu.okhttps.HTTP; 17 | import cn.zhxu.okhttps.OkHttps; 18 | import cn.zhxu.okhttps.gson.GsonMsgConvertor; 19 | 20 | public class QLongHelp { 21 | 22 | //获取青龙配置文件 23 | private static File getConfigFile(Context context) { 24 | var dataPath = CommonHelp.getDataPath(context); 25 | var file = new File(dataPath + "/qlData.json"); 26 | return file; 27 | } 28 | 29 | //获取青龙配置 30 | public static QLData getData(Context context) { 31 | try { 32 | var file = getConfigFile(context); 33 | var json = new StringBuilder(); 34 | var br = new BufferedReader(new FileReader(file)); 35 | var line = ""; 36 | while ((line = br.readLine()) != null) { 37 | json.append(line); 38 | json.append('\n'); 39 | } 40 | var data = new Gson().fromJson(json.toString(), QLData.class); 41 | return data; 42 | } catch (Exception e) { 43 | } 44 | return new QLData(); 45 | } 46 | 47 | //保存青龙配置 48 | public static boolean setData(Context context, QLData data) { 49 | try { 50 | var file = getConfigFile(context); 51 | var json = new Gson().toJson(data); 52 | var writer = new FileWriter(file); 53 | writer.write(json); 54 | writer.close(); 55 | } catch (IOException e) { 56 | return false; 57 | } 58 | return true; 59 | } 60 | 61 | //清空青龙配置 62 | public static boolean clearData(Context context) { 63 | var file = getConfigFile(context); 64 | return file.delete(); 65 | } 66 | 67 | //保存到青龙平台 68 | public static void saveCookie(Context context, QLData qlData, String ck, String remark, Handler handler) { 69 | new Thread(() -> { 70 | var msgWhat = 0; 71 | try { 72 | //获取Token 73 | var http = HTTP.builder().addMsgConvertor(new GsonMsgConvertor()).build(); 74 | var url = qlData.getWeburl() + "/open/auth/token?"; 75 | url += "client_id=" + qlData.getClientId() + "&client_secret=" + qlData.getClientSecret(); 76 | var data1 = http.sync(url).get().getBody().toMapper(); 77 | if (data1.getInt("code") != 200) { 78 | StaticObj.sendMsg(handler, 3);//推送失败 79 | return; 80 | } 81 | var token = data1.getMapper("data").getString("token"); 82 | //从记录中获取匹配备注的记录 83 | url = qlData.getWeburl() + "/open/envs"; 84 | var data2 = http.sync(url).addHeader("Authorization", "Bearer " + token).get().getBody().toMapper(); 85 | if (data2.getInt("code") != 200) { 86 | StaticObj.sendMsg(handler, 3);//推送失败 87 | return; 88 | } 89 | var envId = 0; 90 | var envName = "NotName"; 91 | var envList = data2.getArray("data"); 92 | for (var i = 0; i < envList.size(); i++) { 93 | var envData = envList.getMapper(i); 94 | var remarks = envData.getString("remarks"); 95 | if (remarks != null && remarks.equals(remark)) { 96 | envId = envData.getInt("id"); 97 | envName = envData.getString("name"); 98 | break; 99 | } 100 | } 101 | //把记录提交到青龙 102 | if (envId == 0) { 103 | //新增 104 | var saveData = "[{'value':'" + ck + "','name':'" + envName + "','remarks':'" + remark + "'}]"; 105 | saveData = saveData.replaceAll("'", "\""); 106 | var rdata = http.async(url).addHeader("Authorization", "Bearer " + token).bodyType(OkHttps.JSON).setBodyPara(saveData).post(); 107 | } else { 108 | //修改 109 | var saveData = "{'value':'" + ck + "','name':'" + envName + "','remarks':'" + remark + "','id':" + envId + "}"; 110 | saveData = saveData.replaceAll("'", "\""); 111 | var rdata = http.async(url).addHeader("Authorization", "Bearer " + token).bodyType(OkHttps.JSON).setBodyPara(saveData).put(); 112 | //启用环境变量 113 | if (qlData.getAutoEnable()) { 114 | url = qlData.getWeburl() + "/open/envs/enable"; 115 | var enableData = "[" + envId + "]"; 116 | var r2data = http.async(url).addHeader("Authorization", "Bearer " + token).bodyType(OkHttps.JSON).setBodyPara(enableData).put(); 117 | } 118 | } 119 | msgWhat = 4;//推送成功 120 | } catch (Exception ex) { 121 | msgWhat = 3;//推送失败 122 | } 123 | //发送消息 124 | if (handler != null) { 125 | StaticObj.sendMsg(handler, msgWhat); 126 | } 127 | }).start(); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /app/src/main/java/com/zgcwkj/bllcode/SqliteHelp.java: -------------------------------------------------------------------------------- 1 | package com.zgcwkj.bllcode; 2 | 3 | import android.content.ContentValues; 4 | import android.content.Context; 5 | import android.database.Cursor; 6 | import android.database.sqlite.SQLiteDatabase; 7 | import android.database.sqlite.SQLiteOpenHelper; 8 | 9 | import com.zgcwkj.models.WebData; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | import java.util.UUID; 14 | 15 | public class SqliteHelp extends SQLiteOpenHelper { 16 | private static SqliteHelp sqliteHelp; 17 | 18 | public SqliteHelp(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { 19 | super(context, name, factory, version); 20 | } 21 | 22 | //初始化数据库 23 | public static SqliteHelp initDb(Context context) { 24 | //创建数据库 25 | if (sqliteHelp == null) { 26 | sqliteHelp = new SqliteHelp(context, "web_app.db", null, 1); 27 | } 28 | var db = sqliteHelp.getReadableDatabase(); 29 | //升级数据库 30 | updateDb(db); 31 | //返回对象 32 | return sqliteHelp; 33 | } 34 | 35 | //更新数据库 36 | private static void updateDb(SQLiteDatabase db) { 37 | String sqlStr; 38 | //检查表1 39 | sqlStr = "PRAGMA table_info(web_data)"; 40 | var cursorA = db.rawQuery(sqlStr, null); 41 | if (cursorA != null) { 42 | //检查列 43 | var columnIndex = cursorA.getColumnIndex("name"); 44 | var columnGet = false; 45 | while (cursorA.moveToNext()) { 46 | var colName = cursorA.getString(columnIndex); 47 | if (colName.equals("cookieisolate")) columnGet = true; 48 | } 49 | //创建列 50 | if (!columnGet) { 51 | sqlStr = "ALTER TABLE web_data ADD COLUMN cookieisolate BOOLEAN DEFAULT 0"; 52 | db.execSQL(sqlStr); 53 | } 54 | } 55 | //检查表2 56 | sqlStr = "PRAGMA table_info(web_data)"; 57 | var cursorB = db.rawQuery(sqlStr, null); 58 | if (cursorB != null) { 59 | //检查列 60 | var columnIndex = cursorB.getColumnIndex("name"); 61 | var columnGet = false; 62 | while (cursorB.moveToNext()) { 63 | var colName = cursorB.getString(columnIndex); 64 | if (colName.equals("userAgent")) columnGet = true; 65 | } 66 | //创建列 67 | if (!columnGet) { 68 | sqlStr = "ALTER TABLE web_data ADD COLUMN userAgent TEXT DEFAULT ''"; 69 | db.execSQL(sqlStr); 70 | } 71 | } 72 | } 73 | 74 | //获取所有记录 75 | public static List GetWebDatas() { 76 | var db = sqliteHelp.getReadableDatabase(); 77 | if (!db.isOpen()) return new ArrayList<>(); 78 | var cursor = db.rawQuery("select * from web_data", null); 79 | var dataList = getCursorWebData(cursor); 80 | return dataList; 81 | } 82 | 83 | //获取选中记录 84 | public static WebData GetWebData() { 85 | var data = new WebData(true); 86 | var db = sqliteHelp.getReadableDatabase(); 87 | if (!db.isOpen()) return data; 88 | var cursor = db.rawQuery("select * from web_data where isselect = 1", null); 89 | var dataList = getCursorWebData(cursor); 90 | data = dataList.get(0); 91 | return data; 92 | } 93 | 94 | //获取网站数据 95 | private static List getCursorWebData(Cursor cursor) { 96 | List dataList = new ArrayList<>(); 97 | while (cursor.moveToNext()) { 98 | var idIndex = cursor.getColumnIndex("id"); 99 | var id = cursor.getString(idIndex); 100 | var weburlIndex = cursor.getColumnIndex("weburl"); 101 | var weburl = cursor.getString(weburlIndex); 102 | var cookieIndex = cursor.getColumnIndex("cookie"); 103 | var cookie = cursor.getString(cookieIndex); 104 | var cookiekeyIndex = cursor.getColumnIndex("cookiekey"); 105 | var cookiekey = cursor.getString(cookiekeyIndex); 106 | var cookieisolateIndex = cursor.getColumnIndex("cookieisolate"); 107 | var cookieisolate = cursor.getInt(cookieisolateIndex) > 0; 108 | var userAgentIndex = cursor.getColumnIndex("userAgent"); 109 | var userAgent = cursor.getString(userAgentIndex); 110 | var remarkIndex = cursor.getColumnIndex("remark"); 111 | var remark = cursor.getString(remarkIndex); 112 | var isselectIndex = cursor.getColumnIndex("isselect"); 113 | var isselect = cursor.getInt(isselectIndex) > 0; 114 | dataList.add(new WebData(isselect, weburl, cookie, cookiekey, cookieisolate, userAgent, remark, id)); 115 | } 116 | return dataList; 117 | } 118 | 119 | //保存记录 120 | public static void SaveWebData(WebData data) { 121 | var db = sqliteHelp.getWritableDatabase(); 122 | if (!db.isOpen()) return; 123 | //参数 124 | var values = new ContentValues(); 125 | values.put("weburl", data.getWeburl()); 126 | values.put("cookie", data.getCookie()); 127 | values.put("cookiekey", data.getCookiekey()); 128 | values.put("cookieisolate", data.getCookieIsolate()); 129 | values.put("remark", data.getRemark()); 130 | values.put("userAgent", data.getUserAgent()); 131 | values.put("isselect", data.getIsselect()); 132 | if (!ExistWebData(data)) { 133 | //新增 134 | var id = UUID.randomUUID().toString(); 135 | data.setId(id); 136 | values.put("id", data.getId()); 137 | db.insert("web_data", null, values); 138 | } else { 139 | //修改 140 | db.update("web_data", values, "id = @id", new String[]{data.getId()}); 141 | } 142 | //选择记录 143 | if (data.getIsselect()) { 144 | //全部变成未选择 145 | db.execSQL("update web_data set isselect = 0"); 146 | //标记选择的 147 | db.execSQL("update web_data set isselect = 1 where id = @id", new String[]{data.getId()}); 148 | } 149 | } 150 | 151 | //删除记录 152 | public static void DelWebData(WebData data) { 153 | var db = sqliteHelp.getWritableDatabase(); 154 | if (!db.isOpen()) return; 155 | db.execSQL("delete from web_data where id = @id", new Object[]{data.getId()}); 156 | } 157 | 158 | //是否存在记录 159 | public static boolean ExistWebData(WebData data) { 160 | var db = sqliteHelp.getReadableDatabase(); 161 | if (!db.isOpen()) return false; 162 | var cursor = db.rawQuery("select * from web_data where id = @id", new String[]{data.getId()}); 163 | return cursor.getCount() > 0; 164 | } 165 | 166 | //初始化数据库时创建数据 167 | public static void addWebData(WebData data, SQLiteDatabase db) { 168 | var sql = """ 169 | insert into web_data(id,weburl,cookie,cookiekey,cookieisolate,userAgent,remark,isselect) 170 | values(@id,@weburl,@cookie,@cookiekey,@cookieisolate,@userAgent,@remark,@isselect) 171 | """; 172 | var id = UUID.randomUUID().toString(); 173 | db.execSQL(sql, new Object[]{id, data.getWeburl(), 174 | data.getCookie(), data.getCookiekey(), data.getCookieIsolate(), 175 | data.getUserAgent(), data.getRemark(), data.getIsselect()}); 176 | } 177 | 178 | //初始化数据库 179 | @Override 180 | public void onCreate(SQLiteDatabase db) { 181 | //创建表结构 182 | var sql = """ 183 | CREATE TABLE web_data (id TEXT PRIMARY KEY,weburl TEXT,cookie TEXT,cookiekey TEXT,cookieisolate BOOLEAN, 184 | userAgent TEXT,remark TEXT,isselect BOOLEAN); 185 | """; 186 | db.execSQL(sql); 187 | //默认数据 188 | var data1 = new WebData(true, "http://www.zgcwkj.cn", "ck1;ck2;", false, "示例"); 189 | addWebData(data1, db); 190 | //默认数据 191 | var data2 = new WebData(false, "https://github.com/zgcwkjOpenProject/Android_GetCookies", "", false, "开源地址"); 192 | addWebData(data2, db); 193 | //默认数据 194 | var data3 = new WebData(false, "https://plogin.m.jd.com/login/login/", "pt_pin;pt_key;", false, "京东CK"); 195 | addWebData(data3, db); 196 | //默认数据 197 | var data4 = new WebData(false, "https://plogin.m.jd.com/login/login/", "pt_pin;pt_key;", true, "京东CK2"); 198 | addWebData(data4, db); 199 | //默认数据 200 | var data5 = new WebData(false, "https://h5.ele.me/login/", "unb;cookie2;USERID;SID;", false, "饿了么CK"); 201 | addWebData(data5, db); 202 | } 203 | 204 | @Override 205 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /app/src/main/java/com/zgcwkj/getcks/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.zgcwkj.getcks; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Build; 6 | import android.os.Bundle; 7 | import android.view.KeyEvent; 8 | import android.webkit.WebView; 9 | import android.widget.Toast; 10 | 11 | import androidx.appcompat.app.AppCompatActivity; 12 | import androidx.navigation.Navigation; 13 | import androidx.navigation.ui.AppBarConfiguration; 14 | import androidx.navigation.ui.NavigationUI; 15 | 16 | import com.google.android.material.bottomnavigation.BottomNavigationView; 17 | import com.zgcwkj.bllcode.CommonHelp; 18 | import com.zgcwkj.bllcode.CookieHep; 19 | import com.zgcwkj.bllcode.SqliteHelp; 20 | 21 | public class MainActivity extends AppCompatActivity { 22 | public static MainActivity activity;//程序活动 23 | private long exitTime = 0;//退出计时 24 | private Context mContext; 25 | 26 | @Override 27 | protected void onCreate(Bundle savedInstanceState) { 28 | activity = this; 29 | mContext = getApplicationContext(); 30 | //数据库 31 | SqliteHelp.initDb(this); 32 | //隔离浏览器数据 33 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { 34 | //清除无用的历史数据 35 | CookieHep.clearHistory(mContext); 36 | //创建隔离环境 37 | var data = SqliteHelp.GetWebData(); 38 | if (data.getCookieIsolate()) { 39 | var dataKey = CommonHelp.getMd5(data.getId()); 40 | WebView.setDataDirectorySuffix(dataKey); 41 | StaticObj.dataDirectorySuffix = dataKey; 42 | } 43 | } 44 | //允许浏览器调试 45 | WebView.setWebContentsDebuggingEnabled(true); 46 | // 47 | super.onCreate(savedInstanceState); 48 | setContentView(R.layout.activity_main); 49 | // 50 | var navView = (BottomNavigationView) findViewById(R.id.nav_view); 51 | //将每个菜单ID作为一组ID传递,因为每个菜单应被视为顶级目的地 52 | var appBarConfiguration = new AppBarConfiguration.Builder(R.id.navigation_browser, R.id.navigation_web).build(); 53 | var navController = Navigation.findNavController(this, R.id.nav_host_fragment); 54 | NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration); 55 | NavigationUI.setupWithNavController(navView, navController); 56 | } 57 | 58 | //监听按键事件 59 | @Override 60 | public boolean onKeyDown(int keyCode, KeyEvent event) { 61 | //按钮事件 62 | if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) { 63 | if ((System.currentTimeMillis() - exitTime) > 2000) { 64 | Toast.makeText(MainActivity.this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); 65 | exitTime = System.currentTimeMillis(); 66 | } else { 67 | finish(); 68 | System.exit(0); 69 | } 70 | return true; 71 | } 72 | //执行原有方法 73 | return super.onKeyDown(keyCode, event); 74 | } 75 | 76 | //重启应用 77 | public void restartApp() { 78 | final var intent = getPackageManager().getLaunchIntentForPackage(getPackageName()); 79 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 80 | startActivity(intent); 81 | //杀掉以前进程 82 | android.os.Process.killProcess(android.os.Process.myPid()); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /app/src/main/java/com/zgcwkj/getcks/StaticObj.java: -------------------------------------------------------------------------------- 1 | package com.zgcwkj.getcks; 2 | 3 | import android.os.Handler; 4 | 5 | import com.zgcwkj.bllcode.DialogLoading; 6 | import com.zgcwkj.getcks.dialogs.QLConfigDialog; 7 | import com.zgcwkj.getcks.dialogs.WebDataDialog; 8 | 9 | //静态对象 10 | public class StaticObj { 11 | //数据目录后缀 12 | public static String dataDirectorySuffix = ""; 13 | //加载弹窗 14 | public static DialogLoading dialogLoading; 15 | //输入信息弹窗 16 | public static WebDataDialog dialogInput; 17 | //输入信息弹窗2 18 | public static QLConfigDialog dialogInputQl; 19 | 20 | //发送消息 21 | public static void sendMsg(Handler handler, int msgWhat) { 22 | var iMsg = handler.obtainMessage(); 23 | iMsg.what = msgWhat; 24 | handler.sendMessage(iMsg); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/zgcwkj/getcks/browser/BrowserFragment.java: -------------------------------------------------------------------------------- 1 | package com.zgcwkj.getcks.browser; 2 | 3 | import android.app.AlertDialog; 4 | import android.os.Bundle; 5 | import android.os.Looper; 6 | import android.view.LayoutInflater; 7 | import android.view.Menu; 8 | import android.view.MenuInflater; 9 | import android.view.MenuItem; 10 | import android.view.View; 11 | import android.view.ViewGroup; 12 | import android.webkit.CookieManager; 13 | import android.webkit.WebView; 14 | import android.webkit.WebViewClient; 15 | 16 | import androidx.annotation.NonNull; 17 | import androidx.fragment.app.Fragment; 18 | import androidx.lifecycle.ViewModelProvider; 19 | 20 | import com.zgcwkj.bllcode.CommonHelp; 21 | import com.zgcwkj.bllcode.CookieHep; 22 | import com.zgcwkj.bllcode.QLongHelp; 23 | import com.zgcwkj.bllcode.SqliteHelp; 24 | import com.zgcwkj.getcks.MainActivity; 25 | import com.zgcwkj.getcks.R; 26 | import com.zgcwkj.getcks.StaticObj; 27 | import com.zgcwkj.models.WebData; 28 | 29 | public class BrowserFragment extends Fragment { 30 | public static BrowserHandler handler;//消息传递 31 | public BrowserViewModel viewModel;//页面模型 32 | 33 | public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 34 | var context = this.getContext(); 35 | //传递消息 36 | handler = new BrowserHandler(Looper.myLooper(), this); 37 | //视图模型 38 | viewModel = new ViewModelProvider(this).get(BrowserViewModel.class); 39 | //视图 40 | var view = inflater.inflate(R.layout.fragment_browser, container, false); 41 | //浏览器 42 | openWebUrl(view, false); 43 | //让系统知道有菜单项 44 | setHasOptionsMenu(true); 45 | //返回视图 46 | return view; 47 | } 48 | 49 | @Override 50 | public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 51 | inflater.inflate(R.menu.menu_browser, menu); 52 | //动态变换菜单按钮文字 53 | var qlData = QLongHelp.getData(getContext()); 54 | var btnGetCK = menu.findItem(R.id.browser_btnGetCK); 55 | if (qlData.getWeburl().isEmpty()) { 56 | btnGetCK.setTitle(R.string.menu_getCK1); 57 | } else { 58 | btnGetCK.setTitle(R.string.menu_getCK2); 59 | } 60 | //调用基类处理 61 | super.onCreateOptionsMenu(menu, inflater); 62 | } 63 | 64 | @Override 65 | public boolean onOptionsItemSelected(MenuItem item) { 66 | var view = getView(); 67 | var context = view.getContext(); 68 | var id = item.getItemId(); 69 | if (id == R.id.browser_btnGetCK) {//获取按钮 70 | CookieHep.getCookie(context, null, handler); 71 | return true; 72 | } else if (id == R.id.web_btnResetBrowser) {//重置浏览器按钮 73 | var builder = new AlertDialog.Builder(context); 74 | builder.setIcon(R.drawable.ic_launcher); 75 | builder.setTitle("确定重置浏览器吗?"); 76 | //设置按钮事件 77 | builder.setPositiveButton("确定", (dialog, which) -> { 78 | CookieManager.getInstance().removeAllCookies(null);//清除CK 79 | var mWebview = (WebView) view.findViewById(R.id.my_webview); 80 | mWebview.clearCache(true);//清除缓存数据 81 | mWebview.clearHistory();//清除历史数据 82 | mWebview.clearFormData();//清除表单数据 83 | mWebview.reload(); 84 | }); 85 | //设置按钮事件 86 | builder.setNegativeButton("取消", (dialog, which) -> { 87 | }); 88 | //显示对话框 89 | builder.show(); 90 | return true; 91 | } else if (id == R.id.browser_btnRefresh) {//刷新按钮 92 | openWebUrl(view, true); 93 | return true; 94 | } 95 | //调用基类处理 96 | return super.onOptionsItemSelected(item); 97 | } 98 | 99 | @Override 100 | public void onPause() { 101 | super.onPause(); 102 | } 103 | 104 | //打开网站(第一条数据) 105 | private WebData openWebUrl(View view, boolean isLoad) { 106 | var context = view.getContext(); 107 | var data = SqliteHelp.GetWebData(); 108 | if (data.getWeburl().isEmpty()) { 109 | var url = "http://zgcwkj.cn/"; 110 | data.setWeburl(url); 111 | var id = "00000000-0000-0000-0000-000000000000"; 112 | data.setId(id); 113 | } 114 | //检查是否需要重启 115 | var dataKey = CommonHelp.getMd5(data.getId()); 116 | if ((data.getCookieIsolate() && !dataKey.equals(StaticObj.dataDirectorySuffix)) || 117 | (!data.getCookieIsolate() && !StaticObj.dataDirectorySuffix.isEmpty())) { 118 | //显示对话框 119 | var builder = new AlertDialog.Builder(context); 120 | builder.setIcon(R.drawable.ic_launcher); 121 | builder.setCancelable(false); 122 | builder.setTitle("检测到环境变化,请点击重启应用!"); 123 | builder.setPositiveButton("重启", (dialog, which) -> { 124 | MainActivity.activity.restartApp(); 125 | }); 126 | builder.show(); 127 | } 128 | //浏览器 129 | var mWebview = (WebView) view.findViewById(R.id.my_webview); 130 | //配置浏览器客户端 131 | mWebview.setWebViewClient(new WebViewClient() { 132 | @Override 133 | public void onPageFinished(WebView view, String url) { 134 | CookieManager.getInstance().flush();//存储 Cookie 135 | } 136 | }); 137 | //刷新按钮时,清理缓存 138 | if (isLoad) { 139 | mWebview.clearHistory();//清除历史数据 140 | mWebview.clearFormData();//清除表单数据 141 | mWebview.clearCache(true);//清除缓存数据 142 | } 143 | var settings = mWebview.getSettings(); 144 | settings.setJavaScriptCanOpenWindowsAutomatically(false);//禁用新窗口 145 | settings.setJavaScriptEnabled(true);//允许执行js 146 | settings.setLoadWithOverviewMode(true);//启用自适应屏幕 147 | settings.setSupportZoom(false);//禁用缩放 148 | settings.setBuiltInZoomControls(false);//禁用显示缩放按钮 149 | settings.setUseWideViewPort(false);//禁用大视图模式 150 | settings.setDatabaseEnabled(false);//是否使用缓存 151 | settings.setDomStorageEnabled(true);//DOM存储 152 | //预览模式 153 | if (!data.getUserAgent().isEmpty()) { 154 | settings.setUserAgentString(data.getUserAgent());//用户代理 155 | settings.setLoadWithOverviewMode(false);//禁用自适应屏幕 156 | settings.setSupportZoom(true);//启用缩放 157 | settings.setBuiltInZoomControls(true);//显示缩放按钮 158 | mWebview.setInitialScale(50);//缩放比例 159 | } 160 | //打开网站 161 | mWebview.loadUrl(data.getWeburl()); 162 | return data; 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /app/src/main/java/com/zgcwkj/getcks/browser/BrowserHandler.java: -------------------------------------------------------------------------------- 1 | package com.zgcwkj.getcks.browser; 2 | 3 | import android.content.Context; 4 | import android.os.Handler; 5 | import android.os.Looper; 6 | import android.os.Message; 7 | import android.widget.Toast; 8 | 9 | import androidx.annotation.NonNull; 10 | 11 | import com.zgcwkj.getcks.StaticObj; 12 | 13 | import java.lang.ref.WeakReference; 14 | 15 | public class BrowserHandler extends Handler { 16 | WeakReference myActivity; 17 | 18 | public BrowserHandler(@NonNull Looper looper, BrowserFragment activity) { 19 | super(looper);//调用父类的显式指明的构造函数 20 | myActivity = new WeakReference(activity); 21 | } 22 | 23 | @Override 24 | public void handleMessage(Message msg) { 25 | super.handleMessage(msg); 26 | var nactivity = myActivity.get(); 27 | if (nactivity == null) return; 28 | Context context = nactivity.getContext(); 29 | //关闭加载弹窗 30 | StaticObj.dialogLoading.close(); 31 | switch (msg.what) { 32 | case 0: 33 | Toast.makeText(context, "操作失败", Toast.LENGTH_SHORT).show(); 34 | break; 35 | case 1: 36 | Toast.makeText(context, "内容已复制到剪切板", Toast.LENGTH_SHORT).show(); 37 | break; 38 | case 3: 39 | Toast.makeText(context, "失败,青龙配置异常", Toast.LENGTH_SHORT).show(); 40 | break; 41 | case 4: 42 | Toast.makeText(context, "内容已传输到青龙", Toast.LENGTH_SHORT).show(); 43 | break; 44 | default: 45 | break; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/com/zgcwkj/getcks/browser/BrowserViewModel.java: -------------------------------------------------------------------------------- 1 | package com.zgcwkj.getcks.browser; 2 | 3 | import androidx.lifecycle.ViewModel; 4 | 5 | public class BrowserViewModel extends ViewModel { 6 | public BrowserViewModel() { 7 | } 8 | } -------------------------------------------------------------------------------- /app/src/main/java/com/zgcwkj/getcks/dialogs/QLConfigDialog.java: -------------------------------------------------------------------------------- 1 | package com.zgcwkj.getcks.dialogs; 2 | 3 | import android.app.AlertDialog; 4 | import android.content.Context; 5 | import android.os.Handler; 6 | import android.view.View; 7 | import android.widget.Button; 8 | import android.widget.Switch; 9 | import android.widget.TextView; 10 | 11 | import com.zgcwkj.bllcode.DialogLoading; 12 | import com.zgcwkj.bllcode.QLongHelp; 13 | import com.zgcwkj.getcks.R; 14 | import com.zgcwkj.getcks.StaticObj; 15 | 16 | public class QLConfigDialog { 17 | private Context mContext;//上下文 18 | private AlertDialog dialog;//弹窗 19 | 20 | private QLConfigDialog() { 21 | } 22 | 23 | /** 24 | * 获取一个单例 25 | */ 26 | public static QLConfigDialog build(Context mContext) { 27 | StaticObj.dialogLoading = DialogLoading.build(mContext); 28 | var dialogInput = new QLConfigDialog(); 29 | dialogInput.mContext = mContext; 30 | return dialogInput; 31 | } 32 | 33 | /** 34 | * 显示 35 | */ 36 | public void show(Handler handler) { 37 | var data = QLongHelp.getData(mContext); 38 | //加载布局 39 | final var contentView = View.inflate(mContext, R.layout.web_input_qldata, null); 40 | //青龙平台地址 41 | var qlurl = (TextView) contentView.findViewById(R.id.web_inputData_qlurl); 42 | qlurl.setText(data.getWeburl()); 43 | //客户端ID 44 | var qlClientId = (TextView) contentView.findViewById(R.id.web_inputData_qlClientId); 45 | qlClientId.setText(data.getClientId()); 46 | //客户端密钥 47 | var qlClientSecret = (TextView) contentView.findViewById(R.id.web_inputData_qlClientSecret); 48 | qlClientSecret.setText(data.getClientSecret()); 49 | //自动启动变量 50 | var qlAutoEnable = (Switch) contentView.findViewById(R.id.web_inputData_qlAutoEnable); 51 | qlAutoEnable.setChecked(data.getAutoEnable()); 52 | //按钮 53 | var btnOk = (Button) contentView.findViewById(R.id.web_inputData_btnQlOk); 54 | var btnClear = (Button) contentView.findViewById(R.id.web_inputData_btnQlClear); 55 | var btnCancel = (Button) contentView.findViewById(R.id.web_inputData_btnQlCancel); 56 | //通过AlertDialog.Builder这个类来实例化我们的一个AlertDialog的对象 57 | var builder = new AlertDialog.Builder(mContext); 58 | //设置View来输入框 59 | builder.setView(contentView); 60 | //显示出该对话框 61 | dialog = builder.create(); 62 | dialog.setCanceledOnTouchOutside(false); 63 | dialog.show(); 64 | //确定按钮事件 65 | btnOk.setOnClickListener(arg -> { 66 | var isOK = false; 67 | StaticObj.dialogLoading.show(); 68 | if (!qlurl.getText().toString().trim().isEmpty()) { 69 | data.setWeburl(qlurl.getText().toString()); 70 | data.setClientId(qlClientId.getText().toString()); 71 | data.setClientSecret(qlClientSecret.getText().toString()); 72 | data.setAutoEnable(qlAutoEnable.isChecked()); 73 | QLongHelp.setData(mContext, data); 74 | isOK = true; 75 | } 76 | //发送消息 77 | StaticObj.sendMsg(handler, (isOK ? 11 : 0)); 78 | }); 79 | //清空按钮事件 80 | btnClear.setOnClickListener(arg -> { 81 | StaticObj.dialogLoading.show(); 82 | //清空数据 83 | var isOK = QLongHelp.clearData(mContext); 84 | isOK = true; 85 | //发送消息 86 | StaticObj.sendMsg(handler, (isOK ? 11 : 0)); 87 | //关闭弹窗 88 | close(); 89 | }); 90 | //取消按钮事件 91 | btnCancel.setOnClickListener(arg -> { 92 | close(); 93 | }); 94 | } 95 | 96 | /** 97 | * 关闭 98 | */ 99 | public void close() { 100 | dialog.dismiss(); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /app/src/main/java/com/zgcwkj/getcks/dialogs/WebDataDialog.java: -------------------------------------------------------------------------------- 1 | package com.zgcwkj.getcks.dialogs; 2 | 3 | import android.app.AlertDialog; 4 | import android.content.Context; 5 | import android.os.Build; 6 | import android.os.Handler; 7 | import android.view.View; 8 | import android.widget.Button; 9 | import android.widget.Switch; 10 | import android.widget.TextView; 11 | 12 | import com.zgcwkj.bllcode.CookieHep; 13 | import com.zgcwkj.bllcode.DialogLoading; 14 | import com.zgcwkj.bllcode.SqliteHelp; 15 | import com.zgcwkj.getcks.R; 16 | import com.zgcwkj.getcks.StaticObj; 17 | import com.zgcwkj.models.WebData; 18 | 19 | public class WebDataDialog { 20 | private Context mContext;//上下文 21 | private AlertDialog dialog;//弹窗 22 | 23 | private WebDataDialog() { 24 | } 25 | 26 | //获取一个单例 27 | public static WebDataDialog build(Context mContext) { 28 | StaticObj.dialogLoading = DialogLoading.build(mContext); 29 | var dialogInput = new WebDataDialog(); 30 | dialogInput.mContext = mContext; 31 | return dialogInput; 32 | } 33 | 34 | //显示 35 | public void show(Handler handler) { 36 | var data = new WebData(false); 37 | show(data, handler); 38 | } 39 | 40 | //显示 41 | public void show(WebData data, Handler handler) { 42 | //加载布局 43 | final var contentView = View.inflate(mContext, R.layout.web_input_data, null); 44 | var context = contentView.getContext(); 45 | //Url 46 | var ipWeburl = (TextView) contentView.findViewById(R.id.web_inputData_weburl); 47 | ipWeburl.setText(data.getWeburl()); 48 | //CKK 49 | var ipCookiekey = (TextView) contentView.findViewById(R.id.web_inputData_cookiekey); 50 | ipCookiekey.setText(data.getCookiekey()); 51 | //CKKData 52 | if (!data.getWeburl().isEmpty() && data.getIsselect()) { 53 | //CK 54 | var ipCookie = (TextView) contentView.findViewById(R.id.web_inputData_cookie); 55 | var getCKK = CookieHep.getCookie(mContext, data, null); 56 | ipCookie.setText(getCKK); 57 | } 58 | //用户代理 59 | var ipUserAgent = (TextView) contentView.findViewById(R.id.web_inputData_userAgent); 60 | ipUserAgent.setText(data.getUserAgent()); 61 | //备注 62 | var ipRemark = (TextView) contentView.findViewById(R.id.web_inputData_remark); 63 | ipRemark.setText(data.getRemark()); 64 | //数据隔离 65 | var ipCookieIsolate = (Switch) contentView.findViewById(R.id.web_inputData_cookieIsolate); 66 | ipCookieIsolate.setChecked(data.getCookieIsolate()); 67 | //不支持的系统版本隐藏,安卓9 68 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { 69 | ipCookieIsolate.setVisibility(View.GONE); 70 | } 71 | //按钮 72 | var btnOk = (Button) contentView.findViewById(R.id.web_inputData_btnOk); 73 | var btnCancel = (Button) contentView.findViewById(R.id.web_inputData_btnCancel); 74 | //通过AlertDialog.Builder这个类来实例化我们的一个AlertDialog的对象 75 | var builder = new AlertDialog.Builder(mContext); 76 | //设置View来输入框 77 | builder.setView(contentView); 78 | //显示出该对话框 79 | dialog = builder.create(); 80 | dialog.setCanceledOnTouchOutside(false); 81 | dialog.show(); 82 | //确定按钮事件 83 | btnOk.setOnClickListener(arg -> { 84 | var isOK = false; 85 | StaticObj.dialogLoading.show(); 86 | if (!ipWeburl.getText().toString().trim().isEmpty() 87 | && !ipRemark.getText().toString().isEmpty()) { 88 | data.setWeburl(ipWeburl.getText().toString()); 89 | data.setCookiekey(ipCookiekey.getText().toString()); 90 | data.setUserAgent(ipUserAgent.getText().toString()); 91 | data.setRemark(ipRemark.getText().toString()); 92 | data.setCookieIsolate(ipCookieIsolate.isChecked()); 93 | SqliteHelp.SaveWebData(data); 94 | isOK = true; 95 | } 96 | //发送消息 97 | StaticObj.sendMsg(handler, (isOK ? 1 : 0)); 98 | }); 99 | //取消按钮事件 100 | btnCancel.setOnClickListener(arg -> { 101 | close(); 102 | }); 103 | } 104 | 105 | //关闭 106 | public void close() { 107 | dialog.dismiss(); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /app/src/main/java/com/zgcwkj/getcks/web/WebDataAdapter.java: -------------------------------------------------------------------------------- 1 | package com.zgcwkj.getcks.web; 2 | 3 | import android.app.AlertDialog; 4 | import android.graphics.Color; 5 | import android.os.Handler; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.ArrayAdapter; 10 | import android.widget.Button; 11 | import android.widget.LinearLayout; 12 | import android.widget.TextView; 13 | 14 | import com.zgcwkj.bllcode.CookieHep; 15 | import com.zgcwkj.bllcode.DialogLoading; 16 | import com.zgcwkj.bllcode.SqliteHelp; 17 | import com.zgcwkj.getcks.R; 18 | import com.zgcwkj.getcks.StaticObj; 19 | import com.zgcwkj.getcks.dialogs.WebDataDialog; 20 | import com.zgcwkj.models.WebData; 21 | 22 | import java.util.List; 23 | 24 | public class WebDataAdapter extends ArrayAdapter { 25 | private final WebFragment myFragment;//上下文 26 | private final Handler handler;//上下文 27 | 28 | public WebDataAdapter(WebFragment serverFragment, int textViewResourceID, List objects, Handler handler) { 29 | super(serverFragment.getContext(), textViewResourceID, objects); 30 | this.myFragment = serverFragment; 31 | this.handler = handler; 32 | } 33 | 34 | @Override 35 | public View getView(int position, View convertView, ViewGroup parent) { 36 | var view = LayoutInflater.from(getContext()).inflate(R.layout.web_listview_data, null); 37 | var webData = getItem(position); 38 | //网址 39 | var tv_weburl = (TextView) view.findViewById(R.id.web_url); 40 | tv_weburl.setText(webData.getWeburl()); 41 | //备注 42 | var tv_remark = (TextView) view.findViewById(R.id.web_remark); 43 | tv_remark.setText(webData.getRemark()); 44 | //选择网站 45 | var ll_listview = (LinearLayout) view.findViewById(R.id.web_listview); 46 | ll_listview.setOnClickListener(view1 -> onClickListview(view1, webData)); 47 | //编辑数据 48 | var b_edit = (Button) view.findViewById(R.id.web_btn_edit); 49 | b_edit.setOnClickListener(view1 -> onClickEdit(view1, webData)); 50 | //删除 51 | var b_delete = (Button) view.findViewById(R.id.web_btn_delete); 52 | b_delete.setOnClickListener(view1 -> onClickDelete(view1, webData)); 53 | //选择状态 54 | var linearLayout = (LinearLayout) view.findViewById(R.id.web_select); 55 | if (webData.getIsselect()) { 56 | linearLayout.setBackgroundColor(Color.YELLOW); 57 | b_delete.setVisibility(View.INVISIBLE); 58 | } 59 | //返回结构 60 | return view; 61 | } 62 | 63 | /** 64 | * 列表单击 65 | * 66 | * @param view1 67 | * @param data 68 | */ 69 | public void onClickListview(View view1, WebData data) { 70 | var view = myFragment.getView(); 71 | var context = myFragment.getContext(); 72 | CookieHep.setCookie(context, data);//设置CK 73 | //反馈消息至界面 74 | StaticObj.dialogLoading = DialogLoading.build(context); 75 | StaticObj.dialogLoading.show(); 76 | StaticObj.sendMsg(handler, 4); 77 | } 78 | 79 | /** 80 | * 编辑数据 81 | * 82 | * @param view1 83 | * @param data 84 | */ 85 | private void onClickEdit(View view1, WebData data) { 86 | var view = myFragment.getView(); 87 | var context = myFragment.getContext(); 88 | StaticObj.dialogInput = WebDataDialog.build(context); 89 | StaticObj.dialogInput.show(data, handler); 90 | } 91 | 92 | /** 93 | * 删除数据 94 | * 95 | * @param view1 96 | * @param data 97 | */ 98 | private void onClickDelete(View view1, WebData data) { 99 | var view = myFragment.getView(); 100 | var context = myFragment.getContext(); 101 | //实例化一个对象 102 | var builder = new AlertDialog.Builder(context); 103 | //设置Title的图标 104 | builder.setIcon(R.drawable.ic_launcher); 105 | //设置Title的内容 106 | builder.setTitle("确定删除吗?"); 107 | //设置显示的内容 108 | builder.setMessage("地址:" + data.getWeburl() + "\r\n" + "备注:" + data.getRemark()); 109 | //设置按钮事件 110 | builder.setPositiveButton("确定", (dialog, which) -> { 111 | SqliteHelp.DelWebData(data); 112 | myFragment.LoadDataListView(view);//加载列表数据 113 | }); 114 | //设置按钮事件 115 | builder.setNegativeButton("取消", (dialog, which) -> { 116 | 117 | }); 118 | //显示出该对话框 119 | builder.show(); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /app/src/main/java/com/zgcwkj/getcks/web/WebFragment.java: -------------------------------------------------------------------------------- 1 | package com.zgcwkj.getcks.web; 2 | 3 | import android.os.Bundle; 4 | import android.os.Looper; 5 | import android.view.LayoutInflater; 6 | import android.view.Menu; 7 | import android.view.MenuInflater; 8 | import android.view.MenuItem; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.widget.ListView; 12 | 13 | import androidx.annotation.NonNull; 14 | import androidx.fragment.app.Fragment; 15 | import androidx.lifecycle.ViewModelProvider; 16 | 17 | import com.zgcwkj.bllcode.SqliteHelp; 18 | import com.zgcwkj.getcks.R; 19 | import com.zgcwkj.getcks.StaticObj; 20 | import com.zgcwkj.getcks.dialogs.QLConfigDialog; 21 | import com.zgcwkj.getcks.dialogs.WebDataDialog; 22 | 23 | public class WebFragment extends Fragment { 24 | public static WebHandler handler;//消息传递 25 | public WebViewModel viewModel;//页面模型 26 | 27 | public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 28 | var context = this.getContext(); 29 | //传递消息 30 | handler = new WebHandler(Looper.myLooper(), this); 31 | //视图模型 32 | viewModel = new ViewModelProvider(this).get(WebViewModel.class); 33 | //视图 34 | var view = inflater.inflate(R.layout.fragment_web, container, false); 35 | //加载列表数据 36 | LoadDataListView(view); 37 | //让系统知道有菜单项 38 | setHasOptionsMenu(true); 39 | //返回视图 40 | return view; 41 | } 42 | 43 | @Override 44 | public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 45 | inflater.inflate(R.menu.menu_web, menu); 46 | super.onCreateOptionsMenu(menu, inflater); 47 | } 48 | 49 | @Override 50 | public boolean onOptionsItemSelected(MenuItem item) { 51 | var view = getView(); 52 | var context = getContext(); 53 | var id = item.getItemId(); 54 | if (id == R.id.web_btnAdd) {//添加按钮 55 | StaticObj.dialogInput = WebDataDialog.build(context); 56 | StaticObj.dialogInput.show(handler); 57 | return true; 58 | } else if (id == R.id.web_btnQl) {//配置青龙 59 | StaticObj.dialogInputQl = QLConfigDialog.build(context); 60 | StaticObj.dialogInputQl.show(handler); 61 | return true; 62 | } 63 | //其它让基类来处理 64 | return super.onOptionsItemSelected(item); 65 | } 66 | 67 | /** 68 | * 加载列表数据 69 | */ 70 | public void LoadDataListView(View view) { 71 | //绑定 ListView 数据 72 | var dataList = SqliteHelp.GetWebDatas(); 73 | var sDAdapter = new WebDataAdapter(this, R.layout.web_listview_data, dataList, handler); 74 | var listView = (ListView) view.findViewById(R.id.server_data); 75 | listView.setAdapter(sDAdapter); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /app/src/main/java/com/zgcwkj/getcks/web/WebHandler.java: -------------------------------------------------------------------------------- 1 | package com.zgcwkj.getcks.web; 2 | 3 | import android.content.Context; 4 | import android.os.Handler; 5 | import android.os.Looper; 6 | import android.os.Message; 7 | import android.widget.Toast; 8 | 9 | import androidx.annotation.NonNull; 10 | 11 | import com.zgcwkj.getcks.StaticObj; 12 | 13 | import java.lang.ref.WeakReference; 14 | 15 | public class WebHandler extends Handler { 16 | WeakReference myActivity; 17 | 18 | public WebHandler(@NonNull Looper looper, WebFragment activity) { 19 | super(looper);//调用父类的显式指明的构造函数 20 | myActivity = new WeakReference(activity); 21 | } 22 | 23 | @Override 24 | public void handleMessage(Message msg) { 25 | super.handleMessage(msg); 26 | var nactivity = myActivity.get(); 27 | if (nactivity == null) return; 28 | Context context = nactivity.getContext(); 29 | // 30 | StaticObj.dialogLoading.close(); 31 | switch (msg.what) { 32 | case 0: 33 | Toast.makeText(context, "保存失败", Toast.LENGTH_SHORT).show(); 34 | break; 35 | case 1: 36 | StaticObj.dialogInput.close();//关闭对话框(网站配置) 37 | nactivity.LoadDataListView(nactivity.getView());//加载列表数据 38 | Toast.makeText(context, "保存成功", Toast.LENGTH_SHORT).show(); 39 | break; 40 | case 3: 41 | Toast.makeText(context, "选择失败", Toast.LENGTH_SHORT).show(); 42 | break; 43 | case 4: 44 | nactivity.LoadDataListView(nactivity.getView());//加载列表数据 45 | Toast.makeText(context, "选择成功", Toast.LENGTH_SHORT).show(); 46 | break; 47 | case 11: 48 | StaticObj.dialogInputQl.close();//关闭对话框(青龙配置) 49 | nactivity.LoadDataListView(nactivity.getView());//加载列表数据 50 | Toast.makeText(context, "保存成功", Toast.LENGTH_SHORT).show(); 51 | break; 52 | default: 53 | break; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/zgcwkj/getcks/web/WebViewModel.java: -------------------------------------------------------------------------------- 1 | package com.zgcwkj.getcks.web; 2 | 3 | import androidx.lifecycle.ViewModel; 4 | 5 | public class WebViewModel extends ViewModel { 6 | public WebViewModel() { 7 | } 8 | } -------------------------------------------------------------------------------- /app/src/main/java/com/zgcwkj/models/QLData.java: -------------------------------------------------------------------------------- 1 | package com.zgcwkj.models; 2 | 3 | //青龙数据结构 4 | public class QLData { 5 | //青龙地址 6 | private String weburl; 7 | //客户端ID 8 | private String clientId; 9 | //客户端凭据 10 | private String clientSecret; 11 | //自动启用环境变量 12 | private boolean autoEnable; 13 | 14 | public QLData() { 15 | weburl = ""; 16 | clientId = ""; 17 | clientSecret = ""; 18 | autoEnable = false; 19 | } 20 | 21 | public String getWeburl() { 22 | return weburl; 23 | } 24 | 25 | public void setWeburl(String weburl) { 26 | this.weburl = weburl; 27 | } 28 | 29 | public String getClientId() { 30 | return clientId; 31 | } 32 | 33 | public void setClientId(String clientId) { 34 | this.clientId = clientId; 35 | } 36 | 37 | public String getClientSecret() { 38 | return clientSecret; 39 | } 40 | 41 | public void setClientSecret(String clientSecret) { 42 | this.clientSecret = clientSecret; 43 | } 44 | 45 | public boolean getAutoEnable() { 46 | return autoEnable; 47 | } 48 | 49 | public void setAutoEnable(boolean autoEnable) { 50 | this.autoEnable = autoEnable; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/com/zgcwkj/models/WebData.java: -------------------------------------------------------------------------------- 1 | package com.zgcwkj.models; 2 | 3 | //网站数据结构 4 | public class WebData { 5 | //ID 6 | private String id; 7 | //选择状态 8 | private boolean isselect; 9 | //网站地址 10 | private String weburl; 11 | //Cookie 12 | private String cookie; 13 | //Cookie Key 14 | private String cookiekey; 15 | //Cookie 隔离 16 | private boolean cookieisolate; 17 | //UserAgent 18 | private String userAgent; 19 | //备注 20 | private String remark; 21 | 22 | public WebData(boolean isselect) { 23 | this.weburl = ""; 24 | this.cookie = ""; 25 | this.cookiekey = ""; 26 | this.cookieisolate = false; 27 | this.isselect = isselect; 28 | this.userAgent = ""; 29 | this.remark = ""; 30 | } 31 | 32 | public WebData(boolean isselect, String weburl, String cookiekey, boolean cookieIsolate, 33 | String remark) { 34 | this.weburl = weburl; 35 | this.cookie = ""; 36 | this.cookiekey = cookiekey; 37 | this.cookieisolate = cookieIsolate; 38 | this.isselect = isselect; 39 | this.userAgent = ""; 40 | this.remark = remark; 41 | } 42 | 43 | public WebData(boolean isselect, String weburl, String cookie, String cookiekey, boolean cookieIsolate, 44 | String userAgent, String remark, String id) { 45 | this.weburl = weburl; 46 | this.cookie = cookie; 47 | this.cookiekey = cookiekey; 48 | this.cookieisolate = cookieIsolate; 49 | this.isselect = isselect; 50 | this.userAgent = userAgent; 51 | this.remark = remark; 52 | this.id = id; 53 | } 54 | 55 | public String getId() { 56 | if (id == null) return ""; 57 | return id; 58 | } 59 | 60 | public void setId(String id) { 61 | this.id = id; 62 | } 63 | 64 | public boolean getIsselect() { 65 | return isselect; 66 | } 67 | 68 | public void setIsselect(boolean isselect) { 69 | this.isselect = isselect; 70 | } 71 | 72 | public String getWeburl() { 73 | return weburl; 74 | } 75 | 76 | public void setWeburl(String weburl) { 77 | this.weburl = weburl; 78 | } 79 | 80 | public String getCookie() { 81 | return cookie; 82 | } 83 | 84 | public void setCookie(String cookie) { 85 | this.cookie = cookie; 86 | } 87 | 88 | public String getCookiekey() { 89 | return cookiekey; 90 | } 91 | 92 | public void setCookiekey(String cookiekey) { 93 | this.cookiekey = cookiekey; 94 | } 95 | 96 | public boolean getCookieIsolate() { 97 | return cookieisolate; 98 | } 99 | 100 | public void setCookieIsolate(boolean cookieIsolate) { 101 | this.cookieisolate = cookieIsolate; 102 | } 103 | 104 | public String getUserAgent() { 105 | return userAgent; 106 | } 107 | 108 | public void setUserAgent(String userAgent) { 109 | this.userAgent = userAgent; 110 | } 111 | 112 | public String getRemark() { 113 | return remark; 114 | } 115 | 116 | public void setRemark(String remark) { 117 | this.remark = remark; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zgcwkjOpenProject/Android_GetCookies/8b09354e72d452413df947034aa6e4ad1935db63/app/src/main/res/drawable/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zgcwkjOpenProject/Android_GetCookies/8b09354e72d452413df947034aa6e4ad1935db63/app/src/main/res/drawable/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ico_browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zgcwkjOpenProject/Android_GetCookies/8b09354e72d452413df947034aa6e4ad1935db63/app/src/main/res/drawable/ico_browser.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ico_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zgcwkjOpenProject/Android_GetCookies/8b09354e72d452413df947034aa6e4ad1935db63/app/src/main/res/drawable/ico_delete.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ico_edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zgcwkjOpenProject/Android_GetCookies/8b09354e72d452413df947034aa6e4ad1935db63/app/src/main/res/drawable/ico_edit.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ico_web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zgcwkjOpenProject/Android_GetCookies/8b09354e72d452413df947034aa6e4ad1935db63/app/src/main/res/drawable/ico_web.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_browser.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_web.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/web_input_data.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 13 | 14 | 19 | 20 | 21 | 27 | 28 | 32 | 33 | 37 | 38 | 45 | 46 | 47 | 51 | 52 | 56 | 57 | 64 | 65 | 66 | 70 | 71 | 75 | 76 | 83 | 84 | 85 | 89 | 90 | 94 | 95 | 102 | 103 | 104 | 108 | 109 | 113 | 114 | 121 | 122 | 123 | 128 | 129 | 134 | 135 | 136 | 137 | 142 | 143 |