├── .gitignore ├── LICENSE ├── README.md ├── app ├── build.gradle ├── libs │ ├── GraphView-4.0.1.jar │ ├── androidsvg-1.2.1.jar │ ├── support-v4-13.0.0.jar │ └── svgAndroid2.jar └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ ├── about.html │ ├── pin.db │ └── wpspin.html │ ├── java │ └── com │ │ └── example │ │ └── WiFiPasswordSearcher │ │ ├── AboutActivity.java │ │ ├── AppVersion.java │ │ ├── DatabaseHelper.java │ │ ├── ItemWps.java │ │ ├── MyActivity.java │ │ ├── MyAdapterWps.java │ │ ├── ServerSettingsActivity.java │ │ ├── Settings.java │ │ ├── SettingsActivity.java │ │ ├── StartActivity.java │ │ ├── UserInfoActivity.java │ │ ├── UserManager.java │ │ ├── WPSActivity.java │ │ └── WifiDetails.java │ └── res │ ├── drawable-hdpi │ ├── ic_launcher.png │ └── logo.png │ ├── drawable-ldpi │ ├── ic_launcher.png │ └── logo.png │ ├── drawable-mdpi │ ├── ic_launcher.png │ └── logo.png │ ├── drawable-xhdpi │ ├── ic_launcher.png │ └── logo.png │ ├── layout │ ├── about.xml │ ├── gpslogging.xml │ ├── list_wps_item.xml │ ├── listclick_contextmenu.xml │ ├── main.xml │ ├── row.xml │ ├── server_settings.xml │ ├── settings.xml │ ├── start.xml │ ├── user.xml │ ├── wifi_details.xml │ └── wps.xml │ ├── raw │ ├── open_ico.svg │ ├── pick.ogg │ ├── wep_ico.svg │ ├── wpa2_ico.svg │ ├── wpa_ico.svg │ └── wps_ico.svg │ └── values │ ├── dimens.xml │ └── strings.xml ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | ##### Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm ##### 2 | ##### (thanks to https://github.com/github/gitignore/blob/master/Global/JetBrains.gitignore) ##### 3 | 4 | /*.iml 5 | /app/*.iml 6 | 7 | ## Directory-based project format: 8 | .idea/ 9 | # if you remove the above rule, at least ignore the following: 10 | 11 | # User-specific stuff: 12 | # .idea/workspace.xml 13 | # .idea/tasks.xml 14 | # .idea/dictionaries 15 | 16 | # Sensitive or high-churn files: 17 | # .idea/dataSources.ids 18 | # .idea/dataSources.xml 19 | # .idea/sqlDataSources.xml 20 | # .idea/dynamic.xml 21 | # .idea/uiDesigner.xml 22 | 23 | # Gradle: 24 | # .idea/gradle.xml 25 | # .idea/libraries 26 | 27 | # Mongo Explorer plugin: 28 | # .idea/mongoSettings.xml 29 | 30 | ## File-based project format: 31 | *.ipr 32 | *.iws 33 | 34 | ## Plugin-specific files: 35 | 36 | # IntelliJ 37 | out/ 38 | 39 | # mpeltonen/sbt-idea plugin 40 | .idea_modules/ 41 | 42 | # JIRA plugin 43 | atlassian-ide-plugin.xml 44 | 45 | # Crashlytics plugin (for Android Studio and IntelliJ) 46 | com_crashlytics_export_strings.xml 47 | 48 | 49 | ###### Android Studio generated ##### 50 | .gradle 51 | /local.properties 52 | /.idea/workspace.xml 53 | /app/build 54 | 55 | # Built application files 56 | *.apk 57 | *.ap_ 58 | 59 | # Files for the Dalvik VM 60 | *.dex 61 | 62 | # Java class files 63 | *.class 64 | 65 | # Generated files 66 | bin/ 67 | gen/ 68 | 69 | ####### And standard github .gitignore for Android ##### 70 | 71 | # Proguard folder generated by Eclipse 72 | proguard/ 73 | 74 | # Log Files 75 | *.log 76 | 77 | ###### OS-specific ###### 78 | 79 | # OS X 80 | .DS_Store 81 | 82 | # Windows thumbnail db (thanks to https://gist.github.com/nohitme/c9d3bb8818f94b772556 ) 83 | Thumbs.db 84 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 3WiFi Locator for Android 2 | 3 | The project is abandoned, gave collaborator rights to binarymaster. 4 | 5 | **— Fusix** 6 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 22 5 | buildToolsVersion "27.0.3" 6 | 7 | defaultConfig { 8 | applicationId "com.example.WiFiPasswordSearcher" 9 | minSdkVersion 14 10 | targetSdkVersion 14 11 | } 12 | 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | implementation files('libs/androidsvg-1.2.1.jar') 23 | implementation files('libs/GraphView-4.0.1.jar') 24 | implementation files('libs/support-v4-13.0.0.jar') 25 | implementation files('libs/svgAndroid2.jar') 26 | } 27 | -------------------------------------------------------------------------------- /app/libs/GraphView-4.0.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FusixGit/WiFiPasswordSearcher/739af59460b32db7c1590f15651a45f06e8b1ee2/app/libs/GraphView-4.0.1.jar -------------------------------------------------------------------------------- /app/libs/androidsvg-1.2.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FusixGit/WiFiPasswordSearcher/739af59460b32db7c1590f15651a45f06e8b1ee2/app/libs/androidsvg-1.2.1.jar -------------------------------------------------------------------------------- /app/libs/support-v4-13.0.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FusixGit/WiFiPasswordSearcher/739af59460b32db7c1590f15651a45f06e8b1ee2/app/libs/support-v4-13.0.0.jar -------------------------------------------------------------------------------- /app/libs/svgAndroid2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FusixGit/WiFiPasswordSearcher/739af59460b32db7c1590f15651a45f06e8b1ee2/app/libs/svgAndroid2.jar -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 18 | 21 | 22 | 23 | 24 | 25 | 26 | 28 | 29 | 30 | 32 | 33 | 34 | 36 | 37 | 38 | 40 | 41 | 42 | 44 | 45 | 46 | 48 | 49 | 50 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /app/src/main/assets/about.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 3WiFi Locator About 4 | 41 | 42 | 43 |

License Agreement

44 |
45 | 50 |
51 | 52 |

Credits

53 |
54 | 55 | 56 | 57 | 58 | 59 | 60 |
FusixThe main idea
Initial implementation
Stas'MActive development
Server and API maintenance
RUSHCOWWPS PIN features
61 |
62 | 63 |

Copyright © Stas'M Corp. 2015-2018

64 | 65 |

What's new

66 |
67 | 92 |
93 | 94 | 95 | -------------------------------------------------------------------------------- /app/src/main/assets/pin.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FusixGit/WiFiPasswordSearcher/739af59460b32db7c1590f15651a45f06e8b1ee2/app/src/main/assets/pin.db -------------------------------------------------------------------------------- /app/src/main/java/com/example/WiFiPasswordSearcher/AboutActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.WiFiPasswordSearcher; 2 | 3 | import android.app.Activity; 4 | import android.graphics.Color; 5 | import android.os.Bundle; 6 | import android.util.TypedValue; 7 | import android.webkit.WebView; 8 | 9 | import java.io.InputStream; 10 | 11 | 12 | public class AboutActivity extends Activity 13 | { 14 | protected void onCreate(Bundle savedInstanceState) 15 | { 16 | super.onCreate(savedInstanceState); 17 | setContentView(R.layout.about); 18 | 19 | WebView about = (WebView) findViewById(R.id.aboutWeb); 20 | String filename = "about.html"; 21 | String html; 22 | try { 23 | InputStream in = getAssets().open(filename); 24 | int size = in.available(); 25 | byte[] data = new byte[size]; 26 | int read = in.read(data); 27 | in.close(); 28 | html = (read > 0 ? new String(data, "UTF-8") : ""); 29 | } 30 | catch (Exception e) { 31 | html = ""; 32 | } 33 | 34 | int backColor = getThemeColor(android.R.attr.colorBackground); 35 | int textColor = getResources().getColor(isColorDark(backColor) ? android.R.color.secondary_text_dark : android.R.color.secondary_text_light); 36 | html = html.replace("#000;", colorToCSS(backColor)); 37 | html = html.replace("#fff;", colorToCSS(textColor)); 38 | about.loadData(html, "text/html", "UTF-8"); 39 | } 40 | private boolean isColorDark(int color) 41 | { 42 | double darkness = 1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255; 43 | return darkness >= 0.5; 44 | } 45 | private String colorToCSS(int color) 46 | { 47 | String str = String.format("%06x", color & 0xFFFFFF); 48 | return '#' + str + ";"; 49 | } 50 | private int getThemeColor(int prop) 51 | { 52 | int color = 0; 53 | TypedValue v = new TypedValue(); 54 | getTheme().resolveAttribute(prop, v, true); 55 | if (v.type >= TypedValue.TYPE_FIRST_COLOR_INT && v.type <= TypedValue.TYPE_LAST_COLOR_INT) 56 | { 57 | color = v.data; 58 | } 59 | return color; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/WiFiPasswordSearcher/AppVersion.java: -------------------------------------------------------------------------------- 1 | package com.example.WiFiPasswordSearcher; 2 | 3 | import android.app.Activity; 4 | import android.app.AlertDialog; 5 | import android.content.Context; 6 | import android.content.DialogInterface; 7 | import android.content.Intent; 8 | import android.net.Uri; 9 | import android.widget.Toast; 10 | 11 | import org.json.JSONException; 12 | import org.json.JSONObject; 13 | 14 | import java.io.BufferedReader; 15 | import java.io.File; 16 | import java.io.FileOutputStream; 17 | import java.io.IOException; 18 | import java.io.InputStream; 19 | import java.io.InputStreamReader; 20 | import java.io.OutputStream; 21 | import java.net.HttpURLConnection; 22 | import java.net.URL; 23 | import java.nio.charset.Charset; 24 | import java.text.DecimalFormat; 25 | import java.text.SimpleDateFormat; 26 | import java.util.Date; 27 | import java.util.Locale; 28 | 29 | public class AppVersion 30 | { 31 | private Context context; 32 | private Float ActualyVersion; 33 | private String WhatNews; 34 | private Boolean LoadSuccesses = false; 35 | private String wpsInternalDate = "2018-05-12 22:22:32"; 36 | private Settings mSettings; 37 | 38 | public AppVersion(Context _context) 39 | { 40 | context = _context; 41 | ActualyVersion = 0f; 42 | WhatNews = ""; 43 | 44 | mSettings = new Settings(context); 45 | } 46 | 47 | public void ShowUpdateDialog(Activity activity) 48 | { 49 | AlertDialog.Builder ad = new AlertDialog.Builder(activity); 50 | 51 | ad.setTitle("New version " + ActualyVersion + " available!"); 52 | ad.setMessage(WhatNews); 53 | ad.setCancelable(false); 54 | ad.setPositiveButton("Download", new DialogInterface.OnClickListener() { 55 | public void onClick(DialogInterface dialog, int arg1) { 56 | mSettings.Reload(); 57 | String SERVER_URI = mSettings.AppSettings.getString(Settings.APP_SERVER_URI, context.getResources().getString(R.string.SERVER_URI_DEFAULT)); 58 | Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(SERVER_URI + "/api/app.latest.apk")); 59 | browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 60 | context.startActivity(browserIntent); 61 | } 62 | }); 63 | 64 | ad.setNegativeButton("Ask later", new DialogInterface.OnClickListener() { 65 | public void onClick(DialogInterface dialog, int arg1) { 66 | } 67 | }); 68 | 69 | ad.show(); 70 | } 71 | 72 | private void GetActualyVersion() throws IOException 73 | { 74 | String Args = "/api/ajax.php?Query=AppVersion"; 75 | BufferedReader Reader = null; 76 | String ReadLine = ""; 77 | String RawData = ""; 78 | 79 | try { 80 | mSettings.Reload(); 81 | String SERVER_URI = mSettings.AppSettings.getString(Settings.APP_SERVER_URI, context.getResources().getString(R.string.SERVER_URI_DEFAULT)); 82 | URL Uri = new URL(SERVER_URI + Args); 83 | 84 | HttpURLConnection Connection = (HttpURLConnection) Uri.openConnection(); 85 | Connection.setRequestMethod("GET"); 86 | Connection.setReadTimeout(10 * 1000); 87 | Connection.connect(); 88 | 89 | Reader = new BufferedReader(new InputStreamReader(Connection.getInputStream())); 90 | 91 | while ((ReadLine = Reader.readLine()) != null) { 92 | RawData += ReadLine; 93 | } 94 | try 95 | { 96 | JSONObject Json = new JSONObject(RawData); 97 | Boolean Successes = Json.getBoolean("Successes"); 98 | LoadSuccesses = Successes; 99 | if (LoadSuccesses) 100 | { 101 | ActualyVersion = (float)Json.getDouble("ActualyVersion"); 102 | WhatNews = Json.getString("WhatNews"); 103 | return; 104 | } 105 | 106 | } 107 | catch (JSONException e) 108 | { 109 | e.printStackTrace(); 110 | } 111 | 112 | } 113 | finally 114 | { 115 | 116 | } 117 | } 118 | 119 | public Boolean isActualyVersion(Context context, Boolean showMessage) 120 | { 121 | if (showMessage) LoadSuccesses = false; 122 | 123 | if (!LoadSuccesses) try { 124 | GetActualyVersion(); 125 | } catch (IOException e) { 126 | LoadSuccesses = false; 127 | } 128 | if (!LoadSuccesses) 129 | { 130 | if (showMessage) 131 | { 132 | Toast t = Toast.makeText(context, "No internet connection", Toast.LENGTH_SHORT); 133 | t.show(); 134 | } 135 | return true; 136 | } 137 | Float CurVersion = Float.parseFloat(context.getResources().getString(R.string.app_version)); 138 | if (CurVersion >= ActualyVersion) 139 | { 140 | if (showMessage) 141 | { 142 | Toast t = Toast.makeText(context, "Using latest version", Toast.LENGTH_SHORT); 143 | t.show(); 144 | } 145 | return true; 146 | } 147 | return false; 148 | } 149 | 150 | private Boolean wpsCompanionExists() 151 | { 152 | File file = new File(context.getFilesDir().getAbsolutePath() + "/wpspin.html"); 153 | return file.exists(); 154 | } 155 | 156 | public void wpsCompanionInit(Boolean force) 157 | { 158 | if (wpsCompanionExists() && !force) 159 | return; 160 | 161 | String filename = "wpspin.html"; 162 | try 163 | { 164 | InputStream in = context.getAssets().open(filename); 165 | int size = in.available(); 166 | byte[] data = new byte[size]; 167 | in.read(data); 168 | in.close(); 169 | String str = new String(data, "UTF-8"); 170 | 171 | Date date; 172 | SimpleDateFormat format = new SimpleDateFormat(context.getResources().getString(R.string.DEFAULT_DATE_FORMAT), Locale.US); 173 | try { 174 | date = format.parse(wpsInternalDate); 175 | } catch (Exception e) { 176 | date = new Date(); 177 | } 178 | wpsCompanionUpdate(str, date); 179 | } 180 | catch (Exception e) {} 181 | } 182 | 183 | public void wpsCompanionUpdate(String str, Date date) 184 | { 185 | File outFile = new File(context.getFilesDir().getAbsolutePath() + "/wpspin.html"); 186 | 187 | try 188 | { 189 | OutputStream out = new FileOutputStream(outFile); 190 | str = str.replace("a.filter((n) => b.includes(n));", "a;"); 191 | byte[] data = str.getBytes(Charset.forName("UTF-8")); 192 | out.write(data); 193 | out.close(); 194 | outFile.setLastModified(date.getTime()); 195 | } 196 | catch (Exception e) {} 197 | } 198 | 199 | public String wpsCompanionGetPath() 200 | { 201 | if (!wpsCompanionExists()) 202 | return null; 203 | 204 | return context.getFilesDir().getAbsolutePath() + "/wpspin.html"; 205 | } 206 | 207 | public Date wpsCompanionGetDate() 208 | { 209 | File file = new File(context.getFilesDir().getAbsolutePath() + "/wpspin.html"); 210 | Date date = new Date(); 211 | date.setTime(file.lastModified()); 212 | return date; 213 | } 214 | 215 | public long wpsCompanionGetSize() 216 | { 217 | File file = new File(context.getFilesDir().getAbsolutePath() + "/wpspin.html"); 218 | return file.length(); 219 | } 220 | 221 | public Boolean wpsCompanionInternal() 222 | { 223 | Date date; 224 | SimpleDateFormat format = new SimpleDateFormat(context.getResources().getString(R.string.DEFAULT_DATE_FORMAT), Locale.US); 225 | try { 226 | date = format.parse(wpsInternalDate); 227 | } catch (Exception e) { 228 | date = new Date(); 229 | } 230 | return date.compareTo(wpsCompanionGetDate()) == 0; 231 | } 232 | 233 | public String readableFileSize(long size) 234 | { 235 | if (size <= 0) return "0"; 236 | final String[] units = new String[] { "B", "KiB", "MiB", "GiB", "TiB" }; 237 | int digitGroups = (int) (Math.log10(size) / Math.log10(1024)); 238 | return new DecimalFormat("#,##0.#").format(size/Math.pow(1024, digitGroups)) + " " + units[digitGroups]; 239 | } 240 | } 241 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/WiFiPasswordSearcher/DatabaseHelper.java: -------------------------------------------------------------------------------- 1 | package com.example.WiFiPasswordSearcher; 2 | 3 | import android.content.Context; 4 | import android.database.SQLException; 5 | import android.database.sqlite.SQLiteDatabase; 6 | import android.database.sqlite.SQLiteOpenHelper; 7 | 8 | import java.io.File; 9 | import java.io.FileOutputStream; 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | import java.io.OutputStream; 13 | 14 | public class DatabaseHelper extends SQLiteOpenHelper { 15 | private static String DB_NAME = "pin.db"; 16 | private static String DB_PATH = ""; 17 | private static final int DB_VERSION = 2; 18 | 19 | private SQLiteDatabase mDataBase; 20 | private final Context mContext; 21 | private boolean mNeedUpdate = false; 22 | 23 | public DatabaseHelper(Context context) { 24 | super(context, DB_NAME, null, DB_VERSION); 25 | if (android.os.Build.VERSION.SDK_INT >= 17) 26 | DB_PATH = context.getApplicationInfo().dataDir+"/databases/"; 27 | else 28 | DB_PATH = "/data/data/" + context.getPackageName()+"/databases/"; 29 | 30 | this.mContext = context; 31 | 32 | copyDataBase(); 33 | 34 | this.getReadableDatabase(); 35 | } 36 | 37 | public void updateDataBase() throws IOException { 38 | //mNeedUpdate=true; 39 | if (mNeedUpdate) { 40 | File dbFile = new File(DB_PATH + DB_NAME); 41 | if (dbFile.exists()) 42 | dbFile.delete(); 43 | 44 | copyDataBase(); 45 | 46 | mNeedUpdate = false; 47 | } 48 | } 49 | 50 | private boolean checkDataBase() { 51 | File dbFile = new File(DB_PATH + DB_NAME); 52 | return dbFile.exists(); 53 | } 54 | 55 | private void copyDataBase() { 56 | if (!checkDataBase()) { 57 | this.getReadableDatabase(); 58 | this.close(); 59 | try { 60 | copyDBFile(); 61 | } catch (IOException mIOException) {} 62 | } 63 | } 64 | 65 | private void copyDBFile() throws IOException { 66 | InputStream mInput = mContext.getAssets().open(DB_NAME); 67 | // InputStream mInput = mContext.getResources().openRawResource(R.raw.pin); 68 | OutputStream mOutput = new FileOutputStream(DB_PATH + DB_NAME); 69 | byte[] mBuffer = new byte[1024]; 70 | int mLength; 71 | while ((mLength = mInput.read(mBuffer)) > 0) 72 | mOutput.write(mBuffer, 0, mLength); 73 | mOutput.flush(); 74 | mOutput.close(); 75 | mInput.close(); 76 | } 77 | 78 | public boolean openDataBase() throws SQLException { 79 | mDataBase = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.CREATE_IF_NECESSARY); 80 | return mDataBase != null; 81 | } 82 | 83 | @Override 84 | public synchronized void close() { 85 | if (mDataBase != null) 86 | mDataBase.close(); 87 | super.close(); 88 | } 89 | 90 | @Override 91 | public void onCreate(SQLiteDatabase db) { 92 | 93 | } 94 | 95 | @Override 96 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 97 | if (newVersion > oldVersion) 98 | mNeedUpdate = true; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/WiFiPasswordSearcher/ItemWps.java: -------------------------------------------------------------------------------- 1 | package com.example.WiFiPasswordSearcher; 2 | 3 | public class ItemWps { 4 | /** 5 | * Заголовок 6 | */ 7 | String pin; 8 | String metod; 9 | String score; 10 | String db; 11 | 12 | ItemWps(String h, String s, String c, String d){ 13 | this.pin=h; 14 | this.metod=s; 15 | this.score=c; 16 | this.db=d; 17 | } 18 | 19 | //Всякие гетеры и сеттеры 20 | public String getHeader() { 21 | return pin; 22 | } 23 | public void setHeader(String header) { 24 | this.pin = header; 25 | } 26 | public String getSubHeader() { 27 | return metod; 28 | } 29 | public void setSubHeader(String subHeader) { 30 | this.metod = subHeader; 31 | } 32 | public String getScore() { 33 | return score; 34 | } 35 | public void setScore(String score) { 36 | this.score = score; 37 | } 38 | public String getDb() { 39 | return db; 40 | } 41 | public void setDb(String db) { 42 | this.db = db; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/WiFiPasswordSearcher/MyActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.WiFiPasswordSearcher; 2 | 3 | import android.app.Activity; 4 | import android.app.AlertDialog; 5 | import android.app.ProgressDialog; 6 | import android.app.ActionBar; 7 | import android.content.*; 8 | import android.graphics.Color; 9 | import android.graphics.drawable.Drawable; 10 | import android.location.LocationManager; 11 | import android.net.wifi.ScanResult; 12 | import android.net.wifi.WifiConfiguration; 13 | import android.net.wifi.WifiManager; 14 | import android.os.Bundle; 15 | import android.os.StrictMode; 16 | import android.view.View; 17 | import android.view.ViewGroup; 18 | import android.widget.*; 19 | import com.larvalabs.svgandroid.SVG; 20 | import com.larvalabs.svgandroid.SVGParser; 21 | import org.json.JSONArray; 22 | import org.json.JSONException; 23 | import org.json.JSONObject; 24 | 25 | import java.io.BufferedReader; 26 | import java.io.DataOutputStream; 27 | import java.io.InputStreamReader; 28 | import java.net.HttpURLConnection; 29 | import java.net.URL; 30 | import java.util.ArrayList; 31 | import java.util.Collections; 32 | import java.util.Comparator; 33 | import java.util.HashMap; 34 | import java.util.List; 35 | import java.util.Map; 36 | 37 | 38 | class APData 39 | { 40 | public String BSSID; 41 | public ArrayList Keys; 42 | public ArrayList Generated; 43 | public ArrayList WPS; 44 | } 45 | 46 | class MyScanResult 47 | { 48 | public String BSSID; 49 | public String SSID; 50 | public int frequency; 51 | public int level; 52 | public String capabilities; 53 | } 54 | 55 | class WiFiListSimpleAdapter extends SimpleAdapter 56 | { 57 | private Context context; 58 | private List DataList; 59 | private static HashMap SvgImageCache = new HashMap<>(); 60 | 61 | public WiFiListSimpleAdapter(Context _context, List> data, int resource, String[] from, int[] to) { 62 | super(_context, data, resource, from, to); 63 | context = _context; 64 | DataList = data; 65 | } 66 | 67 | private String DeleteInTextTags(String text) { 68 | 69 | if (text.length() > 2 && text.substring(0, 2).equals("*[")) { 70 | String stylePref = text.substring(2, text.indexOf("]*")); 71 | 72 | text = text.substring(stylePref.length() + 4); 73 | } 74 | return text; 75 | } 76 | 77 | private void ParseInTextTags(TextView txtView) 78 | { 79 | String text = ""+txtView.getText(); 80 | 81 | if (text.length() > 2 && text.substring(0, 2).equals("*[")) 82 | { 83 | String stylePref = text.substring(2, text.indexOf("]*")); 84 | txtView.setText(text.substring(stylePref.length() + 4)); 85 | 86 | if (stylePref.indexOf(":") > 0) 87 | { 88 | String style = stylePref.substring(0, stylePref.indexOf(":")); 89 | String value = stylePref.substring(stylePref.indexOf(":")+1); 90 | 91 | if (style.equals("color")) 92 | { 93 | switch (value) 94 | { 95 | case "red": 96 | txtView.setTextColor(Color.rgb(153, 0, 0)); 97 | break; 98 | case "green": 99 | txtView.setTextColor(Color.GREEN); 100 | break; 101 | case "greendark": 102 | txtView.setTextColor(Color.rgb(0, 153, 76)); 103 | break; 104 | case "blue": 105 | txtView.setTextColor(Color.BLUE); 106 | break; 107 | case "yellow": 108 | txtView.setTextColor(Color.rgb(153, 153, 0)); 109 | break; 110 | case "gray": 111 | txtView.setTextColor(Color.rgb(105, 105, 105)); 112 | break; 113 | } 114 | } 115 | } 116 | } 117 | else { 118 | txtView.setTextColor(Color.WHITE); 119 | } 120 | } 121 | 122 | 123 | public View getView(int position, View convertView, ViewGroup parent) { 124 | View view = super.getView(position, convertView, parent); 125 | 126 | ImageView imgSec = (ImageView) view.findViewById(R.id.imgSec); 127 | ImageView imgWPS = (ImageView) view.findViewById(R.id.imgWps); 128 | 129 | HashMap ElemWiFi; 130 | ElemWiFi = (HashMap) DataList.get(position); 131 | String Capability = ElemWiFi.get("CAPABILITY"); 132 | 133 | imgSec.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 134 | imgWPS.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 135 | 136 | SVG svgImg; 137 | 138 | if (Capability.contains("WPA2")) 139 | { 140 | Drawable img = SvgImageCache.get("WPA2"); 141 | if (img == null) 142 | { 143 | svgImg = SVGParser.getSVGFromResource(context.getResources(), R.raw.wpa2_ico); 144 | img = svgImg.createPictureDrawable(); 145 | SvgImageCache.put("WPA2", img); 146 | } 147 | imgSec.setImageDrawable(img); 148 | } 149 | else if (Capability.contains("WPA")) 150 | { 151 | Drawable img = SvgImageCache.get("WPA"); 152 | if (img == null) 153 | { 154 | svgImg = SVGParser.getSVGFromResource(context.getResources(), R.raw.wpa_ico); 155 | img = svgImg.createPictureDrawable(); 156 | SvgImageCache.put("WPA", img); 157 | } 158 | imgSec.setImageDrawable(img); 159 | } 160 | else if (Capability.contains("WEP")) 161 | { 162 | Drawable img = SvgImageCache.get("WEP"); 163 | if (img == null) 164 | { 165 | svgImg = SVGParser.getSVGFromResource(context.getResources(), R.raw.wep_ico); 166 | img = svgImg.createPictureDrawable(); 167 | SvgImageCache.put("WEP", img); 168 | } 169 | imgSec.setImageDrawable(img); 170 | } 171 | else 172 | { 173 | Drawable img = SvgImageCache.get("OPEN"); 174 | if (img == null) 175 | { 176 | svgImg = SVGParser.getSVGFromResource(context.getResources(), R.raw.open_ico); 177 | img = svgImg.createPictureDrawable(); 178 | SvgImageCache.put("OPEN", img); 179 | } 180 | imgSec.setImageDrawable(img); 181 | } 182 | 183 | if (Capability.contains("WPS")) 184 | { 185 | Drawable img = SvgImageCache.get("WPS"); 186 | if (img == null) 187 | { 188 | svgImg = SVGParser.getSVGFromResource(context.getResources(), R.raw.wps_ico); 189 | img = svgImg.createPictureDrawable(); 190 | SvgImageCache.put("WPS", img); 191 | } 192 | imgWPS.setImageDrawable(img); 193 | } 194 | else 195 | { 196 | imgWPS.setImageResource(android.R.color.transparent); 197 | } 198 | 199 | TextView txtKey = (TextView) view.findViewById(R.id.KEY); 200 | TextView txtSignal = (TextView) view.findViewById(R.id.txtSignal); 201 | TextView txtRowId = (TextView)view.findViewById(R.id.txtRowId); 202 | TextView txtKeysCount = (TextView)view.findViewById(R.id.txtKeysCount); 203 | TextView txtWPS = (TextView)view.findViewById(R.id.txtWPS); 204 | LinearLayout llKeys = (LinearLayout)view.findViewById(R.id.llKeys); 205 | 206 | llKeys.setOnClickListener(onKeyClick); 207 | 208 | ParseInTextTags(txtKey); 209 | ParseInTextTags(txtSignal); 210 | ParseInTextTags(txtKeysCount); 211 | ParseInTextTags(txtWPS); 212 | 213 | int keysCount = Integer.parseInt(txtKeysCount.getText().toString()); 214 | llKeys.setClickable(keysCount > 1); 215 | 216 | txtRowId.setText(Integer.toString(position)); 217 | 218 | return view; 219 | } 220 | 221 | private View.OnClickListener onKeyClick = new View.OnClickListener() 222 | { 223 | public void onClick(View v) 224 | { 225 | if (MyActivity.WiFiKeys == null || MyActivity.WiFiKeys.size() == 0) return; 226 | 227 | LinearLayout llRow = (LinearLayout)v.getParent().getParent(); 228 | TextView txtRowId = (TextView)llRow.findViewById(R.id.txtRowId); 229 | final int rowId = Integer.parseInt(txtRowId.getText().toString()); 230 | 231 | ArrayList keys = MyActivity.WiFiKeys.get(rowId).Keys; 232 | ArrayList wpss = MyActivity.WiFiKeys.get(rowId).WPS; 233 | 234 | if (keys.size() <= 1) return; 235 | 236 | String[] keysList = new String[keys.size()]; 237 | 238 | for (int i = 0; i < keysList.length; i++) 239 | { 240 | String WPS = wpss.get(i); 241 | if (WPS.isEmpty()) { 242 | keysList[i] = "Key: " + DeleteInTextTags(keys.get(i)); 243 | } 244 | else { 245 | keysList[i] = "Key: " + DeleteInTextTags(keys.get(i)) + " WPS: " + DeleteInTextTags(WPS); 246 | } 247 | } 248 | 249 | AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context); 250 | dialogBuilder.setTitle("Choose key:"); 251 | dialogBuilder.setItems(keysList, new DialogInterface.OnClickListener() { 252 | public void onClick(DialogInterface dialog, int item) { 253 | passwordChoose(rowId, item); 254 | }}); 255 | dialogBuilder.show(); 256 | } 257 | }; 258 | 259 | private void passwordChoose(int rowID, int passId) 260 | { 261 | View row = null; 262 | for (int i = 0; i < MyActivity.WiFiList.getChildCount(); i++) 263 | { 264 | row = MyActivity.WiFiList.getChildAt(i); 265 | TextView txtRowId = (TextView)row.findViewById(R.id.txtRowId); 266 | int rid = Integer.parseInt(txtRowId.getText().toString()); 267 | if (rid != rowID) 268 | row = null; 269 | else 270 | break; 271 | } 272 | if (row == null) 273 | return; 274 | 275 | ArrayList keys = MyActivity.WiFiKeys.get(rowID).Keys; 276 | ArrayList gen = MyActivity.WiFiKeys.get(rowID).Generated; 277 | ArrayList wps = MyActivity.WiFiKeys.get(rowID).WPS; 278 | String choosedPassword = keys.get(passId); 279 | Boolean isGen = gen.get(passId); 280 | String curWPS = wps.get(passId); 281 | String KeyColor; 282 | 283 | keys.set(passId, keys.get(0)); 284 | keys.set(0, choosedPassword); 285 | gen.set(passId, gen.get(0)); 286 | gen.set(0, isGen); 287 | wps.set(passId, wps.get(0)); 288 | wps.set(0, curWPS); 289 | 290 | TextView txtKey = (TextView)row.findViewById(R.id.KEY); 291 | KeyColor = (isGen ? "*[color:red]*" : "*[color:green]*"); 292 | txtKey.setText(KeyColor + choosedPassword); 293 | ParseInTextTags(txtKey); 294 | TextView txtWPS = (TextView)row.findViewById(R.id.txtWPS); 295 | txtWPS.setText(curWPS.isEmpty() ? "*[color:gray]*[unknown]" : "*[color:blue]*" + curWPS); 296 | ParseInTextTags(txtWPS); 297 | } 298 | } 299 | 300 | public class MyActivity extends Activity { 301 | /** 302 | * Called when the activity is first created. 303 | */ 304 | 305 | private Settings mSettings; 306 | private UserManager User; 307 | 308 | public static String APP_VERSION = ""; 309 | public static String API_READ_KEY = ""; 310 | public static String API_WRITE_KEY = ""; 311 | public static Boolean API_KEYS_VALID = false; 312 | 313 | 314 | public static ListView WiFiList = null; 315 | private Button btnRefresh = null; 316 | private Button btnCheckFromBase = null; 317 | private Button btnStartGPSLog = null; 318 | private ImageButton btnSettings = null; 319 | private static List WiFiScanResult = null; 320 | public static ArrayList WiFiKeys = new ArrayList<>(); 321 | 322 | private static boolean ScanInProcess = false; 323 | private static BroadcastReceiver ScanWiFiReceiverIntent = null; 324 | 325 | private WifiManager WifiMgr = null; 326 | private LocationManager LocationMgr = null; 327 | 328 | private ClipboardManager sClipboard = null; 329 | protected LinearLayout lastWiFiClickItem = null; 330 | 331 | private static WiFiListSimpleAdapter adapter = null; 332 | 333 | private static final String[] listContextMenuItems = new String[]{ 334 | "Network details", 335 | "Copy ESSID", 336 | "Copy BSSID", 337 | "Copy network key", 338 | "Store network profile", 339 | "Generate WPS PIN" 340 | }; 341 | 342 | public void btnRefreshOnClick(View v) 343 | { 344 | if (ScanInProcess) return; 345 | 346 | if (WiFiKeys != null) WiFiKeys.clear(); 347 | if (WiFiScanResult != null) WiFiScanResult.clear(); 348 | 349 | Context context = getApplicationContext(); 350 | ArrayList> list = new ArrayList<>(); 351 | SimpleAdapter adapter = new SimpleAdapter(context, list, R.layout.row, 352 | new String[]{"ESSID", "BSSID"}, 353 | new int[]{R.id.ESSID, R.id.BSSID}); 354 | WiFiList.setAdapter(adapter); 355 | ScanAndShowWiFi(); 356 | }; 357 | 358 | private View.OnClickListener btnSettingsOnClick = new View.OnClickListener() 359 | { 360 | public void onClick(View v) { 361 | Intent intent = new Intent(MyActivity.this, SettingsActivity.class); 362 | startActivity(intent); 363 | } 364 | }; 365 | 366 | private View.OnClickListener btnStartGPSLogOnClick = new View.OnClickListener() 367 | { 368 | public void onClick(View v) 369 | { 370 | /*setContentView(R.layout.gpslogging); 371 | btnSettingsRevent = (ImageButton) findViewById(R.id.btnGPSLoggingRevent); 372 | btnSettingsRevent.setOnClickListener(btnSettingsReventOnClick);*/ 373 | } 374 | }; 375 | 376 | private View.OnClickListener btnCheckFromBaseOnClick = new View.OnClickListener() 377 | { 378 | public void onClick(View v) 379 | { 380 | if (ScanInProcess) return; 381 | if (WiFiKeys != null) WiFiKeys.clear(); 382 | 383 | final ProgressDialog dProccess = new ProgressDialog(MyActivity.this); 384 | dProccess.setProgressStyle(ProgressDialog.STYLE_SPINNER); 385 | dProccess.setMessage("Searching in 3WiFi..."); 386 | dProccess.setCanceledOnTouchOutside(false); 387 | btnCheckFromBase.setEnabled(false); 388 | dProccess.show(); 389 | 390 | new Thread(new Runnable() { 391 | @Override 392 | public void run() { 393 | CheckFromBase(); 394 | dProccess.dismiss(); 395 | } 396 | }).start(); 397 | } 398 | }; 399 | 400 | public Activity getActivity() 401 | { 402 | return this; 403 | } 404 | 405 | private TextView GetDataRowsFromLinLay(LinearLayout LinLay, String Type) 406 | { 407 | switch (Type) 408 | { 409 | case "BSSID": 410 | return (TextView)LinLay.findViewById(R.id.BSSID); 411 | case "ESSID": 412 | return (TextView)LinLay.findViewById(R.id.ESSID); 413 | case "KEY": 414 | return (TextView)LinLay.findViewById(R.id.KEY); 415 | } 416 | return null; 417 | } 418 | 419 | 420 | public AdapterView.OnItemClickListener WiFiListOnClick = new AdapterView.OnItemClickListener() 421 | { 422 | @Override 423 | public void onItemClick(AdapterView parent, View linearLayout, int position, final long id) 424 | { 425 | LinearLayout item = (LinearLayout)linearLayout; 426 | lastWiFiClickItem = item; 427 | 428 | TextView txtBSSID = GetDataRowsFromLinLay(item, "BSSID"); 429 | TextView txtESSID = GetDataRowsFromLinLay(item, "ESSID"); 430 | 431 | AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(MyActivity.this); 432 | 433 | dialogBuilder.setTitle(txtESSID.getText()); 434 | final String ESSDWps = txtESSID.getText().toString(); 435 | final String BSSDWps = txtBSSID.getText().toString(); 436 | 437 | dialogBuilder.setItems(listContextMenuItems, new DialogInterface.OnClickListener() { 438 | public void onClick(DialogInterface dialog, int item) 439 | { 440 | APData apdata; 441 | Boolean NeedToast = false; 442 | 443 | MyScanResult scanResult = WiFiScanResult.get((int)id); 444 | 445 | switch (item) 446 | { 447 | case 0: 448 | Intent detailsActivityIntent = new Intent(MyActivity.this, WifiDetails.class); 449 | HashMap WifiInfo = new HashMap<>(); 450 | WifiInfo.put("BSSID", scanResult.BSSID); 451 | WifiInfo.put("SSID", scanResult.SSID); 452 | WifiInfo.put("Freq", Integer.toString(scanResult.frequency)); 453 | WifiInfo.put("Signal", Integer.toString(scanResult.level)); 454 | WifiInfo.put("Capabilities", scanResult.capabilities); 455 | 456 | detailsActivityIntent.putExtra("WifiInfo", WifiInfo); 457 | startActivity(detailsActivityIntent); 458 | break; 459 | case 1: // Copy 460 | TextView txtBSSID = GetDataRowsFromLinLay(lastWiFiClickItem, "ESSID"); 461 | ClipData dataClip; 462 | dataClip = ClipData.newPlainText("text", txtBSSID.getText()); 463 | sClipboard.setPrimaryClip(dataClip); 464 | NeedToast = true; 465 | break; 466 | case 2: // Copy BSSID 467 | TextView txtESSID = GetDataRowsFromLinLay(lastWiFiClickItem, "BSSID"); 468 | dataClip = ClipData.newPlainText("text", txtESSID.getText()); 469 | sClipboard.setPrimaryClip(dataClip); 470 | NeedToast = true; 471 | break; 472 | case 3: // Copy Key 473 | if (WiFiKeys.isEmpty()) 474 | { 475 | Toast toast = Toast.makeText(getApplicationContext(), 476 | "No data here! Click 3WiFi button to fetch some keys.", 477 | Toast.LENGTH_LONG); 478 | toast.show(); 479 | break; 480 | } 481 | 482 | apdata = WiFiKeys.get((int)id); 483 | 484 | if (apdata.Keys.size() < 1) 485 | { 486 | Toast toast = Toast.makeText(getApplicationContext(), 487 | "Key not found! Nothing to copy", Toast.LENGTH_SHORT); 488 | toast.show(); 489 | return; 490 | } 491 | 492 | dataClip = ClipData.newPlainText("text", apdata.Keys.get(0)); 493 | sClipboard.setPrimaryClip(dataClip); 494 | NeedToast = true; 495 | break; 496 | case 4: // Add network 497 | if (WiFiKeys.isEmpty()) 498 | { 499 | Toast toast = Toast.makeText(getApplicationContext(), 500 | "No data here! Click 3WiFi button to fetch some keys.", 501 | Toast.LENGTH_LONG); 502 | toast.show(); 503 | break; 504 | } 505 | 506 | apdata = WiFiKeys.get((int)id); 507 | if (apdata == null || apdata.Keys.size() < 1) 508 | { 509 | Toast toast = Toast.makeText(getApplicationContext(), 510 | "Key not found!", Toast.LENGTH_SHORT); 511 | toast.show(); 512 | break; 513 | } 514 | 515 | if (!WifiMgr.isWifiEnabled()) 516 | { 517 | Toast toast = Toast.makeText(getApplicationContext(), 518 | "Wi-Fi interface is disabled", Toast.LENGTH_SHORT); 519 | toast.show(); 520 | break; 521 | } 522 | List list = WifiMgr.getConfiguredNetworks(); 523 | int cnt = 0; 524 | for (WifiConfiguration wifi : list) 525 | { 526 | if (wifi.SSID != null && wifi.SSID.equals("\"" + scanResult.SSID + "\"")) 527 | cnt++; 528 | } 529 | if (cnt > 0) 530 | { 531 | final MyScanResult gScanResult = scanResult; 532 | final APData gAPData = apdata; 533 | DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() 534 | { 535 | @Override 536 | public void onClick(DialogInterface dialog, int which) 537 | { 538 | switch (which) 539 | { 540 | case DialogInterface.BUTTON_POSITIVE: 541 | addNetworkProfile(gScanResult, gAPData); 542 | break; 543 | case DialogInterface.BUTTON_NEGATIVE: 544 | break; 545 | } 546 | dialog.dismiss(); 547 | } 548 | }; 549 | AlertDialog.Builder builder = new AlertDialog.Builder(MyActivity.this); 550 | builder.setTitle("Are you sure?") 551 | .setMessage(String.format("Network \"%s\" is already stored %d times.", scanResult.SSID, cnt)) 552 | .setPositiveButton("Yes", dialogClickListener) 553 | .setNegativeButton("No", dialogClickListener).show(); 554 | } 555 | else 556 | addNetworkProfile(scanResult, apdata); 557 | break; 558 | case 5: // wps 559 | if (!scanResult.capabilities.contains("WPS")) 560 | { 561 | DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() 562 | { 563 | @Override 564 | public void onClick(DialogInterface dialog, int which) 565 | { 566 | switch (which) 567 | { 568 | case DialogInterface.BUTTON_POSITIVE: 569 | wpsGenStart(ESSDWps, BSSDWps); 570 | break; 571 | case DialogInterface.BUTTON_NEGATIVE: 572 | break; 573 | } 574 | dialog.dismiss(); 575 | } 576 | }; 577 | AlertDialog.Builder builder = new AlertDialog.Builder(MyActivity.this); 578 | builder.setTitle("Are you sure?") 579 | .setMessage(String.format("Network \"%s\" is not WPS enabled.", scanResult.SSID)) 580 | .setPositiveButton("Yes", dialogClickListener) 581 | .setNegativeButton("No", dialogClickListener).show(); 582 | break; 583 | } 584 | wpsGenStart(ESSDWps, BSSDWps); 585 | break; 586 | } 587 | 588 | if (NeedToast) 589 | { 590 | Toast toast = Toast.makeText(getApplicationContext(), 591 | "Copied to clipboard", Toast.LENGTH_SHORT); 592 | toast.show(); 593 | } 594 | 595 | dialog.dismiss(); 596 | } 597 | }); 598 | 599 | dialogBuilder.show(); 600 | 601 | } 602 | 603 | }; 604 | 605 | private void wpsGenStart(String ESSDWps, String BSSDWps) 606 | { 607 | Intent wpsActivityIntent = new Intent(MyActivity.this, WPSActivity.class); 608 | wpsActivityIntent.putExtra("variable", ESSDWps); 609 | wpsActivityIntent.putExtra("variable1", BSSDWps); 610 | startActivity(wpsActivityIntent); 611 | } 612 | 613 | private void addNetworkProfile(MyScanResult scanResult, APData apdata) 614 | { 615 | WifiConfiguration WifiCfg = new WifiConfiguration(); 616 | WifiCfg.BSSID = scanResult.BSSID; 617 | WifiCfg.SSID = String.format("\"%s\"", scanResult.SSID); 618 | WifiCfg.hiddenSSID = false; 619 | WifiCfg.priority = 1000; 620 | 621 | if (scanResult.capabilities.contains("WEP")) 622 | { 623 | WifiCfg.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 624 | WifiCfg.allowedProtocols.set(WifiConfiguration.Protocol.RSN); 625 | WifiCfg.allowedProtocols.set(WifiConfiguration.Protocol.WPA); 626 | WifiCfg.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN); 627 | WifiCfg.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED); 628 | WifiCfg.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); 629 | WifiCfg.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP); 630 | WifiCfg.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40); 631 | WifiCfg.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104); 632 | 633 | WifiCfg.wepKeys[0] = String.format("\"%s\"", apdata.Keys.get(0)); 634 | WifiCfg.wepTxKeyIndex = 0; 635 | } 636 | else 637 | { 638 | WifiCfg.preSharedKey = String.format("\"%s\"", apdata.Keys.get(0)); 639 | } 640 | 641 | int netId = WifiMgr.addNetwork(WifiCfg); 642 | Toast toast; 643 | if (netId > -1) 644 | { 645 | toast = Toast.makeText(getApplicationContext(), 646 | "Network profile added!", Toast.LENGTH_SHORT); 647 | } 648 | else 649 | { 650 | if (WifiMgr.isWifiEnabled()) 651 | { 652 | toast = Toast.makeText(getApplicationContext(), 653 | "Failed to add network profile", Toast.LENGTH_SHORT); 654 | } 655 | else 656 | { 657 | toast = Toast.makeText(getApplicationContext(), 658 | "Wi-Fi interface is disabled", Toast.LENGTH_SHORT); 659 | } 660 | } 661 | toast.show(); 662 | } 663 | 664 | @Override 665 | public void onSaveInstanceState(Bundle savedInstanceState) { 666 | super.onSaveInstanceState(savedInstanceState); 667 | } 668 | 669 | @Override 670 | public void onRestoreInstanceState(Bundle savedInstanceState) 671 | { 672 | super.onRestoreInstanceState(savedInstanceState); 673 | } 674 | 675 | public void ApiDataTest() 676 | { 677 | if (!API_KEYS_VALID) 678 | { 679 | runOnUiThread(new Runnable() { 680 | @Override 681 | public void run() { 682 | Toast t = Toast.makeText(getApplicationContext(), "Please enter credentials", Toast.LENGTH_SHORT); 683 | t.show(); 684 | } 685 | }); 686 | Intent startActivity = new Intent(this, StartActivity.class); 687 | startActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); 688 | startActivity(startActivity); 689 | } 690 | } 691 | 692 | @Override 693 | public void onCreate(Bundle savedInstanceState) { 694 | super.onCreate(savedInstanceState); 695 | setContentView(R.layout.main); 696 | ActionBar actionBar = getActionBar(); 697 | actionBar.hide(); 698 | 699 | if (android.os.Build.VERSION.SDK_INT > 9) { 700 | StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); 701 | StrictMode.setThreadPolicy(policy); 702 | } 703 | APP_VERSION = getResources().getString(R.string.app_version); 704 | 705 | mSettings = new Settings(getApplicationContext()); 706 | User = new UserManager(getApplicationContext()); 707 | 708 | API_READ_KEY = mSettings.AppSettings.getString(Settings.API_READ_KEY, ""); 709 | API_WRITE_KEY = mSettings.AppSettings.getString(Settings.API_WRITE_KEY, ""); 710 | API_KEYS_VALID = mSettings.AppSettings.getBoolean(Settings.API_KEYS_VALID, false); 711 | 712 | 713 | WiFiList = (ListView) findViewById(R.id.WiFiList); 714 | btnRefresh = (Button) findViewById(R.id.btnRefresh); 715 | btnCheckFromBase = (Button) findViewById(R.id.btnCheckFromBase); 716 | btnSettings = (ImageButton) findViewById(R.id.btnSettings); 717 | btnStartGPSLog = (Button) findViewById(R.id.btnStartGPSLog); 718 | 719 | WifiMgr = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); 720 | LocationMgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 721 | sClipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); 722 | 723 | btnCheckFromBase.setOnClickListener(btnCheckFromBaseOnClick); 724 | btnStartGPSLog.setOnClickListener(btnStartGPSLogOnClick); 725 | btnSettings.setOnClickListener(btnSettingsOnClick); 726 | WiFiList.setOnItemClickListener(WiFiListOnClick); 727 | 728 | if (adapter != null) 729 | { 730 | WiFiList.setAdapter(adapter); 731 | btnCheckFromBase.setEnabled(true); 732 | } 733 | if (ScanInProcess) 734 | { 735 | // if(ScanWiFiReceiverIntent != null) unregisterReceiver(ScanWiFiReceiverIntent); 736 | //ScanAndShowWiFi(); 737 | } 738 | ScanAndShowWiFi(); 739 | } 740 | 741 | public void ScanAndShowWiFi() 742 | { 743 | final Comparator comparator = new Comparator() 744 | { 745 | @Override 746 | public int compare(MyScanResult lhs, MyScanResult rhs) 747 | { 748 | return (lhs.level < rhs.level ? 1 : (lhs.level == rhs.level ? 0 : -1)); 749 | } 750 | }; 751 | WiFiScanResult = null; 752 | adapter = null; 753 | if (false) 754 | { 755 | try 756 | { 757 | List results = new ArrayList<>(); 758 | MyScanResult sc; 759 | sc = new MyScanResult(); 760 | sc.BSSID = "00:0E:8F:D3:5E:9C"; 761 | sc.SSID = "beeline 49"; 762 | sc.capabilities = "WPA WPA2 WPS"; 763 | sc.level = -58; 764 | sc.frequency = 2440; 765 | results.add(sc); 766 | 767 | sc = new MyScanResult(); 768 | sc.BSSID = "64:D9:54:39:15:6B"; 769 | sc.SSID = "MGTS_ADSL_7003"; 770 | sc.capabilities = "WPA2 WPS"; 771 | sc.level = -65; 772 | sc.frequency = 2460; 773 | results.add(sc); 774 | 775 | sc = new MyScanResult(); 776 | sc.BSSID = "2C:AB:25:06:49:CB"; 777 | sc.SSID = "beeline-50"; 778 | sc.capabilities = "WPA WPS"; 779 | sc.level = -70; 780 | sc.frequency = 2420; 781 | results.add(sc); 782 | 783 | ArrayList> list = new ArrayList<>(); 784 | HashMap ElemWiFi; 785 | Collections.sort(results, comparator); 786 | WiFiScanResult = results; 787 | 788 | for (MyScanResult result : results) { 789 | ElemWiFi = new HashMap<>(); 790 | ElemWiFi.put("ESSID", result.SSID); 791 | ElemWiFi.put("BSSID", result.BSSID.toUpperCase()); 792 | ElemWiFi.put("KEY", "*[color:gray]*[no data]"); 793 | ElemWiFi.put("WPS", "*[color:gray]*[no data]"); 794 | ElemWiFi.put("SIGNAL", getStrSignal(result.level)); 795 | ElemWiFi.put("KEYSCOUNT", "*[color:gray]*0"); 796 | ElemWiFi.put("CAPABILITY", result.capabilities); 797 | 798 | list.add(ElemWiFi); 799 | } 800 | 801 | adapter = new WiFiListSimpleAdapter(getActivity(), list, R.layout.row, 802 | new String[]{"ESSID", "BSSID", "KEY", "WPS", "SIGNAL", "KEYSCOUNT", "CAPABILITY"}, 803 | new int[]{R.id.ESSID, R.id.BSSID, R.id.KEY, R.id.txtWPS, R.id.txtSignal, R.id.txtKeysCount}); 804 | WiFiList.setAdapter(adapter); 805 | 806 | ScanInProcess = false; 807 | btnRefresh.setEnabled(true); 808 | btnCheckFromBase.setEnabled(true); 809 | } 810 | catch (Exception e) {} 811 | return; 812 | } 813 | if (!WifiMgr.isWifiEnabled()) 814 | { 815 | Toast toast = Toast.makeText(this, 816 | "Wi-Fi interface is disabled", Toast.LENGTH_SHORT); 817 | toast.show(); 818 | return; 819 | } 820 | final ProgressDialog dProccess = new ProgressDialog(MyActivity.this); 821 | dProccess.setProgressStyle(ProgressDialog.STYLE_SPINNER); 822 | dProccess.setMessage("Scanning networks..."); 823 | dProccess.setCanceledOnTouchOutside(false); 824 | dProccess.show(); 825 | 826 | ScanWiFiReceiverIntent = new BroadcastReceiver() { 827 | @Override 828 | public void onReceive(Context context, Intent intent) 829 | { 830 | List res = WifiMgr.getScanResults(); 831 | List results = new ArrayList<>(); 832 | for (ScanResult result : res) { 833 | MyScanResult sc = new MyScanResult(); 834 | sc.BSSID = result.BSSID; 835 | sc.SSID = result.SSID; 836 | sc.level = result.level; 837 | sc.frequency = result.frequency; 838 | sc.capabilities = result.capabilities; 839 | results.add(sc); 840 | } 841 | Collections.sort(results, comparator); 842 | WiFiScanResult = results; 843 | 844 | ArrayList> list = new ArrayList<>(); 845 | HashMap ElemWiFi; 846 | 847 | for (MyScanResult result : results) { 848 | ElemWiFi = new HashMap<>(); 849 | ElemWiFi.put("ESSID", result.SSID); 850 | ElemWiFi.put("BSSID", result.BSSID.toUpperCase()); 851 | ElemWiFi.put("KEY", "*[color:gray]*[no data]"); 852 | ElemWiFi.put("WPS", "*[color:gray]*[no data]"); 853 | ElemWiFi.put("SIGNAL", getStrSignal(result.level)); 854 | ElemWiFi.put("KEYSCOUNT", "*[color:gray]*0"); 855 | ElemWiFi.put("CAPABILITY", result.capabilities); 856 | 857 | list.add(ElemWiFi); 858 | } 859 | 860 | adapter = new WiFiListSimpleAdapter(getActivity(), list, R.layout.row, 861 | new String[]{"ESSID", "BSSID", "KEY", "WPS", "SIGNAL", "KEYSCOUNT", "CAPABILITY"}, 862 | new int[]{R.id.ESSID, R.id.BSSID, R.id.KEY, R.id.txtWPS, R.id.txtSignal, R.id.txtKeysCount}); 863 | WiFiList.setAdapter(adapter); 864 | 865 | ScanInProcess = false; 866 | btnRefresh.setEnabled(true); 867 | btnCheckFromBase.setEnabled(true); 868 | 869 | Toast toast = Toast.makeText(getApplicationContext(), 870 | "Scan is complete!", Toast.LENGTH_SHORT); 871 | toast.show(); 872 | 873 | unregisterReceiver(this); 874 | ScanWiFiReceiverIntent = null; 875 | dProccess.dismiss(); 876 | } 877 | }; 878 | registerReceiver(ScanWiFiReceiverIntent, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)); 879 | 880 | ScanInProcess = true; 881 | btnRefresh.setEnabled(false); 882 | btnCheckFromBase.setEnabled(false); 883 | WifiMgr.startScan(); 884 | } 885 | 886 | private void CheckFromBase() 887 | { 888 | JSONObject bss = new JSONObject(); 889 | BufferedReader Reader = null; 890 | String ReadLine = ""; 891 | String RawData = ""; 892 | Boolean FETCH_ESS; 893 | 894 | try { 895 | JSONObject query = new JSONObject(); 896 | query.put("key", API_READ_KEY); 897 | JSONArray bssids = new JSONArray(); 898 | JSONArray essids = new JSONArray(); 899 | for (MyScanResult result : WiFiScanResult) { 900 | bssids.put(result.BSSID); 901 | essids.put(result.SSID); 902 | } 903 | mSettings.Reload(); 904 | FETCH_ESS = mSettings.AppSettings.getBoolean(Settings.APP_FETCH_ESS, false); 905 | 906 | query.put("bssid", bssids); 907 | if (FETCH_ESS) 908 | query.put("essid", essids); 909 | 910 | String SERVER_URI = mSettings.AppSettings.getString(Settings.APP_SERVER_URI, getResources().getString(R.string.SERVER_URI_DEFAULT)); 911 | URL Uri = new URL(SERVER_URI + "/api/apiquery"); 912 | 913 | HttpURLConnection Connection = (HttpURLConnection) Uri.openConnection(); 914 | Connection.setRequestMethod("POST"); 915 | Connection.setDoOutput(true); 916 | Connection.setRequestProperty("Content-Type", "application/json"); 917 | 918 | DataOutputStream writer = new DataOutputStream( 919 | Connection.getOutputStream()); 920 | writer.writeBytes(query.toString()); 921 | 922 | Connection.setReadTimeout(10 * 1000); 923 | Connection.connect(); 924 | 925 | Reader = new BufferedReader(new InputStreamReader(Connection.getInputStream())); 926 | 927 | while ((ReadLine = Reader.readLine()) != null) { 928 | RawData += ReadLine; 929 | } 930 | 931 | try 932 | { 933 | JSONObject json = new JSONObject(RawData); 934 | Boolean ret = json.getBoolean("result"); 935 | 936 | if (!ret) 937 | { 938 | // API failure 939 | String error = json.getString("error"); 940 | final String errorDesc = User.GetErrorDesc(error); 941 | 942 | if (error != null) { 943 | if (error.equals("loginfail")) 944 | { 945 | mSettings.Editor.putBoolean(Settings.API_KEYS_VALID, false); 946 | mSettings.Editor.commit(); 947 | API_KEYS_VALID = false; 948 | ApiDataTest(); 949 | return; 950 | } 951 | runOnUiThread(new Runnable() { 952 | @Override 953 | public void run() { 954 | Toast t = Toast.makeText(getApplicationContext(), errorDesc, Toast.LENGTH_SHORT); 955 | t.show(); 956 | btnCheckFromBase.setEnabled(true); 957 | } 958 | }); 959 | } 960 | return; 961 | } 962 | if (!json.isNull("data")) 963 | { 964 | try 965 | { 966 | bss = json.getJSONObject("data"); 967 | } 968 | catch (Exception e) 969 | { 970 | // add empty object 971 | bss = new JSONObject(); 972 | } 973 | } 974 | } 975 | catch (Exception e) 976 | { 977 | // JSON error 978 | runOnUiThread(new Runnable() { 979 | @Override 980 | public void run() { 981 | Toast t = Toast.makeText(getApplicationContext(), "Database failure", Toast.LENGTH_SHORT); 982 | t.show(); 983 | btnCheckFromBase.setEnabled(true); 984 | } 985 | }); 986 | return; 987 | } 988 | } 989 | catch (Exception e) 990 | { 991 | // Connection error 992 | runOnUiThread(new Runnable() { 993 | @Override 994 | public void run() { 995 | Toast t = Toast.makeText(getApplicationContext(), "No internet connection", Toast.LENGTH_SHORT); 996 | t.show(); 997 | btnCheckFromBase.setEnabled(true); 998 | } 999 | }); 1000 | return; 1001 | } 1002 | 1003 | ArrayList> list = new ArrayList<>(); 1004 | HashMap ElemWiFi; 1005 | String KeyColor; 1006 | int i = 0; 1007 | for (MyScanResult result : WiFiScanResult) { 1008 | APData apdata = GetWiFiKeyByBSSID(bss, FETCH_ESS, result.SSID, result.BSSID.toUpperCase()); 1009 | 1010 | ElemWiFi = new HashMap<>(); 1011 | ElemWiFi.put("ESSID", result.SSID); 1012 | ElemWiFi.put("BSSID", result.BSSID.toUpperCase()); 1013 | ElemWiFi.put("SIGNAL", getStrSignal(result.level)); 1014 | 1015 | 1016 | if (apdata.Keys.size() < 1) 1017 | { 1018 | ElemWiFi.put("KEY", "*[color:gray]*[unknown]"); 1019 | ElemWiFi.put("KEYSCOUNT", "*[color:gray]*" + Integer.toString(apdata.Keys.size())); 1020 | } 1021 | else 1022 | { 1023 | KeyColor = (apdata.Generated.get(0) ? "*[color:red]*" : "*[color:green]*"); 1024 | ElemWiFi.put("KEY", KeyColor + apdata.Keys.get(0)); 1025 | ElemWiFi.put("KEYSCOUNT", "*[color:green]*" + Integer.toString(apdata.Keys.size())); 1026 | } 1027 | 1028 | if (apdata.WPS.size() < 1 || apdata.WPS.get(0).isEmpty()) 1029 | { 1030 | ElemWiFi.put("WPS", "*[color:gray]*[unknown]"); 1031 | } 1032 | else 1033 | { 1034 | ElemWiFi.put("WPS", "*[color:blue]*" + apdata.WPS.get(0)); 1035 | } 1036 | 1037 | 1038 | ElemWiFi.put("CAPABILITY", result.capabilities); 1039 | list.add(ElemWiFi); 1040 | 1041 | WiFiKeys.add(i, apdata); 1042 | i++; 1043 | } 1044 | 1045 | adapter = new WiFiListSimpleAdapter(getActivity(), list, R.layout.row, 1046 | new String[]{"ESSID", "BSSID", "KEY", "WPS", "SIGNAL", "KEYSCOUNT", "CAPABILITY"}, 1047 | new int[]{R.id.ESSID, R.id.BSSID, R.id.KEY, R.id.txtWPS, R.id.txtSignal, R.id.txtKeysCount}); 1048 | 1049 | runOnUiThread(new Thread(new Runnable() { 1050 | @Override 1051 | public void run() { 1052 | WiFiList.setAdapter(adapter); 1053 | btnCheckFromBase.setEnabled(true); 1054 | } 1055 | } 1056 | )); 1057 | } 1058 | 1059 | public Boolean KeyWPSPairExists(ArrayList keys, ArrayList pins, String key, String pin) 1060 | { 1061 | for (int i = 0; i < keys.size(); i++) 1062 | { 1063 | if (keys.get(i).equals(key) && pins.get(i).equals(pin)) 1064 | return true; 1065 | } 1066 | return false; 1067 | } 1068 | 1069 | public APData GetWiFiKeyByBSSID(JSONObject bss, Boolean fetchESS, String ESSID, String BSSID) 1070 | { 1071 | ArrayList keys = new ArrayList<>(); 1072 | ArrayList gen = new ArrayList<>(); 1073 | ArrayList wpsPins = new ArrayList<>(); 1074 | 1075 | try { 1076 | String val = (fetchESS ? BSSID + '|' + ESSID : BSSID); 1077 | boolean Successes = !bss.isNull(val); 1078 | if (Successes) 1079 | { 1080 | JSONArray rows = bss.getJSONArray(val); 1081 | 1082 | for (int i = 0; i < rows.length(); i++) 1083 | { 1084 | JSONObject row = rows.getJSONObject(i); 1085 | String key = row.getString("key"); 1086 | String wps = row.getString("wps"); 1087 | if (KeyWPSPairExists(keys, wpsPins, key, wps)) 1088 | continue; 1089 | keys.add(key); 1090 | wpsPins.add(wps); 1091 | gen.add(false); 1092 | } 1093 | } 1094 | } 1095 | catch (JSONException e) { 1096 | e.printStackTrace(); 1097 | } 1098 | 1099 | if (keys.size() == 0) 1100 | { 1101 | String PassiveKey = PassiveVulnerabilityTest(ESSID, BSSID); 1102 | if (!PassiveKey.isEmpty()) 1103 | { 1104 | keys.add(PassiveKey); 1105 | gen.add(true); 1106 | wpsPins.add(""); 1107 | } 1108 | } 1109 | 1110 | APData apdata = new APData(); 1111 | apdata.BSSID = BSSID; 1112 | apdata.Keys = keys; 1113 | apdata.Generated = gen; 1114 | apdata.WPS = wpsPins; 1115 | 1116 | return apdata; 1117 | } 1118 | 1119 | public String PassiveVulnerabilityTest(String ESSID, String BSSID) 1120 | { 1121 | String ret = ""; 1122 | if (ESSID.length() > 9) 1123 | { 1124 | if (ESSID.substring(0, 9).equals("MGTS_GPON")) 1125 | { 1126 | ret = BSSID.replace(":", ""); 1127 | ret = ret.substring(4, 12); 1128 | } 1129 | } 1130 | return ret; 1131 | } 1132 | private String getStrSignal(int Signal) { 1133 | String Color = ""; 1134 | Signal = (100 + Signal) * 2; 1135 | Signal = Math.min(Math.max(Signal, 0), 100); 1136 | 1137 | if (Signal < 48) Color = "*[color:red]*"; 1138 | if (Signal >= 48 && Signal < 65) Color = "*[color:yellow]*"; 1139 | if (Signal >= 65) Color = "*[color:greendark]*"; 1140 | 1141 | return Color + Integer.toString(Signal) + "%"; 1142 | } 1143 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/WiFiPasswordSearcher/MyAdapterWps.java: -------------------------------------------------------------------------------- 1 | package com.example.WiFiPasswordSearcher; 2 | 3 | import android.content.*; 4 | import android.view.*; 5 | import android.widget.*; 6 | import java.util.*; 7 | 8 | 9 | public class MyAdapterWps extends BaseAdapter { 10 | 11 | ArrayList data = new ArrayList(); 12 | Context context; 13 | 14 | public MyAdapterWps(Context context, ArrayList arr) { 15 | if (arr != null) { 16 | data = arr; 17 | } 18 | this.context = context; 19 | } 20 | 21 | @Override 22 | public int getCount() { 23 | // TODO Auto-generated method stub 24 | return data.size(); 25 | } 26 | 27 | @Override 28 | public Object getItem(int num) { 29 | // TODO Auto-generated method stub 30 | return data.get(num); 31 | } 32 | 33 | @Override 34 | public long getItemId(int arg0) { 35 | return arg0; 36 | } 37 | 38 | @Override 39 | public View getView(int i, View someView, ViewGroup arg2) { 40 | //Получение объекта inflater из контекста 41 | LayoutInflater inflater = LayoutInflater.from(context); 42 | //Если someView (View из ListView) вдруг оказался равен 43 | //null тогда мы загружаем его с помошью inflater 44 | if (someView == null) { 45 | someView = inflater.inflate(R.layout.list_wps_item, arg2, false); 46 | } 47 | //Обявляем наши текствьюшки и связываем их с разметкой 48 | TextView pin = (TextView) someView.findViewById(R.id.txtPin); 49 | TextView metod = (TextView) someView.findViewById(R.id.txtMetod); 50 | TextView score = (TextView) someView.findViewById(R.id.txtScor); 51 | TextView db = (TextView) someView.findViewById(R.id.txtDb); 52 | // 53 | pin.setText(data.get(i).pin); 54 | metod.setText(data.get(i).metod); 55 | score.setText(data.get(i).score); 56 | db.setText(data.get(i).db); 57 | return someView; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/WiFiPasswordSearcher/ServerSettingsActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.WiFiPasswordSearcher; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | import android.text.InputType; 6 | import android.view.View; 7 | import android.widget.*; 8 | 9 | public class ServerSettingsActivity extends Activity 10 | { 11 | 12 | private EditText txtServerLogin = null; 13 | private EditText txtServerPassword = null; 14 | private EditText txtServerUri = null; 15 | private Switch swFetchESS = null; 16 | private Switch swCheckUpd = null; 17 | 18 | Button btnCancel = null; 19 | Button btnSave = null; 20 | 21 | Settings mSettings; 22 | 23 | protected void onCreate(Bundle savedInstanceState) 24 | { 25 | super.onCreate(savedInstanceState); 26 | setContentView(R.layout.server_settings); 27 | 28 | txtServerLogin = (EditText) findViewById(R.id.txt_settings_3wifi_login); 29 | txtServerPassword = (EditText) findViewById(R.id.txt_settings_3wifi_password); 30 | txtServerUri = (EditText) findViewById(R.id.txt_settings_3wifi_server); 31 | swFetchESS = (Switch) findViewById(R.id.sw_fetch_ess); 32 | swCheckUpd = (Switch) findViewById(R.id.sw_check_upd); 33 | 34 | btnCancel = (Button) findViewById(R.id.btn_settitgs_3wifi_cancel); 35 | btnSave = (Button) findViewById(R.id.btn_settitgs_3wifi_save); 36 | 37 | mSettings = new Settings(getApplicationContext()); 38 | mSettings.Reload(); 39 | 40 | String SERVER_LOGIN = mSettings.AppSettings.getString(Settings.APP_SERVER_LOGIN, ""); 41 | String SERVER_PASSWORD = mSettings.AppSettings.getString(Settings.APP_SERVER_PASSWORD, ""); 42 | String SERVER_URI = mSettings.AppSettings.getString(Settings.APP_SERVER_URI, getResources().getString(R.string.SERVER_URI_DEFAULT)); 43 | Boolean FETCH_ESS = mSettings.AppSettings.getBoolean(Settings.APP_FETCH_ESS, false); 44 | Boolean CHECK_UPDATES = mSettings.AppSettings.getBoolean(Settings.APP_CHECK_UPDATES, true); 45 | 46 | txtServerLogin.setText(SERVER_LOGIN); 47 | txtServerPassword.setText(SERVER_PASSWORD); 48 | txtServerUri.setText(SERVER_URI); 49 | swFetchESS.setChecked(FETCH_ESS); 50 | swCheckUpd.setChecked(CHECK_UPDATES); 51 | 52 | btnCancel.setOnClickListener(btnCloseOnClick); 53 | btnSave.setOnClickListener(btnSaveOnClick); 54 | } 55 | private View.OnClickListener btnCloseOnClick = new View.OnClickListener() 56 | { 57 | public void onClick(View v) 58 | { 59 | finish(); 60 | } 61 | }; 62 | private View.OnClickListener btnSaveOnClick = new View.OnClickListener() 63 | { 64 | public void onClick(View v) 65 | { 66 | String Login = txtServerLogin.getText().toString(); 67 | String Password = txtServerPassword.getText().toString(); 68 | String Uri = txtServerUri.getText().toString(); 69 | Boolean FetchESS = swFetchESS.isChecked(); 70 | Boolean CheckUpdates = swCheckUpd.isChecked(); 71 | 72 | // Save 73 | mSettings.Editor.putString(Settings.APP_SERVER_LOGIN, Login); 74 | mSettings.Editor.putString(Settings.APP_SERVER_PASSWORD, Password); 75 | mSettings.Editor.putString(Settings.APP_SERVER_URI, Uri); 76 | mSettings.Editor.putBoolean(Settings.APP_FETCH_ESS, FetchESS); 77 | mSettings.Editor.putBoolean(Settings.APP_CHECK_UPDATES, CheckUpdates); 78 | mSettings.Editor.commit(); 79 | 80 | finish(); 81 | } 82 | }; 83 | 84 | public void cbUnmaskClick(View view) 85 | { 86 | int eType = txtServerPassword.getInputType(); 87 | if (((CheckBox)view).isChecked()) { 88 | txtServerPassword.setInputType(eType & ~InputType.TYPE_TEXT_VARIATION_PASSWORD); 89 | } 90 | else { 91 | txtServerPassword.setInputType(eType | InputType.TYPE_TEXT_VARIATION_PASSWORD); 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/WiFiPasswordSearcher/Settings.java: -------------------------------------------------------------------------------- 1 | package com.example.WiFiPasswordSearcher; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | 6 | 7 | /** 8 | * Created by пк on 19.11.2015. 9 | */ 10 | public class Settings 11 | { 12 | public static final String APP_PREFERENCES = "settings"; 13 | public static final String APP_SERVER_LOGIN = "SERVER_LOGIN"; 14 | public static final String APP_SERVER_PASSWORD = "SERVER_PASSWORD"; 15 | public static final String APP_SERVER_URI = "SERVER_URI"; 16 | public static final String APP_FETCH_ESS = "FETCH_ESS"; 17 | public static final String APP_CHECK_UPDATES = "CHECK_UPDATES"; 18 | public static final String API_READ_KEY = "READ_KEY"; 19 | public static final String API_WRITE_KEY = "WRITE_KEY"; 20 | public static final String API_KEYS_VALID = "KEYS_VALID"; 21 | public static final String USER_REGDATE = "USER_REGDATE"; 22 | public static final String USER_NICK = "USER_NICK"; 23 | public static final String USER_GROUP = "USER_GROUP"; 24 | public static final String WIFI_SIGNAL = "WIFI_SIGNAL"; 25 | public static final String WPS_SOURCE = "WPS_SOURCE"; 26 | 27 | 28 | public SharedPreferences AppSettings = null; 29 | public SharedPreferences.Editor Editor = null; 30 | 31 | private Context context; 32 | 33 | public Settings(Context _context) 34 | { 35 | context = _context; 36 | Init(); 37 | } 38 | 39 | private void Init() 40 | { 41 | AppSettings = context.getSharedPreferences(APP_PREFERENCES, context.MODE_PRIVATE); 42 | Editor = AppSettings.edit(); 43 | } 44 | 45 | public void Reload() 46 | { 47 | Init(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/WiFiPasswordSearcher/SettingsActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.WiFiPasswordSearcher; 2 | 3 | import android.app.Activity; 4 | import android.app.AlertDialog; 5 | import android.content.DialogInterface; 6 | import android.content.Intent; 7 | import android.os.Bundle; 8 | import android.text.InputType; 9 | import android.view.View; 10 | import android.widget.*; 11 | 12 | import java.util.HashMap; 13 | 14 | public class SettingsActivity extends Activity { 15 | /** 16 | * Called when the activity is first created. 17 | */ 18 | 19 | protected void onCreate(Bundle savedInstanceState) 20 | { 21 | super.onCreate(savedInstanceState); 22 | setContentView(R.layout.settings); 23 | 24 | ListView GeneralListView = (ListView) findViewById(R.id.SettingsListView); 25 | 26 | String[] strSettingsRows = getResources().getStringArray(R.array.strings_settings_rows); 27 | ArrayAdapter adapterSettingsListView = new ArrayAdapter(this, android.R.layout.simple_list_item_1, strSettingsRows); 28 | GeneralListView.setAdapter(adapterSettingsListView); 29 | 30 | GeneralListView.setOnItemClickListener(GeneralListOnClick); 31 | } 32 | 33 | private AdapterView.OnItemClickListener GeneralListOnClick = new AdapterView.OnItemClickListener() 34 | { 35 | public void onItemClick(AdapterView parent, View Item, int position, long id) 36 | { 37 | TextView txtItem = (TextView) Item; 38 | 39 | switch((int)id) 40 | { 41 | case 0: // 3WiFi settings 42 | Intent ServerSettingsIntent = new Intent(SettingsActivity.this, ServerSettingsActivity.class); 43 | startActivity(ServerSettingsIntent); 44 | break; 45 | case 1: // Manage WPS PIN Companion 46 | Intent userActivity = new Intent(SettingsActivity.this, UserInfoActivity.class); 47 | userActivity.putExtra("showInfo", "wpspin"); 48 | startActivity(userActivity); 49 | break; 50 | case 2: // Monitor a network 51 | LinearLayout lay = new LinearLayout(SettingsActivity.this); 52 | lay.setOrientation(LinearLayout.VERTICAL); 53 | 54 | final EditText ebss = new EditText(SettingsActivity.this); 55 | ebss.setHint("Enter BSSID (11:22:33:44:55:66)"); 56 | ebss.setInputType(InputType.TYPE_CLASS_TEXT); 57 | lay.addView(ebss); 58 | 59 | final EditText eess = new EditText(SettingsActivity.this); 60 | eess.setHint("Enter ESSID"); 61 | eess.setInputType(InputType.TYPE_CLASS_TEXT); 62 | lay.addView(eess); 63 | 64 | AlertDialog.Builder alert = new AlertDialog.Builder(SettingsActivity.this); 65 | alert.setTitle("Enter network properties"); 66 | alert.setView(lay); 67 | 68 | alert.setPositiveButton("OK", new DialogInterface.OnClickListener() 69 | { 70 | @Override 71 | public void onClick(DialogInterface dialog, int which) 72 | { 73 | Intent detailsActivityIntent = new Intent(SettingsActivity.this, WifiDetails.class); 74 | HashMap WifiInfo = new HashMap(); 75 | WifiInfo.put("BSSID", ebss.getText().toString().toLowerCase()); 76 | WifiInfo.put("SSID", eess.getText().toString()); 77 | WifiInfo.put("Freq", "0"); 78 | WifiInfo.put("Signal", "-100"); 79 | 80 | finish(); 81 | detailsActivityIntent.putExtra("WifiInfo", WifiInfo); 82 | startActivity(detailsActivityIntent); 83 | } 84 | }); 85 | alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() 86 | { 87 | @Override 88 | public void onClick(DialogInterface dialog, int which) 89 | { 90 | dialog.cancel(); 91 | } 92 | }); 93 | 94 | alert.show(); 95 | break; 96 | case 3: // About 97 | Intent AboutInfoIntent = new Intent(SettingsActivity.this, AboutActivity.class); 98 | startActivity(AboutInfoIntent); 99 | break; 100 | case 4: // Check updates 101 | AppVersion Version = new AppVersion(getApplicationContext()); 102 | if (!Version.isActualyVersion(getApplicationContext(), true)) 103 | { 104 | Version.ShowUpdateDialog(SettingsActivity.this); 105 | } 106 | break; 107 | case 5: // Logout 108 | Settings mSettings = new Settings(getApplicationContext()); 109 | mSettings.Reload(); 110 | mSettings.Editor.remove(Settings.APP_SERVER_LOGIN); 111 | mSettings.Editor.remove(Settings.APP_SERVER_PASSWORD); 112 | mSettings.Editor.remove(Settings.API_READ_KEY); 113 | mSettings.Editor.remove(Settings.API_WRITE_KEY); 114 | mSettings.Editor.remove(Settings.API_KEYS_VALID); 115 | mSettings.Editor.commit(); 116 | 117 | Intent StartPage = new Intent(getApplicationContext(), StartActivity.class); 118 | StartPage.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); 119 | startActivity(StartPage); 120 | break; 121 | } 122 | } 123 | }; 124 | } 125 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/WiFiPasswordSearcher/StartActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.WiFiPasswordSearcher; 2 | 3 | import android.app.Activity; 4 | import android.app.AlertDialog; 5 | import android.app.ProgressDialog; 6 | import android.content.DialogInterface; 7 | import android.content.Intent; 8 | import android.content.res.Configuration; 9 | import android.os.Bundle; 10 | import android.view.View; 11 | import android.widget.Button; 12 | import android.widget.EditText; 13 | import android.widget.LinearLayout; 14 | import android.widget.Toast; 15 | 16 | import org.json.JSONArray; 17 | import org.json.JSONException; 18 | import org.json.JSONObject; 19 | 20 | import java.io.*; 21 | import java.net.HttpURLConnection; 22 | import java.net.URL; 23 | import java.net.URLEncoder; 24 | 25 | /** 26 | * Created by пк on 20.12.2015. 27 | */ 28 | public class StartActivity extends Activity { 29 | 30 | private Settings mSettings; 31 | private static Boolean VersionAlreadyChecked = false; 32 | private UserManager User; 33 | 34 | public EditText edtLogin = null; 35 | public EditText edtPassword = null; 36 | public Button btnGetKeys = null; 37 | public Button btnStart = null; 38 | public Button btnUserInfo = null; 39 | public LinearLayout llMenu = null; 40 | 41 | public void onCreate(Bundle savedInstanceState) 42 | { 43 | super.onCreate(savedInstanceState); 44 | setContentView(R.layout.start); 45 | this.onConfigurationChanged(getResources().getConfiguration()); 46 | 47 | mSettings = new Settings(getApplicationContext()); 48 | User = new UserManager(getApplicationContext()); 49 | 50 | edtLogin = (EditText)findViewById(R.id.edtLogin); 51 | edtPassword = (EditText)findViewById(R.id.edtPassword); 52 | 53 | llMenu = (LinearLayout)findViewById(R.id.llStartMenu); 54 | btnGetKeys = (Button)findViewById(R.id.btnGetApiKeys); 55 | btnStart = (Button)findViewById(R.id.btnStart); 56 | btnUserInfo = (Button)findViewById(R.id.btnUserInfo); 57 | 58 | Boolean API_KEYS_VALID = mSettings.AppSettings.getBoolean(Settings.API_KEYS_VALID, false); 59 | String SavedLogin = mSettings.AppSettings.getString(Settings.APP_SERVER_LOGIN, ""); 60 | String SavedPassword = mSettings.AppSettings.getString(Settings.APP_SERVER_PASSWORD, ""); 61 | Boolean CHECK_UPDATES = mSettings.AppSettings.getBoolean(Settings.APP_CHECK_UPDATES, true); 62 | 63 | if (API_KEYS_VALID) 64 | { 65 | btnGetKeys.setVisibility(View.GONE); 66 | edtLogin.setEnabled(false); 67 | edtPassword.setEnabled(false); 68 | llMenu.setVisibility(View.VISIBLE); 69 | 70 | if (CHECK_UPDATES && !VersionAlreadyChecked) 71 | { 72 | new Thread(new Runnable() { 73 | @Override 74 | public void run() { 75 | final AppVersion Version = new AppVersion(getApplicationContext()); 76 | Boolean Result = Version.isActualyVersion(getApplicationContext(), false); 77 | if (!Result) 78 | { 79 | runOnUiThread(new Runnable() { 80 | @Override 81 | public void run() 82 | { 83 | Version.ShowUpdateDialog(StartActivity.this); 84 | } 85 | }); 86 | } 87 | VersionAlreadyChecked = true; 88 | } 89 | }).start(); 90 | } 91 | } 92 | 93 | edtLogin.setText(SavedLogin); 94 | edtPassword.setText(SavedPassword); 95 | 96 | btnGetKeys.setOnClickListener(new View.OnClickListener() { 97 | @Override 98 | public void onClick(View v) { 99 | final ProgressDialog dProccess = new ProgressDialog(StartActivity.this); 100 | dProccess.setProgressStyle(ProgressDialog.STYLE_SPINNER); 101 | dProccess.setMessage("Signing in..."); 102 | dProccess.setCanceledOnTouchOutside(false); 103 | dProccess.show(); 104 | 105 | new Thread(new Runnable() { 106 | @Override 107 | public void run() { 108 | Boolean res = false; 109 | 110 | try { 111 | res = getApiKeys(edtLogin.getText().toString(), edtPassword.getText().toString()); 112 | } catch (IOException e) { 113 | e.printStackTrace(); 114 | } 115 | if (res) 116 | { 117 | User.getFromSettings(); 118 | 119 | runOnUiThread(new Runnable() { 120 | @Override 121 | public void run() { 122 | btnGetKeys.setVisibility(View.GONE); 123 | llMenu.setVisibility(View.VISIBLE); 124 | edtLogin.setEnabled(false); 125 | edtPassword.setEnabled(false); 126 | } 127 | }); 128 | } 129 | dProccess.dismiss(); 130 | } 131 | }).start(); 132 | } 133 | }); 134 | 135 | btnUserInfo.setOnClickListener(new View.OnClickListener() { 136 | @Override 137 | public void onClick(View v) { 138 | Intent userActivity = new Intent(StartActivity.this, UserInfoActivity.class); 139 | userActivity.putExtra("showInfo", "user"); 140 | startActivity(userActivity); 141 | } 142 | }); 143 | btnStart.setOnClickListener(new View.OnClickListener() { 144 | @Override 145 | public void onClick(View v) { 146 | Intent mainActivity = new Intent(StartActivity.this, MyActivity.class); 147 | startActivity(mainActivity); 148 | finish(); 149 | } 150 | }); 151 | } 152 | 153 | public void onConfigurationChanged(Configuration newConfig) 154 | { 155 | super.onConfigurationChanged(newConfig); 156 | 157 | LinearLayout LR = (LinearLayout)findViewById(R.id.rootLayout); 158 | LinearLayout LP = (LinearLayout)findViewById(R.id.layoutPadding); 159 | 160 | if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) 161 | { 162 | LR.setOrientation(LinearLayout.VERTICAL); 163 | LP.setVisibility(View.VISIBLE); 164 | } 165 | else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) 166 | { 167 | LR.setOrientation(LinearLayout.HORIZONTAL); 168 | LP.setVisibility(View.GONE); 169 | } 170 | } 171 | 172 | private boolean getApiKeys(String Login, String Password) throws IOException 173 | { 174 | String Args = "/api/apikeys"; 175 | BufferedReader Reader; 176 | String ReadLine; 177 | String RawData = ""; 178 | 179 | try { 180 | mSettings.Reload(); 181 | String SERVER_URI = mSettings.AppSettings.getString(Settings.APP_SERVER_URI, getResources().getString(R.string.SERVER_URI_DEFAULT)); 182 | URL Uri = new URL(SERVER_URI + Args); 183 | 184 | HttpURLConnection Connection = (HttpURLConnection) Uri.openConnection(); 185 | Connection.setRequestMethod("POST"); 186 | Connection.setDoOutput(true); 187 | Connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 188 | 189 | DataOutputStream writer = new DataOutputStream ( 190 | Connection.getOutputStream()); 191 | writer.writeBytes( 192 | "login=" + URLEncoder.encode(Login, "UTF-8") + 193 | "&password=" + URLEncoder.encode(Password, "UTF-8") + 194 | "&genread=1"); 195 | 196 | Connection.setReadTimeout(10 * 1000); 197 | Connection.connect(); 198 | 199 | Reader = new BufferedReader(new InputStreamReader(Connection.getInputStream())); 200 | 201 | while ((ReadLine = Reader.readLine()) != null) { 202 | RawData += ReadLine; 203 | } 204 | 205 | try 206 | { 207 | String ReadApiKey = null, WriteApiKey = null; 208 | JSONObject Json = new JSONObject(RawData); 209 | Boolean Successes = Json.getBoolean("result"); 210 | if (Successes) 211 | { 212 | JSONObject profile = Json.getJSONObject("profile"); 213 | 214 | JSONArray keys = Json.getJSONArray("data"); 215 | for (int i = 0; i < keys.length(); i++) 216 | { 217 | JSONObject keyData = keys.getJSONObject(i); 218 | String access = keyData.getString("access"); 219 | 220 | if (access.equals("read")) 221 | { 222 | ReadApiKey = keyData.getString("key"); 223 | } 224 | else if (access.equals("write")) 225 | { 226 | WriteApiKey = keyData.getString("key"); 227 | } 228 | if (ReadApiKey != null && WriteApiKey != null) 229 | break; 230 | } 231 | 232 | if (ReadApiKey == null) 233 | { 234 | runOnUiThread(new Runnable() { 235 | @Override 236 | public void run() { 237 | Toast t = Toast.makeText(getApplicationContext(), "No API keys received.", Toast.LENGTH_SHORT); 238 | t.show(); 239 | } 240 | }); 241 | return false; 242 | } 243 | 244 | mSettings.Editor.putString(Settings.APP_SERVER_LOGIN, Login); 245 | mSettings.Editor.putString(Settings.APP_SERVER_PASSWORD, Password); 246 | mSettings.Editor.putString(Settings.API_READ_KEY, ReadApiKey); 247 | mSettings.Editor.putString(Settings.API_WRITE_KEY, WriteApiKey); 248 | mSettings.Editor.putBoolean(Settings.API_KEYS_VALID, true); 249 | mSettings.Editor.putString(Settings.USER_NICK, profile.getString("nick")); 250 | mSettings.Editor.putString(Settings.USER_REGDATE, profile.getString("regdate")); 251 | mSettings.Editor.putInt(Settings.USER_GROUP, profile.getInt("level")); 252 | mSettings.Editor.commit(); 253 | 254 | return true; 255 | } 256 | else 257 | { 258 | String error = Json.getString("error"); 259 | final String errorDesc = User.GetErrorDesc(error); 260 | 261 | if (error != null) { 262 | runOnUiThread(new Runnable() { 263 | @Override 264 | public void run() { 265 | Toast t = Toast.makeText(getApplicationContext(), errorDesc, Toast.LENGTH_SHORT); 266 | t.show(); 267 | } 268 | }); 269 | } 270 | return false; 271 | } 272 | } 273 | catch (JSONException e) 274 | { 275 | e.printStackTrace(); 276 | } 277 | } 278 | catch (Exception e) 279 | { 280 | e.printStackTrace(); 281 | } 282 | runOnUiThread(new Runnable() 283 | { 284 | @Override 285 | public void run() 286 | { 287 | DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() 288 | { 289 | @Override 290 | public void onClick(DialogInterface dialog, int which) 291 | { 292 | switch (which) 293 | { 294 | case DialogInterface.BUTTON_POSITIVE: 295 | btnOffline(null); 296 | break; 297 | case DialogInterface.BUTTON_NEGATIVE: 298 | break; 299 | } 300 | dialog.dismiss(); 301 | } 302 | }; 303 | AlertDialog.Builder builder = new AlertDialog.Builder(StartActivity.this); 304 | builder.setTitle("No internet connection") 305 | .setMessage("Do you want to work in offline mode?") 306 | .setPositiveButton("Yes", dialogClickListener) 307 | .setNegativeButton("No", dialogClickListener).show(); 308 | } 309 | }); 310 | return false; 311 | } 312 | 313 | public void btnOffline(View view) 314 | { 315 | mSettings.Editor.putString(Settings.API_READ_KEY, "offline"); 316 | mSettings.Editor.commit(); 317 | Intent offlineActivityIntent = new Intent(StartActivity.this, MyActivity.class); 318 | startActivity(offlineActivityIntent); 319 | } 320 | } 321 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/WiFiPasswordSearcher/UserInfoActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.WiFiPasswordSearcher; 2 | 3 | import android.app.Activity; 4 | import android.app.ProgressDialog; 5 | import android.os.AsyncTask; 6 | import android.os.Bundle; 7 | import android.view.View; 8 | import android.widget.Button; 9 | import android.widget.LinearLayout; 10 | import android.widget.TextView; 11 | import android.widget.Toast; 12 | 13 | import org.apache.http.client.ResponseHandler; 14 | import org.apache.http.client.methods.HttpGet; 15 | import org.apache.http.impl.client.BasicResponseHandler; 16 | import org.apache.http.impl.client.DefaultHttpClient; 17 | 18 | import java.text.DateFormat; 19 | import java.text.SimpleDateFormat; 20 | import java.util.Date; 21 | import java.util.Locale; 22 | 23 | /** 24 | * Created by пк on 20.12.2015. 25 | */ 26 | public class UserInfoActivity extends Activity { 27 | 28 | public TextView txtLogin = null; 29 | public TextView txtRegDate = null; 30 | public TextView txtGroup = null; 31 | private String info; 32 | 33 | public void onCreate(Bundle savedInstanceState) { 34 | super.onCreate(savedInstanceState); 35 | setContentView(R.layout.user); 36 | 37 | Settings mSettings = new Settings(getApplicationContext()); 38 | 39 | try { 40 | info = getIntent().getExtras().getString("showInfo"); 41 | } 42 | catch (Exception e) { 43 | info = "user"; 44 | } 45 | 46 | txtLogin = (TextView) findViewById(R.id.txtLogin); 47 | txtRegDate = (TextView) findViewById(R.id.txtRegDate); 48 | txtGroup = (TextView) findViewById(R.id.txtGroup); 49 | 50 | String Nick, Group; 51 | Date date; 52 | 53 | if (info != null && info.equals("wpspin")) 54 | { 55 | AppVersion updater = new AppVersion(getApplicationContext()); 56 | updater.wpsCompanionInit(false); 57 | 58 | LinearLayout lButtons = (LinearLayout) findViewById(R.id.buttonsLayout); 59 | lButtons.setVisibility(LinearLayout.VISIBLE); 60 | Button btnRevert = (Button) findViewById(R.id.btnRevert); 61 | btnRevert.setEnabled(!updater.wpsCompanionInternal()); 62 | 63 | TextView lReg = (TextView) findViewById(R.id.labRegDate); 64 | TextView lGroup = (TextView) findViewById(R.id.labGroup); 65 | 66 | Nick = "WPS PIN Companion"; 67 | lReg.setText("Last Updated"); 68 | date = updater.wpsCompanionGetDate(); 69 | lGroup.setText("File Size"); 70 | long size = updater.wpsCompanionGetSize(); 71 | Group = updater.readableFileSize(size); 72 | } 73 | else 74 | { 75 | UserManager User = new UserManager(getApplicationContext()); 76 | User.getFromSettings(); 77 | 78 | LinearLayout lButtons = (LinearLayout) findViewById(R.id.buttonsLayout); 79 | lButtons.setVisibility(LinearLayout.GONE); 80 | 81 | SimpleDateFormat format = new SimpleDateFormat(getResources().getString(R.string.DEFAULT_DATE_FORMAT), Locale.US); 82 | try { 83 | date = format.parse(User.RegDate); 84 | } catch (Exception e) { 85 | date = new Date(); 86 | } 87 | 88 | Nick = User.NickName; 89 | Group = User.GetGroup(); 90 | } 91 | 92 | txtLogin.setText(Nick); 93 | txtRegDate.setText(DateFormat.getDateTimeInstance().format(date)); 94 | txtGroup.setText(Group); 95 | } 96 | 97 | private class AsyncWpsUpdater extends AsyncTask 98 | { 99 | private ProgressDialog pd; 100 | private Toast toast; 101 | 102 | @Override 103 | protected void onPreExecute() 104 | { 105 | super.onPreExecute(); 106 | pd = new ProgressDialog(UserInfoActivity.this); 107 | pd.setProgressStyle(ProgressDialog.STYLE_SPINNER); 108 | pd.setMessage("Updating component..."); 109 | pd.setCanceledOnTouchOutside(false); 110 | pd.show(); 111 | } 112 | 113 | protected String doInBackground(String[] input) 114 | { 115 | DefaultHttpClient hc = new DefaultHttpClient(); 116 | ResponseHandler res = new BasicResponseHandler(); 117 | 118 | Settings mSettings = new Settings(getApplicationContext()); 119 | mSettings.Reload(); 120 | String SERVER_URI = mSettings.AppSettings.getString(Settings.APP_SERVER_URI, getResources().getString(R.string.SERVER_URI_DEFAULT)); 121 | HttpGet http = new HttpGet(SERVER_URI + "/wpspin"); 122 | String str = ""; 123 | try 124 | { 125 | str = hc.execute(http, res); 126 | } 127 | catch (Exception e) {} 128 | 129 | return str; 130 | } 131 | 132 | @Override 133 | protected void onPostExecute(String str) 134 | { 135 | String msg; 136 | pd.dismiss(); 137 | 138 | if (str.contains("initAlgos();")) 139 | { 140 | AppVersion updater = new AppVersion(getApplicationContext()); 141 | updater.wpsCompanionUpdate(str, new Date()); 142 | txtRegDate.setText(DateFormat.getDateTimeInstance().format(updater.wpsCompanionGetDate())); 143 | txtGroup.setText(updater.readableFileSize(updater.wpsCompanionGetSize())); 144 | Button btnRevert = (Button) findViewById(R.id.btnRevert); 145 | btnRevert.setEnabled(!updater.wpsCompanionInternal()); 146 | msg = "Update successful!"; 147 | } 148 | else if (str.length() == 0) 149 | { 150 | msg = "No internet connection"; 151 | } 152 | else 153 | { 154 | msg = "Update failed"; 155 | } 156 | toast = Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT); 157 | toast.show(); 158 | } 159 | } 160 | 161 | public void btnUpdateOnClick(View v) 162 | { 163 | if (info != null && info.equals("wpspin")) 164 | { 165 | new AsyncWpsUpdater().execute(); 166 | } 167 | } 168 | 169 | public void btnRevertOnClick(View v) 170 | { 171 | if (info != null && info.equals("wpspin")) 172 | { 173 | AppVersion updater = new AppVersion(getApplicationContext()); 174 | updater.wpsCompanionInit(true); 175 | txtRegDate.setText(DateFormat.getDateTimeInstance().format(updater.wpsCompanionGetDate())); 176 | txtGroup.setText(updater.readableFileSize(updater.wpsCompanionGetSize())); 177 | v.setEnabled(!updater.wpsCompanionInternal()); 178 | Toast toast = Toast.makeText(getApplicationContext(), 179 | "Reverted to initial state", Toast.LENGTH_SHORT); 180 | toast.show(); 181 | } 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/WiFiPasswordSearcher/UserManager.java: -------------------------------------------------------------------------------- 1 | package com.example.WiFiPasswordSearcher; 2 | 3 | import android.content.Context; 4 | import org.json.JSONException; 5 | import org.json.JSONObject; 6 | 7 | import java.io.*; 8 | import java.net.HttpURLConnection; 9 | import java.net.MalformedURLException; 10 | import java.net.ProtocolException; 11 | import java.net.URL; 12 | 13 | /** 14 | * Created by пк on 20.12.2015. 15 | */ 16 | public class UserManager { 17 | private Settings mSettings = null; 18 | private String APP_VERSION = ""; 19 | private String API_READ_KEY = ""; 20 | 21 | public String Login = ""; 22 | public String NickName = ""; 23 | public String RegDate = ""; 24 | public Integer Level = -1; 25 | 26 | UserManager(Context context) { 27 | APP_VERSION = context.getResources().getString(R.string.app_version); 28 | mSettings = new Settings(context); 29 | API_READ_KEY = mSettings.AppSettings.getString(Settings.API_READ_KEY, ""); 30 | Login = mSettings.AppSettings.getString(Settings.APP_SERVER_LOGIN, ""); 31 | } 32 | 33 | public void getFromSettings() 34 | { 35 | NickName = mSettings.AppSettings.getString(Settings.USER_NICK, ""); 36 | RegDate = mSettings.AppSettings.getString(Settings.USER_REGDATE, ""); 37 | Level = mSettings.AppSettings.getInt(Settings.USER_GROUP, -1); 38 | } 39 | 40 | public String GetGroup() 41 | { 42 | return GetTextGroup(Level); 43 | } 44 | 45 | public String GetTextGroup(Integer Level) 46 | { 47 | switch (Level) 48 | { 49 | case -2: return "Banned"; 50 | case -1: return "No logged"; 51 | case 0: return "Guest"; 52 | case 1: return "User"; 53 | case 2: return "Developer"; 54 | case 3: return "Administrator"; 55 | } 56 | return ""; 57 | } 58 | 59 | public String GetErrorDesc(String error) 60 | { 61 | if (error.equals("database")) 62 | return "Database maintenance, try again later"; 63 | if (error.equals("loginfail")) 64 | return "Username or password incorrect"; 65 | if (error.equals("form")) 66 | return "Please fill required form fields"; 67 | return "Unknown Error: " + error; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/WiFiPasswordSearcher/WPSActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.WiFiPasswordSearcher; 2 | 3 | import android.app.*; 4 | import android.content.*; 5 | import android.database.*; 6 | import android.database.sqlite.*; 7 | import android.graphics.*; 8 | import android.net.wifi.WifiManager; 9 | import android.net.wifi.WifiManager.WpsCallback; 10 | import android.net.wifi.WpsInfo; 11 | import android.os.*; 12 | import android.text.InputType; 13 | import android.view.*; 14 | import android.webkit.*; 15 | import android.widget.*; 16 | import java.io.*; 17 | import java.util.*; 18 | import org.apache.http.client.*; 19 | import org.apache.http.client.methods.*; 20 | import org.apache.http.impl.client.*; 21 | import org.json.*; 22 | 23 | 24 | class WPSPin 25 | { 26 | public int mode; 27 | public String name; 28 | public String pin; 29 | public Boolean sugg; 30 | } 31 | 32 | public class WPSActivity extends Activity 33 | { 34 | private WebView mWebView; 35 | private WifiManager WifiMgr; 36 | 37 | ArrayList data = new ArrayList(); 38 | ArrayList pins = new ArrayList(); 39 | ProgressDialog pd = null; 40 | private Settings mSettings; 41 | private WpsCallback wpsCallback; 42 | private Boolean wpsConnecting = false; 43 | private String wpsLastPin = ""; 44 | public static String API_READ_KEY = ""; 45 | 46 | ArrayList wpsPin = new ArrayList(); 47 | ArrayList wpsMet = new ArrayList(); 48 | ArrayList wpsScore = new ArrayList(); 49 | ArrayList wpsDb = new ArrayList(); 50 | 51 | private DatabaseHelper mDBHelper; 52 | private SQLiteDatabase mDb; 53 | private volatile boolean wpsReady = false; 54 | private String cachedPins = ""; 55 | 56 | private static final String[] listContextMenuItems = new String[]{ 57 | "Connect using WPS... (without root)", 58 | "Copy this WPS PIN" 59 | }; 60 | 61 | public void onCreate(Bundle savedInstanceState) 62 | { 63 | super.onCreate(savedInstanceState); 64 | setContentView(R.layout.wps); 65 | 66 | mDBHelper = new DatabaseHelper(this); 67 | try 68 | { 69 | mDBHelper.updateDataBase(); 70 | } 71 | catch (IOException mIOException) 72 | { 73 | throw new Error("UnableToUpdateDatabase"); 74 | } 75 | 76 | try 77 | { 78 | mDb = mDBHelper.getWritableDatabase(); 79 | } 80 | catch (SQLException mSQLException) 81 | { 82 | throw mSQLException; 83 | } 84 | 85 | if (android.os.Build.VERSION.SDK_INT > 9) 86 | { 87 | StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); 88 | StrictMode.setThreadPolicy(policy); 89 | } 90 | mSettings = new Settings(getApplicationContext()); 91 | 92 | API_READ_KEY = mSettings.AppSettings.getString(Settings.API_READ_KEY, ""); 93 | 94 | ActionBar actionBar = getActionBar(); 95 | actionBar.hide(); 96 | 97 | TextView ESSDWpsText = (TextView)findViewById(R.id.ESSDWpsTextView); 98 | String ESSDWps = getIntent().getExtras().getString("variable"); 99 | ESSDWpsText.setText(ESSDWps); // ESSID 100 | TextView BSSDWpsText = (TextView)findViewById(R.id.BSSDWpsTextView); 101 | final String BSSDWps = getIntent().getExtras().getString("variable1"); 102 | BSSDWpsText.setText(BSSDWps); // BSSID 103 | 104 | WifiMgr = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); 105 | wpsCallback = null; 106 | 107 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 108 | { 109 | wpsCallback = new WpsCallback() 110 | { 111 | @Override 112 | public void onStarted(String pin) { 113 | wpsConnecting = true; 114 | pd = new ProgressDialog(WPSActivity.this); 115 | pd.setProgressStyle(ProgressDialog.STYLE_SPINNER); 116 | pd.setMessage("Connecting to the network..."); 117 | pd.setCanceledOnTouchOutside(false); 118 | pd.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() 119 | { 120 | @Override 121 | public void onClick(DialogInterface dialog, int which) { 122 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 123 | { 124 | WifiMgr.cancelWps(wpsCallback); 125 | } 126 | wpsConnecting = false; 127 | dialog.dismiss(); 128 | Toast.makeText(getApplicationContext(), "Connection cancelled", Toast.LENGTH_SHORT).show(); 129 | } 130 | }); 131 | pd.show(); 132 | } 133 | 134 | @Override 135 | public void onSucceeded() { 136 | if (!wpsConnecting) 137 | return; 138 | wpsConnecting = false; 139 | pd.dismiss(); 140 | Toast.makeText(getApplicationContext(), "Connected successfully!", Toast.LENGTH_SHORT).show(); 141 | } 142 | 143 | @Override 144 | public void onFailed(int reason) { 145 | if (!wpsConnecting && reason > 2) 146 | return; 147 | wpsConnecting = false; 148 | pd.dismiss(); 149 | String title = "An error occurred"; 150 | String errorMessage; 151 | switch (reason) { 152 | case 0: // Generic failure 153 | if (wpsLastPin.isEmpty()) { 154 | title = "WPS connection failed"; 155 | errorMessage = "Your device does not support entering pin via WPS. You could try again, or use root mode."; 156 | } 157 | else { 158 | errorMessage = "Generic failure - something went wrong. Try turning your Wi-Fi interface off and on, then try again. If this doesn't help, try restarting your device."; 159 | } 160 | break; 161 | case 1: // In progress 162 | errorMessage = "Operation currently in progress."; 163 | break; 164 | case 2: // Busy 165 | errorMessage = "Wi-Fi interface is busy."; 166 | break; 167 | case WifiManager.WPS_OVERLAP_ERROR: 168 | errorMessage = "Another WPS transaction is in progress."; 169 | break; 170 | case WifiManager.WPS_WEP_PROHIBITED: 171 | errorMessage = "WEP encryption prohibited."; 172 | break; 173 | case WifiManager.WPS_TKIP_ONLY_PROHIBITED: 174 | errorMessage = "TKIP-only encryption prohibited."; 175 | break; 176 | case WifiManager.WPS_AUTH_FAILURE: 177 | errorMessage = "Selected WPS PIN is not correct."; 178 | break; 179 | case WifiManager.WPS_TIMED_OUT: 180 | title = "WPS connection timeout"; 181 | errorMessage = "The network did not respond " + 182 | "due to low signal or some other reasons. " + 183 | "You may try again."; 184 | break; 185 | default: 186 | title = "OH SHI*"; 187 | errorMessage = "Unexpected error " + reason; 188 | break; 189 | } 190 | 191 | AlertDialog.Builder builder = new AlertDialog.Builder(WPSActivity.this); 192 | builder.setTitle(title) 193 | .setMessage(errorMessage) 194 | .setCancelable(false) 195 | .setPositiveButton("OK", new DialogInterface.OnClickListener() { 196 | public void onClick(DialogInterface dialog, int id) { 197 | dialog.dismiss(); 198 | } 199 | }); 200 | AlertDialog alert = builder.create(); 201 | alert.show(); 202 | } 203 | }; 204 | } 205 | 206 | ListView wpslist = (ListView)findViewById(R.id.WPSlist); 207 | wpslist.setOnItemClickListener(new AdapterView.OnItemClickListener() 208 | { 209 | @Override 210 | public void onItemClick(AdapterView parent, View itemClicked, int position, long id) 211 | { 212 | ShowMenu(BSSDWps, wpsPin.get(position)); 213 | } 214 | }); 215 | 216 | mWebView = (WebView) findViewById(R.id.webView); 217 | mWebView.addJavascriptInterface(new myJavascriptInterface(), "JavaHandler"); 218 | mWebView.setWebViewClient(new WebViewClient() 219 | { 220 | @Override 221 | public void onPageFinished(WebView view, String url) 222 | { 223 | super.onPageFinished(view, url); 224 | final String BSSDWps = getIntent().getExtras().getString("variable1"); 225 | mWebView.loadUrl("javascript:initAlgos();window.JavaHandler.initAlgos(JSON.stringify(algos),'" + BSSDWps + "');"); 226 | } 227 | }); 228 | mWebView.getSettings().setJavaScriptEnabled(true); 229 | AppVersion wpspin = new AppVersion(getApplicationContext()); 230 | wpspin.wpsCompanionInit(false); 231 | String path = wpspin.wpsCompanionGetPath(); 232 | if (path == null) 233 | path = "/android_asset/wpspin.html"; 234 | mWebView.loadUrl("file://" + path); 235 | 236 | new AsyncInitActivity().execute(BSSDWps); 237 | } 238 | 239 | private void ShowMenu(final String BSSID, final String pin) 240 | { 241 | AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(WPSActivity.this); 242 | String spin = pin; 243 | if (spin.length() == 0) 244 | spin = ""; 245 | dialogBuilder.setTitle("Selected pin: " + spin); 246 | 247 | dialogBuilder.setItems(listContextMenuItems, new DialogInterface.OnClickListener() { 248 | public void onClick(DialogInterface dialog, int item) { 249 | switch (item) { 250 | case 0: 251 | if (!WifiMgr.isWifiEnabled()) 252 | { 253 | Toast toast = Toast.makeText(getApplicationContext(), 254 | "Wi-Fi interface is disabled", Toast.LENGTH_SHORT); 255 | toast.show(); 256 | break; 257 | } 258 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 259 | { 260 | WpsInfo wpsInfo = new WpsInfo(); 261 | wpsInfo.BSSID = BSSID; 262 | wpsInfo.pin = pin; 263 | wpsInfo.setup = WpsInfo.KEYPAD; 264 | 265 | wpsLastPin = pin; 266 | WifiMgr.startWps(wpsInfo, wpsCallback); 267 | } 268 | else 269 | { 270 | AlertDialog.Builder builder = new AlertDialog.Builder(WPSActivity.this); 271 | builder.setTitle("Unsupported Android version") 272 | .setMessage("This function requires Android 5.0 (Lollipop) with API 21 or higher. Please upgrade your system.") 273 | .setCancelable(false) 274 | .setPositiveButton("OK", new DialogInterface.OnClickListener() { 275 | public void onClick(DialogInterface dialog, int id) { 276 | dialog.dismiss(); 277 | } 278 | }); 279 | AlertDialog alert = builder.create(); 280 | alert.show(); 281 | } 282 | break; 283 | case 1: 284 | Toast.makeText(getApplicationContext(), "Pin \"" + pin + "\" copied", Toast.LENGTH_SHORT).show(); 285 | try 286 | { 287 | ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); 288 | ClipData dataClip = ClipData.newPlainText("text", pin); 289 | clipboard.setPrimaryClip(dataClip); 290 | } 291 | catch (Exception e) {} 292 | break; 293 | } 294 | } 295 | }); 296 | 297 | dialogBuilder.show(); 298 | } 299 | 300 | private class AsyncInitActivity extends AsyncTask 301 | { 302 | @Override 303 | protected void onPreExecute() 304 | { 305 | super.onPreExecute(); 306 | pd = ProgressDialog.show(WPSActivity.this, "Please wait...", "Initializing..."); 307 | } 308 | 309 | protected String doInBackground(String[] BSSDWps) 310 | { 311 | // get MAC manufacturer 312 | String BSSID = BSSDWps[0]; 313 | String response2; 314 | DefaultHttpClient hc2 = new DefaultHttpClient(); 315 | ResponseHandler res2 = new BasicResponseHandler(); 316 | 317 | HttpPost http2 = new HttpPost("http://wpsfinder.com/ethernet-wifi-brand-lookup/MAC:" + BSSID); 318 | try 319 | { 320 | response2 = hc2.execute(http2, res2); 321 | response2 = response2.substring(response2.indexOf("muted'>
") + 15, response2.indexOf("
0) 330 | { 331 | try 332 | { 333 | Thread.sleep(100); 334 | wait -= 100; 335 | } 336 | catch (Exception e) {} 337 | } 338 | 339 | return response2; 340 | } 341 | 342 | @Override 343 | protected void onPostExecute(String response2) 344 | { 345 | int src = mSettings.AppSettings.getInt(Settings.WPS_SOURCE, 1); 346 | if (src != 1) 347 | pd.dismiss(); 348 | TextView VendorWpsText = (TextView)findViewById(R.id.VendorWpsTextView); 349 | if (response2.length() > 50) 350 | { 351 | response2 = "unknown vendor"; 352 | } 353 | VendorWpsText.setText(response2); 354 | 355 | switch (src) 356 | { 357 | case 1: 358 | btnwpsbaseclick(null); 359 | break; 360 | case 2: 361 | btnGenerate(null); 362 | break; 363 | case 3: 364 | btnLocalClick(null); 365 | break; 366 | } 367 | } 368 | } 369 | 370 | private class GetPinsFromBase extends AsyncTask 371 | { 372 | @Override 373 | protected void onPreExecute() 374 | { 375 | super.onPreExecute(); 376 | String msg = "Getting pins..."; 377 | 378 | if (pd.isShowing()) 379 | { 380 | pd.setMessage(msg); 381 | } 382 | else 383 | { 384 | pd = ProgressDialog.show(WPSActivity.this, "Please wait...", msg); 385 | } 386 | } 387 | 388 | protected String doInBackground(String[] BSSDWps) 389 | { 390 | String BSSID = BSSDWps[0]; 391 | String response; 392 | data.clear(); 393 | wpsScore.clear(); 394 | wpsDb.clear(); 395 | wpsPin.clear(); 396 | wpsMet.clear(); 397 | DefaultHttpClient hc = new DefaultHttpClient(); 398 | ResponseHandler res = new BasicResponseHandler(); 399 | 400 | mSettings.Reload(); 401 | String SERVER_URI = mSettings.AppSettings.getString(Settings.APP_SERVER_URI, getResources().getString(R.string.SERVER_URI_DEFAULT)); 402 | HttpGet http = new HttpGet(SERVER_URI + "/api/apiwps?key=" + API_READ_KEY + "&bssid=" + BSSID); 403 | try 404 | { 405 | if (cachedPins.isEmpty()) 406 | response = hc.execute(http, res); 407 | else 408 | response = cachedPins; 409 | 410 | try 411 | { 412 | JSONObject jObject = new JSONObject(response); 413 | Boolean result = jObject.getBoolean("result"); 414 | 415 | if (result) 416 | { 417 | cachedPins = response; 418 | try 419 | { 420 | jObject = jObject.getJSONObject("data"); 421 | jObject = jObject.getJSONObject(BSSID); 422 | 423 | JSONArray array = jObject.optJSONArray("scores"); 424 | for (int i = 0; i < array.length(); i++) 425 | { 426 | jObject = array.getJSONObject(i); 427 | wpsPin.add(jObject.getString("value")); 428 | wpsMet.add(jObject.getString("name")); 429 | wpsScore.add(jObject.getString("score")); 430 | wpsDb.add(jObject.getBoolean("fromdb") ? "✔" : ""); 431 | Integer score = Math.round(Float.parseFloat(wpsScore.get(i)) * 100); 432 | wpsScore.set(i, Integer.toString(score) + "%"); 433 | 434 | data.add(new ItemWps(wpsPin.get(i), wpsMet.get(i), wpsScore.get(i), wpsDb.get(i))); 435 | } 436 | } 437 | catch (Exception e) {} 438 | } 439 | else 440 | { 441 | String error = jObject.getString("error"); 442 | 443 | if (error.equals("loginfail")) 444 | { 445 | mSettings.Editor.putBoolean(Settings.API_KEYS_VALID, false); 446 | mSettings.Editor.commit(); 447 | runOnUiThread(new Runnable() { 448 | @Override 449 | public void run() { 450 | Toast t = Toast.makeText(getApplicationContext(), "Please enter credentials", Toast.LENGTH_SHORT); 451 | t.show(); 452 | } 453 | }); 454 | Intent startActivity = new Intent(getApplicationContext(), StartActivity.class); 455 | startActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); 456 | startActivity(startActivity); 457 | } 458 | response = "api_error"; 459 | } 460 | } 461 | catch (JSONException e) 462 | { 463 | response = "json_error"; 464 | } 465 | } 466 | catch (Exception e) 467 | { 468 | response = "http_error"; 469 | } 470 | return response; 471 | } 472 | 473 | @Override 474 | protected void onPostExecute(String str) 475 | { 476 | pd.dismiss(); 477 | ListView wpslist = (ListView)findViewById(R.id.WPSlist); 478 | String msg = ""; 479 | Boolean toast = true; 480 | if (str.equals("http_error")) 481 | { 482 | msg = "No internet connection"; 483 | toast = false; 484 | } 485 | else if (str.equals("json_error")) 486 | { 487 | msg = "Connection failure"; 488 | toast = false; 489 | } 490 | else if (str.equals("api_error")) 491 | { 492 | msg = "Database failure"; 493 | toast = false; 494 | } 495 | else if (data.isEmpty()) 496 | { 497 | msg = "No pins found"; 498 | } 499 | if (msg.length() > 0) 500 | { 501 | data.add(new ItemWps(null, msg, null, null)); 502 | } 503 | wpslist.setEnabled(msg.length() == 0); 504 | 505 | wpslist.setAdapter(new MyAdapterWps(WPSActivity.this, data)); 506 | if (toast) toastMessage("Selected source: 3WiFi Online WPS PIN"); 507 | } 508 | } 509 | 510 | public void btnwpsbaseclick(View view) 511 | { //пины из базы 512 | findViewById(R.id.baseButton).getBackground().setColorFilter(Color.parseColor("#1cd000"), PorterDuff.Mode.MULTIPLY); 513 | findViewById(R.id.wpsButton1).getBackground().clearColorFilter(); 514 | findViewById(R.id.wpsButton2).getBackground().clearColorFilter(); 515 | mSettings.Editor.putInt(Settings.WPS_SOURCE, 1); 516 | mSettings.Editor.commit(); 517 | String BSSDWps = getIntent().getExtras().getString("variable1"); 518 | new GetPinsFromBase().execute(BSSDWps); 519 | } 520 | 521 | private class myJavascriptInterface 522 | { 523 | @JavascriptInterface 524 | public void initAlgos(String json, String bssid) 525 | { 526 | pins.clear(); 527 | try 528 | { 529 | JSONArray arr = new JSONArray(json); 530 | 531 | for (int i = 0; i < arr.length(); i++) 532 | { 533 | JSONObject obj = arr.getJSONObject(i); 534 | 535 | WPSPin pin = new WPSPin(); 536 | pin.mode = obj.getInt("mode"); 537 | pin.name = obj.getString("name"); 538 | pins.add(pin); 539 | } 540 | mWebView.loadUrl("javascript:window.JavaHandler.getPins(1,JSON.stringify(pinSuggestAPI(true,'" + bssid + "',null)), '" + bssid + "');"); 541 | } 542 | catch (JSONException e) 543 | { 544 | wpsReady = true; 545 | } 546 | } 547 | 548 | @JavascriptInterface 549 | public void getPins(int all, String json, String bssid) 550 | { 551 | try 552 | { 553 | JSONArray arr = new JSONArray(json); 554 | 555 | for (int i = 0; i < arr.length(); i++) 556 | { 557 | JSONObject obj = arr.getJSONObject(i); 558 | if (all > 0) 559 | { 560 | WPSPin pin = pins.get(i); 561 | pin.pin = obj.getString("pin"); 562 | pin.sugg = false; 563 | } 564 | else 565 | { 566 | WPSPin pin = pins.get(obj.getInt("algo")); 567 | pin.sugg = true; 568 | } 569 | } 570 | if (all > 0) 571 | mWebView.loadUrl("javascript:window.JavaHandler.getPins(0,JSON.stringify(pinSuggestAPI(false,'" + bssid + "',null)), '');"); 572 | else 573 | wpsReady = true; 574 | } 575 | catch (JSONException e) 576 | { 577 | pins.clear(); 578 | wpsReady = true; 579 | } 580 | } 581 | } 582 | 583 | public void btnGenerate(View view) 584 | { //генераторpppppp 585 | findViewById(R.id.wpsButton1).getBackground().setColorFilter(Color.parseColor("#1cd000"), PorterDuff.Mode.MULTIPLY); 586 | findViewById(R.id.baseButton).getBackground().clearColorFilter(); 587 | findViewById(R.id.wpsButton2).getBackground().clearColorFilter(); 588 | mSettings.Editor.putInt(Settings.WPS_SOURCE, 2); 589 | mSettings.Editor.commit(); 590 | ListView wpslist = (ListView) findViewById(R.id.WPSlist); 591 | wpslist.setAdapter(null); 592 | wpsPin.clear(); 593 | wpsMet.clear(); 594 | data.clear(); 595 | 596 | for (WPSPin pin : pins) 597 | { 598 | if (!pin.sugg) continue; 599 | wpsPin.add(pin.pin); 600 | wpsMet.add(pin.name); 601 | data.add(new ItemWps( 602 | pin.pin.equals("") ? "" : pin.pin, 603 | pin.name, 604 | pin.mode == 3 ? "STA" : "", 605 | "✔" 606 | )); 607 | } 608 | for (WPSPin pin : pins) 609 | { 610 | if (pin.sugg) continue; 611 | wpsPin.add(pin.pin); 612 | wpsMet.add(pin.name); 613 | data.add(new ItemWps( 614 | pin.pin.equals("") ? "" : pin.pin, 615 | pin.name, 616 | pin.mode == 3 ? "STA" : "", 617 | "" 618 | )); 619 | } 620 | wpslist.setEnabled(pins.size() > 0); 621 | wpslist.setAdapter(new MyAdapterWps(WPSActivity.this, data)); 622 | toastMessage("Selected source: WPS PIN Companion"); 623 | } 624 | 625 | private int findAlgoByPin(String pin) 626 | { 627 | int i = 0; 628 | for (WPSPin p : pins) 629 | { 630 | if (pin.equals(p.pin)) 631 | return i; 632 | i++; 633 | } 634 | return -1; 635 | } 636 | 637 | private int findAlgoByName(String name) 638 | { 639 | int i = 0; 640 | for (WPSPin p : pins) 641 | { 642 | if (name.equals(p.name)) 643 | return i; 644 | i++; 645 | } 646 | return -1; 647 | } 648 | 649 | public void btnLocalClick(View view) 650 | { //локальная база 651 | findViewById(R.id.wpsButton2).getBackground().setColorFilter(Color.parseColor("#1cd000"), PorterDuff.Mode.MULTIPLY); 652 | findViewById(R.id.wpsButton1).getBackground().clearColorFilter(); 653 | findViewById(R.id.baseButton).getBackground().clearColorFilter(); 654 | mSettings.Editor.putInt(Settings.WPS_SOURCE, 3); 655 | mSettings.Editor.commit(); 656 | ListView wpslist = (ListView) findViewById(R.id.WPSlist); 657 | wpslist.setAdapter(null); 658 | final String BSSDWps = getIntent().getExtras().getString("variable1"); 659 | 660 | try 661 | { 662 | data.clear(); 663 | wpsPin.clear(); 664 | Cursor cursor = mDb.rawQuery("SELECT * FROM pins WHERE mac='" + BSSDWps.substring(0, 8) + "'", null); 665 | cursor.moveToFirst(); 666 | 667 | do { 668 | String p = cursor.getString(0); 669 | if (p.equals("vacante")) 670 | p = ""; // empty pin 671 | int idx = findAlgoByPin(p); 672 | 673 | if (idx == -1) 674 | { 675 | if (p.equals("airocon")) 676 | idx = findAlgoByName("Airocon Realtek"); 677 | else if (p.equals("arcady")) 678 | idx = findAlgoByName("Livebox Arcadyan"); 679 | else if (p.equals("asus")) 680 | idx = findAlgoByName("ASUS PIN"); 681 | else if (p.equals("dlink")) 682 | idx = findAlgoByName("D-Link PIN"); 683 | else if (p.equals("dlink1")) 684 | idx = findAlgoByName("D-Link PIN +1"); 685 | else if (p.equals("thirtytwo")) 686 | idx = findAlgoByName("32-bit PIN"); 687 | //else if (p.equals("trend")) 688 | // idx = findAlgoByName(""); // unknown 689 | else if (p.equals("twentyeight")) 690 | idx = findAlgoByName("28-bit PIN"); 691 | else if (p.equals("zhao")) 692 | idx = findAlgoByName("24-bit PIN"); 693 | 694 | if (idx > -1) 695 | { 696 | WPSPin algo = pins.get(idx); 697 | p = algo.pin; 698 | } 699 | } 700 | 701 | if (idx > -1) 702 | { 703 | WPSPin algo = pins.get(idx); 704 | data.add(new ItemWps( 705 | p.equals("") ? "" : p, 706 | algo.name, 707 | algo.mode == 3 ? "STA" : "", 708 | "" 709 | )); 710 | } 711 | else 712 | { 713 | data.add(new ItemWps( 714 | p.equals("") ? "" : p, 715 | "Unknown", 716 | p.matches("[0-9]+") ? "STA" : "", 717 | "" 718 | )); 719 | } 720 | wpsPin.add(p); 721 | } 722 | while(cursor.moveToNext()); 723 | cursor.close(); 724 | wpslist.setEnabled(true); 725 | } 726 | catch (Exception e) 727 | { 728 | data.add(new ItemWps(null, "No pins found", null, null)); 729 | wpslist.setEnabled(false); 730 | } 731 | wpslist.setAdapter(new MyAdapterWps(WPSActivity.this, data)); 732 | 733 | toastMessage("Selected source: WPA WPS TESTER"); 734 | } 735 | 736 | public void btnCustomPin(View view) 737 | { 738 | AlertDialog.Builder alert = new AlertDialog.Builder(this); 739 | alert.setTitle("Enter your WPS PIN:"); 740 | 741 | final EditText input = new EditText(this); 742 | input.setInputType(InputType.TYPE_CLASS_TEXT); 743 | alert.setView(input); 744 | 745 | alert.setPositiveButton("OK", new DialogInterface.OnClickListener() 746 | { 747 | @Override 748 | public void onClick(DialogInterface dialog, int which) 749 | { 750 | String BSSDWps = getIntent().getExtras().getString("variable1"); 751 | String pin = input.getText().toString(); 752 | ShowMenu(BSSDWps, pin); 753 | } 754 | }); 755 | alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() 756 | { 757 | @Override 758 | public void onClick(DialogInterface dialog, int which) 759 | { 760 | dialog.cancel(); 761 | } 762 | }); 763 | 764 | alert.show(); 765 | } 766 | 767 | //Toast 768 | public void toastMessage(String text) 769 | { 770 | Toast toast = Toast.makeText(getApplicationContext(), 771 | text, Toast.LENGTH_LONG); 772 | toast.show(); 773 | } 774 | } 775 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/WiFiPasswordSearcher/WifiDetails.java: -------------------------------------------------------------------------------- 1 | package com.example.WiFiPasswordSearcher; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.content.res.Configuration; 6 | import android.media.AudioManager; 7 | import android.media.SoundPool; 8 | import android.net.wifi.ScanResult; 9 | import android.net.wifi.WifiManager; 10 | import android.os.Bundle; 11 | import android.view.ViewGroup; 12 | import android.widget.CheckBox; 13 | import android.widget.CompoundButton; 14 | import android.widget.LinearLayout; 15 | import android.widget.TextView; 16 | import com.jjoe64.graphview.GraphView; 17 | import com.jjoe64.graphview.Viewport; 18 | import com.jjoe64.graphview.series.DataPoint; 19 | import com.jjoe64.graphview.series.LineGraphSeries; 20 | 21 | import java.util.HashMap; 22 | import java.util.List; 23 | 24 | public class WifiDetails extends Activity 25 | { 26 | private ScanResult WiFiInfo; 27 | private Thread DetectorThread; 28 | private SoundPool mSoundPool; 29 | private WifiManager WifiMgr; 30 | 31 | private String NetworkBSSID; 32 | private String NetworkESSID; 33 | private TextView txtBSSID; 34 | private TextView txtESSID; 35 | private TextView txtFreq; 36 | private TextView txtSignal; 37 | private TextView txtChannel; 38 | 39 | private boolean ScanThreadActive; 40 | private boolean UseWifiDetector; 41 | private int LastSignal; 42 | private int LastFreq = -1; 43 | private String LastBSSID; 44 | private String LastESSID; 45 | private Settings mSettings; 46 | 47 | 48 | private LineGraphSeries graphSeries; 49 | private GraphView graphView; 50 | private int iGraphPointCount; 51 | 52 | protected void onCreate(Bundle savedInstanceState) 53 | { 54 | super.onCreate(savedInstanceState); 55 | setContentView(R.layout.wifi_details); 56 | this.onConfigurationChanged(getResources().getConfiguration()); 57 | 58 | UseWifiDetector = false; 59 | HashMap StartWifiInfo = (HashMap)(getIntent().getSerializableExtra("WifiInfo")); 60 | NetworkBSSID = StartWifiInfo.get("BSSID"); 61 | NetworkESSID = StartWifiInfo.get("SSID"); 62 | 63 | txtBSSID = (TextView)this.findViewById(R.id.txtDetailsBSSID); 64 | txtESSID = (TextView)this.findViewById(R.id.txtDetailsESSID); 65 | txtFreq = (TextView)this.findViewById(R.id.txtDetailsFreq); 66 | txtSignal = (TextView)this.findViewById(R.id.txtDetailsSignal); 67 | txtChannel = (TextView)this.findViewById(R.id.txtDetailsChannel); 68 | CheckBox chkbUseDetector = (CheckBox)this.findViewById(R.id.chkbUseDetector); 69 | LinearLayout llGrphView = (LinearLayout)this.findViewById(R.id.llGrphView); 70 | 71 | mSoundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0); 72 | 73 | // Graph init 74 | iGraphPointCount = 0; 75 | graphSeries = new LineGraphSeries<>(); 76 | graphView = new GraphView(this); 77 | graphView.getGridLabelRenderer().setNumVerticalLabels(2); 78 | graphView.getGridLabelRenderer().setHorizontalLabelsVisible(false); 79 | graphView.getViewport().setMinY(0); 80 | graphView.getViewport().setMaxY(100); 81 | graphView.getViewport().setYAxisBoundsStatus(Viewport.AxisBoundsStatus.FIX); 82 | graphView.getViewport().setYAxisBoundsManual(true); 83 | 84 | graphView.setTitle("Signal graph"); 85 | graphView.addSeries(graphSeries); 86 | llGrphView.addView(graphView); 87 | 88 | chkbUseDetector.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 89 | @Override 90 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 91 | UseWifiDetector = isChecked; 92 | 93 | mSettings.Editor.putBoolean(Settings.WIFI_SIGNAL, UseWifiDetector); 94 | mSettings.Editor.commit(); 95 | 96 | if (UseWifiDetector) { 97 | DetectorThread = new Thread(new Runnable() { 98 | @Override 99 | public void run() { 100 | DetectorWorker(); 101 | } 102 | }); 103 | DetectorThread.start(); 104 | } 105 | } 106 | }); 107 | 108 | mSettings = new Settings(getApplicationContext()); 109 | mSettings.Reload(); 110 | 111 | Boolean wifiSignal = mSettings.AppSettings.getBoolean(Settings.WIFI_SIGNAL, false); 112 | chkbUseDetector.setChecked(wifiSignal); 113 | 114 | setBSSID(StartWifiInfo.get("BSSID")); 115 | setESSID(StartWifiInfo.get("SSID")); 116 | setFreq(StartWifiInfo.get("Freq")); 117 | setSignal(StartWifiInfo.get("Signal")); 118 | 119 | WifiMgr = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); 120 | 121 | Thread ScanThread = new Thread(new Runnable() { 122 | @Override 123 | public void run() { 124 | ScanWorker(); 125 | } 126 | }); 127 | ScanThreadActive = true; 128 | ScanThread.start(); 129 | } 130 | 131 | public void onConfigurationChanged(Configuration newConfig) 132 | { 133 | super.onConfigurationChanged(newConfig); 134 | 135 | LinearLayout LR = (LinearLayout)findViewById(R.id.rootLayout); 136 | LinearLayout LI = (LinearLayout)findViewById(R.id.layoutInfo); 137 | 138 | if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) 139 | { 140 | LR.setOrientation(LinearLayout.VERTICAL); 141 | ViewGroup.LayoutParams layoutParams = LI.getLayoutParams(); 142 | layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT; 143 | LI.setLayoutParams(layoutParams); 144 | } 145 | else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) 146 | { 147 | LR.setOrientation(LinearLayout.HORIZONTAL); 148 | ViewGroup.LayoutParams layoutParams = LI.getLayoutParams(); 149 | layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT; 150 | LI.setLayoutParams(layoutParams); 151 | } 152 | } 153 | 154 | protected void onDestroy() 155 | { 156 | super.onDestroy(); 157 | UseWifiDetector = false; 158 | ScanThreadActive = false; 159 | graphView.removeAllSeries(); 160 | graphSeries = null; 161 | } 162 | private void Update() 163 | { 164 | setBSSID(WiFiInfo.BSSID); 165 | setESSID(WiFiInfo.SSID); 166 | setFreq(Integer.toString(WiFiInfo.frequency)); 167 | setSignal(Integer.toString(WiFiInfo.level)); 168 | } 169 | 170 | private void DetectorWorker() 171 | { 172 | int PickSoundId = mSoundPool.load(getApplicationContext(), R.raw.pick, 1); 173 | 174 | while (UseWifiDetector) 175 | { 176 | if (LastSignal > 0) 177 | mSoundPool.play(PickSoundId, 1, 1, 100, 0, 1); 178 | int SleepTime = 2100-(2000/100)*LastSignal; 179 | try { 180 | Thread.sleep((long)SleepTime, 0); 181 | } catch (InterruptedException e) { 182 | e.printStackTrace(); 183 | } 184 | } 185 | } 186 | 187 | private void ScanWorker() // THREADED! 188 | { 189 | while(ScanThreadActive) 190 | { 191 | List results; 192 | 193 | Boolean Founded = false; 194 | WifiMgr.startScan(); 195 | results = WifiMgr.getScanResults(); 196 | boolean match; 197 | 198 | for (ScanResult result : results) { 199 | if (!NetworkBSSID.isEmpty() && !NetworkESSID.isEmpty()) 200 | { 201 | match = (result.BSSID.equals(NetworkBSSID) && result.SSID.equals(NetworkESSID)); 202 | } 203 | else if (NetworkBSSID.isEmpty() && !NetworkESSID.isEmpty()) 204 | { 205 | match = result.SSID.equals(NetworkESSID); 206 | } 207 | else if (!NetworkBSSID.isEmpty() && NetworkESSID.isEmpty()) 208 | { 209 | match = result.BSSID.equals(NetworkBSSID); 210 | } 211 | else 212 | { 213 | match = true; 214 | } 215 | if (match) { 216 | if (NetworkBSSID.isEmpty()) NetworkBSSID = result.BSSID; 217 | if (NetworkESSID.isEmpty()) NetworkESSID = result.SSID; 218 | 219 | WiFiInfo = result; 220 | Update(); 221 | Founded = true; 222 | break; 223 | } 224 | } 225 | if (!Founded) setSignal("-100"); 226 | try { 227 | Thread.sleep((long)1000, 0); 228 | } catch (InterruptedException e) { 229 | e.printStackTrace(); 230 | } 231 | } 232 | } 233 | private void setBSSID(String BSSID) 234 | { 235 | BSSID = BSSID.toUpperCase(); 236 | if (BSSID.equals(LastBSSID)) return; 237 | 238 | final String text = "BSSID: " + (BSSID.isEmpty() ? "Unknown" : BSSID); 239 | 240 | runOnUiThread(new Runnable() { 241 | @Override 242 | public void run() { 243 | txtBSSID.setText(text); 244 | } 245 | }); 246 | LastBSSID = BSSID; 247 | } 248 | 249 | private void setESSID(String ESSID) 250 | { 251 | if (ESSID.equals(LastESSID)) return; 252 | final String text = (ESSID.isEmpty() ? "" : ESSID); 253 | 254 | runOnUiThread(new Runnable() { 255 | @Override 256 | public void run() { 257 | txtESSID.setText(text); 258 | } 259 | }); 260 | LastESSID = ESSID; 261 | } 262 | 263 | private void setFreq(String Freq) 264 | { 265 | String sDiap = ""; 266 | int Channel = 0; 267 | 268 | int iFreq = Integer.parseInt(Freq); 269 | if (iFreq == LastFreq) return; 270 | 271 | if (iFreq > 0) 272 | { 273 | if (iFreq >= 2401 && iFreq <= 2483) 274 | { 275 | sDiap = "2.4 GHz"; 276 | Channel = ((iFreq - 2412) / 5) + 1; 277 | } 278 | else if (iFreq >= 5150 && iFreq <= 5250) 279 | { 280 | sDiap = "UNII 1"; 281 | Channel = (5000 + iFreq) / 5; 282 | } 283 | else if (iFreq >= 5250 && iFreq <= 5350) 284 | { 285 | sDiap = "UNII 2"; 286 | Channel = (5000 + iFreq) / 5; 287 | } 288 | else if (iFreq >= 5470 && iFreq <= 5725) 289 | { 290 | sDiap = "UNII 2 Extended"; 291 | Channel = (iFreq / 5) + 1; 292 | } 293 | else if (iFreq >= 5725 && iFreq <= 5825) 294 | { 295 | sDiap = "UNII 3"; 296 | Channel = (5000 + iFreq) / 5; 297 | } 298 | } 299 | 300 | final String sText = "Freq: " + (iFreq <= 0 ? "Unknown" : Freq + " MHz " + "(" + sDiap + ")"); 301 | 302 | runOnUiThread(new Runnable() { 303 | @Override 304 | public void run() { 305 | txtFreq.setText(sText); 306 | } 307 | }); 308 | setChannel(Channel); 309 | 310 | LastFreq = iFreq; 311 | } 312 | 313 | private void setSignal(String Signal) 314 | { 315 | int iSignal = Integer.parseInt(Signal); 316 | iSignal = (100 + iSignal) * 2; 317 | iSignal = Math.min(Math.max(iSignal, 0), 100); 318 | final int fSignal = iSignal; 319 | LastSignal = iSignal; 320 | 321 | runOnUiThread(new Runnable() { 322 | @Override 323 | public void run() { 324 | graphSeries.appendData(new DataPoint(iGraphPointCount, fSignal), true, 25); 325 | iGraphPointCount++; 326 | txtSignal.setText("Signal: " + fSignal + "%"); 327 | } 328 | }); 329 | } 330 | private void setChannel(final int Channel) 331 | { 332 | runOnUiThread(new Runnable() { 333 | @Override 334 | public void run() { 335 | txtChannel.setText("Channel: " + (Channel <= 0 ? "N/A" : Channel)); 336 | } 337 | }); 338 | } 339 | 340 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FusixGit/WiFiPasswordSearcher/739af59460b32db7c1590f15651a45f06e8b1ee2/app/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FusixGit/WiFiPasswordSearcher/739af59460b32db7c1590f15651a45f06e8b1ee2/app/src/main/res/drawable-hdpi/logo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FusixGit/WiFiPasswordSearcher/739af59460b32db7c1590f15651a45f06e8b1ee2/app/src/main/res/drawable-ldpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FusixGit/WiFiPasswordSearcher/739af59460b32db7c1590f15651a45f06e8b1ee2/app/src/main/res/drawable-ldpi/logo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FusixGit/WiFiPasswordSearcher/739af59460b32db7c1590f15651a45f06e8b1ee2/app/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FusixGit/WiFiPasswordSearcher/739af59460b32db7c1590f15651a45f06e8b1ee2/app/src/main/res/drawable-mdpi/logo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FusixGit/WiFiPasswordSearcher/739af59460b32db7c1590f15651a45f06e8b1ee2/app/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FusixGit/WiFiPasswordSearcher/739af59460b32db7c1590f15651a45f06e8b1ee2/app/src/main/res/drawable-xhdpi/logo.png -------------------------------------------------------------------------------- /app/src/main/res/layout/about.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 15 | 16 | 21 | 22 | 26 | 27 | 32 | 33 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /app/src/main/res/layout/gpslogging.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 15 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/layout/list_wps_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 17 | 18 | 23 | 24 | 27 | 28 | 37 | 38 | 47 | 48 | 54 | 55 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /app/src/main/res/layout/listclick_contextmenu.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/layout/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 15 | 16 |