├── LICENSE
├── README.md
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── icons
├── LICENSE
├── Privacy Police 128x128.png
├── Privacy Police 16x16.png
├── Privacy Police 256x256.png
├── Privacy Police 32x32.png
├── Privacy Police 48x48.png
├── Privacy Police 512x512.png
├── Privacy Police 64x64.png
├── Privacy Police Playstore Banner.png
├── Privacy Police.png
└── Privacy Police.psd
├── privacypolice.iml
├── privacypolice
├── build.gradle
├── proguard-rules.txt
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── ic_launcher-web.png
│ ├── ic_menu_clear_playlist-web.png
│ ├── ic_notification.png
│ ├── ic_wifi_signal_0-web.png
│ ├── ic_wifi_signal_1-web.png
│ ├── java
│ └── be
│ │ └── uhasselt
│ │ └── privacypolice
│ │ ├── Analytics.java
│ │ ├── AskPermissionActivity.java
│ │ ├── LocationAccess.java
│ │ ├── LocationNoticeActivity.java
│ │ ├── MACManagerActivity.java
│ │ ├── NetworkManagerActivity.java
│ │ ├── NotificationHandler.java
│ │ ├── PermissionChangeReceiver.java
│ │ ├── PreferencesActivity.java
│ │ ├── PreferencesStorage.java
│ │ ├── SSIDManagerActivity.java
│ │ ├── ScanResultsChecker.java
│ │ └── WakelockHandler.java
│ └── res
│ ├── drawable-hdpi-v11
│ └── ic_notification.png
│ ├── drawable-hdpi-v9
│ └── ic_notification.png
│ ├── drawable-hdpi
│ ├── ic_launcher.png
│ ├── ic_notification.png
│ ├── ic_wifi_signal_0_teal.png
│ ├── ic_wifi_signal_1_teal.png
│ ├── ic_wifi_signal_2_teal.png
│ ├── ic_wifi_signal_3_teal.png
│ └── ic_wifi_signal_4_teal.png
│ ├── drawable-mdpi-v11
│ └── ic_notification.png
│ ├── drawable-mdpi-v9
│ └── ic_notification.png
│ ├── drawable-mdpi
│ ├── ic_launcher.png
│ ├── ic_notification.png
│ ├── ic_wifi_signal_0_teal.png
│ ├── ic_wifi_signal_1_teal.png
│ ├── ic_wifi_signal_2_teal.png
│ ├── ic_wifi_signal_3_teal.png
│ └── ic_wifi_signal_4_teal.png
│ ├── drawable-xhdpi-v11
│ └── ic_notification.png
│ ├── drawable-xhdpi-v9
│ └── ic_notification.png
│ ├── drawable-xhdpi
│ ├── ic_launcher.png
│ ├── ic_notification.png
│ ├── ic_wifi_signal_0_teal.png
│ ├── ic_wifi_signal_1_teal.png
│ ├── ic_wifi_signal_2_teal.png
│ ├── ic_wifi_signal_3_teal.png
│ └── ic_wifi_signal_4_teal.png
│ ├── drawable-xxhdpi-v11
│ ├── border.xml
│ └── ic_notification.png
│ ├── drawable-xxhdpi-v9
│ └── ic_notification.png
│ ├── drawable-xxhdpi
│ ├── ic_launcher.png
│ ├── ic_notification.png
│ ├── ic_wifi_signal_0_teal.png
│ ├── ic_wifi_signal_1_teal.png
│ ├── ic_wifi_signal_2_teal.png
│ ├── ic_wifi_signal_3_teal.png
│ └── ic_wifi_signal_4_teal.png
│ ├── drawable-xxxhdpi
│ ├── ic_wifi_signal_0_pink.png
│ ├── ic_wifi_signal_0_teal.png
│ ├── ic_wifi_signal_1_pink.png
│ ├── ic_wifi_signal_1_teal.png
│ ├── ic_wifi_signal_2_pink.png
│ ├── ic_wifi_signal_2_teal.png
│ ├── ic_wifi_signal_3_pink.png
│ ├── ic_wifi_signal_3_teal.png
│ ├── ic_wifi_signal_4_pink.png
│ ├── ic_wifi_signal_4_teal.png
│ ├── ic_wifi_unavailable_pink.png
│ └── ic_wifi_unavailable_teal.png
│ ├── layout
│ ├── activity_askpermission.xml
│ ├── activity_locationnotice.xml
│ ├── activity_preferences.xml
│ └── item_networkmanager.xml
│ ├── menu
│ ├── ask_permission.xml
│ └── networkmanager.xml
│ ├── mipmap-hdpi
│ └── ic_menu_clear_playlist.png
│ ├── mipmap-mdpi
│ └── ic_menu_clear_playlist.png
│ ├── mipmap-xhdpi
│ └── ic_menu_clear_playlist.png
│ ├── mipmap-xxhdpi
│ └── ic_menu_clear_playlist.png
│ ├── mipmap-xxxhdpi
│ └── ic_menu_clear_playlist.png
│ ├── values-de
│ └── strings.xml
│ ├── values-es
│ └── strings.xml
│ ├── values-fr
│ └── strings.xml
│ ├── values-it
│ └── strings.xml
│ ├── values-nl
│ └── strings.xml
│ ├── values-pt-rPT
│ └── strings.xml
│ ├── values-v21
│ └── styles.xml
│ ├── values-w820dp
│ └── dimens.xml
│ ├── values
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
│ └── xml
│ ├── preferences.xml
│ ├── preferences_location.xml
│ └── tracker.xml
└── settings.gradle
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 | {description}
294 | Copyright (C) {year} {fullname}
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | {signature of Ty Coon}, 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
341 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Wi-Fi PrivacyPolice
2 |
3 | Wi-Fi Privacy Police prevents your smartphone or tablet from leaking privacy sensitive information via Wi-Fi networks. It does this in two ways:
4 |
5 | * It prevents your smartphone from sending out the names of Wi-Fi networks it wants to connect to over the air. This makes sure that other people in your surroundings can not see the networks you've connected to, and the places you've visited.
6 | * If your smartphone encounters an unknown access point with a known name (for example, a malicious access point pretending to be your home network), it asks whether you trust this access point before connecting. This makes sure that other people are not able to steal your data.
7 |
8 | Wi-Fi Privacy Police does not have any negative impact on your battery. In fact, you may see your battery life increase by using this app.
9 |
10 | View our [short paper](https://brambonne.com/docs/bonne14sasquatchprivacypolice.pdf) or our [slightly longer paper](https://brambonne.com/docs/bonne14sasquatch.pdf) for more technical information.
11 |
12 | Wi-Fi Privacy Police is an app developed at the Expertise Center for Digital Media, a research institute of UHasselt. Its code was written by [Bram Bonné](https://www.brambonne.com). The application is available on [Google Play](https://play.google.com/store/apps/details?id=be.uhasselt.privacypolice) and [F-Droid](https://f-droid.org/repository/browse/?fdid=be.uhasselt.privacypolice).
13 |
14 | PrivacyPolice now requires the location permission to run. This is because Android 6.0 does not allow access to the list of Wi-Fi networks without this location. PrivacyPolice will *never* collect your information. Please consult the source code at https://github.com/BramBonne/privacypolice if you have any doubts.
15 |
16 | Note to those using CyanogenMod: make sure that Privacy Guard is not blocking access to Wi-Fi Privacy Police, as it will then not be able to see the available networks. This will cause Wi-Fi Privacy Police to disable access to all of them.
17 |
18 | A lot of effort went into making this app work flawlessly. If you, however, run into any problems when using this app, nor the app developers, nor the UHasselt take responsibility. You are encouraged to report any issues at uhasselt.edm.developer@gmail.com or via [GitHub](https://github.com/BramBonne/privacypolice/issues/new); we will try to fix them as soon as possible.
19 |
20 | Should you have any other questions about the app, feel free to drop by on reddit (either at [/r/Android](http://www.reddit.com/r/Android/comments/2uyw50/wifi_privacypolice_prevents_your_smartphone_or/) or at [/r/androidapps](http://www.reddit.com/r/androidapps/comments/2u2ww0/dev_wifi_privacypolice_prevents_your_smartphone/)) to see our FAQ and/or pose your own question.
21 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | mavenCentral()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.3.3'
9 | }
10 | }
11 |
12 | allprojects {
13 | repositories {
14 | mavenCentral()
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Settings specified in this file will override any Gradle settings
5 | # configured through the IDE.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Mar 09 12:09:58 CET 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/icons/LICENSE:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/icons/LICENSE
--------------------------------------------------------------------------------
/icons/Privacy Police 128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/icons/Privacy Police 128x128.png
--------------------------------------------------------------------------------
/icons/Privacy Police 16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/icons/Privacy Police 16x16.png
--------------------------------------------------------------------------------
/icons/Privacy Police 256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/icons/Privacy Police 256x256.png
--------------------------------------------------------------------------------
/icons/Privacy Police 32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/icons/Privacy Police 32x32.png
--------------------------------------------------------------------------------
/icons/Privacy Police 48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/icons/Privacy Police 48x48.png
--------------------------------------------------------------------------------
/icons/Privacy Police 512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/icons/Privacy Police 512x512.png
--------------------------------------------------------------------------------
/icons/Privacy Police 64x64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/icons/Privacy Police 64x64.png
--------------------------------------------------------------------------------
/icons/Privacy Police Playstore Banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/icons/Privacy Police Playstore Banner.png
--------------------------------------------------------------------------------
/icons/Privacy Police.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/icons/Privacy Police.png
--------------------------------------------------------------------------------
/icons/Privacy Police.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/icons/Privacy Police.psd
--------------------------------------------------------------------------------
/privacypolice.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/privacypolice/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | android {
3 | compileSdkVersion 26
4 | buildToolsVersion '25.0.0'
5 |
6 | dependencies {
7 | // Used for analytics (retention rate etc. See Analytics.java for details)
8 | //compile 'com.google.android.gms:play-services:6.5.87'
9 | // Used for notifications compatibility
10 | compile 'com.android.support:support-v4:+'
11 | }
12 |
13 | defaultConfig {
14 | minSdkVersion 14
15 | targetSdkVersion 26
16 | versionCode 13
17 | versionName "2.2.4"
18 | }
19 | signingConfigs {
20 | release {
21 | storeFile file("release.keystore")
22 | keyAlias "releasekey"
23 | // Create a keystore.properties file in this directory, containing storePassword="password"
24 | def props = new Properties()
25 | props.load(new FileInputStream(rootProject.file('privacypolice/keystore.properties')))
26 | storePassword props['storePassword']
27 | keyPassword props['storePassword']
28 | }
29 | }
30 | buildTypes {
31 | release {
32 | minifyEnabled true
33 | zipAlignEnabled true
34 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
35 | debuggable false
36 | signingConfig signingConfigs.release
37 | }
38 | }
39 | }
40 |
41 | dependencies {
42 | }
--------------------------------------------------------------------------------
/privacypolice/proguard-rules.txt:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /home/bram/Progs/android-sdk-linux/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the ProGuard
5 | # include property in project.properties.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | # Remove logging in release version
20 | -assumenosideeffects class android.util.Log {
21 | public static *** d(...);
22 | public static *** v(...);
23 | public static *** i(...);
24 | }
--------------------------------------------------------------------------------
/privacypolice/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
17 |
22 |
25 |
26 |
27 |
28 |
29 |
30 |
33 |
34 |
37 |
38 |
41 |
42 |
43 |
47 |
48 |
49 |
50 |
51 |
52 |
56 |
57 |
58 |
59 |
60 |
61 |
64 |
67 |
71 |
74 |
75 |
76 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/privacypolice/src/main/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/ic_launcher-web.png
--------------------------------------------------------------------------------
/privacypolice/src/main/ic_menu_clear_playlist-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/ic_menu_clear_playlist-web.png
--------------------------------------------------------------------------------
/privacypolice/src/main/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/ic_notification.png
--------------------------------------------------------------------------------
/privacypolice/src/main/ic_wifi_signal_0-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/ic_wifi_signal_0-web.png
--------------------------------------------------------------------------------
/privacypolice/src/main/ic_wifi_signal_1-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/ic_wifi_signal_1-web.png
--------------------------------------------------------------------------------
/privacypolice/src/main/java/be/uhasselt/privacypolice/Analytics.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, 2015 Bram Bonné
3 | *
4 | * This file is part of Wi-Fi PrivacyPolice.
5 | *
6 | * Wi-Fi PrivacyPolice is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 2 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Wi-Fi PrivacyPolice is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Wi-Fi PrivacyPolice. If not, see .
18 | */
19 |
20 | package be.uhasselt.privacypolice;
21 |
22 | /**
23 | * Used for sending usage data. No personal information is collected, and data is carefully
24 | * anonymized before being used *for research purposes only*
25 | * This code is currently not used, but might be used for future research.
26 | */
27 | /*
28 | import android.content.Context;
29 | import android.util.Log;
30 |
31 | import com.google.android.gms.analytics.GoogleAnalytics;
32 | import com.google.android.gms.analytics.HitBuilders;
33 | import com.google.android.gms.analytics.Tracker;
34 | import com.google.android.gms.common.ConnectionResult;
35 | import com.google.android.gms.common.GooglePlayServicesUtil;
36 |
37 | public class Analytics {
38 | private Tracker tracker;
39 | private Context context;
40 |
41 | public Analytics(Context ctx) {
42 | context = ctx;
43 | // If the user does not want to / is not able to be tracked, do not create an Analytics instance
44 | if (!isTrackingEnabled())
45 | return;
46 | GoogleAnalytics analytics = GoogleAnalytics.getInstance(ctx);
47 | // Use id = 0, since we will be using only one analytics tracker
48 | tracker = analytics.newTracker(R.xml.tracker);
49 | }
50 |
51 | public boolean isTrackingEnabled() {
52 | if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(context) != ConnectionResult.SUCCESS) {
53 | Log.d("PrivacyPolice", "Not using analytics because Google Play services is disabled");
54 | return false;
55 | }
56 | PreferencesStorage prefs = new PreferencesStorage(context);
57 | if (!prefs.getTrackingAllowed()) {
58 | Log.d("PrivacyPolice", "Not using analytics because the user has indicated he/she does not want to be tracked");
59 | return false;
60 | }
61 | return true;
62 | }
63 |
64 | public void scanCompleted(int nAccessPoints) {
65 | if (!isTrackingEnabled())
66 | return;
67 | Log.v("PrivacyPolice", "Sending analytics data about a completed scan");
68 | tracker.send(new HitBuilders.EventBuilder()
69 | .setCategory("Tech")
70 | .setAction("accessPointsPerScan")
71 | .setValue(nAccessPoints)
72 | .build()
73 | );
74 | }
75 | }
76 | */
77 |
--------------------------------------------------------------------------------
/privacypolice/src/main/java/be/uhasselt/privacypolice/AskPermissionActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, 2015 Bram Bonné
3 | *
4 | * This file is part of Wi-Fi PrivacyPolice.
5 | *
6 | * Wi-Fi PrivacyPolice is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 2 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Wi-Fi PrivacyPolice is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Wi-Fi PrivacyPolice. If not, see .
18 | */
19 |
20 | package be.uhasselt.privacypolice;
21 |
22 | import android.app.Activity;
23 | import android.content.Intent;
24 | import android.content.res.Resources;
25 | import android.os.Bundle;
26 | import android.view.View;
27 | import android.widget.Button;
28 | import android.widget.TextView;
29 |
30 | /* This activity is used on older devices where actions on notifications are not yet supported.
31 | * It allows users of those devices to decide whether a network should be trusted.
32 | * The activity presents itself as a dialog box.
33 | */
34 |
35 | public class AskPermissionActivity extends Activity {
36 |
37 | @Override
38 | protected void onCreate(Bundle savedInstanceState) {
39 | super.onCreate(savedInstanceState);
40 | setContentView(R.layout.activity_askpermission);
41 |
42 | // Get the information for the network that we want to connect to
43 | Intent intent = getIntent();
44 | final String SSID = intent.getStringExtra("SSID");
45 | final String BSSID = intent.getStringExtra("BSSID");
46 |
47 | // Put the name of the network in the notice
48 | Resources res = getResources();
49 | String permissionString = String.format(res.getString(R.string.ask_permission), SSID);
50 | // ... and display it in the correct place
51 | TextView networkQuestion = (TextView) findViewById(R.id.networkQuestion);
52 | networkQuestion.setText(permissionString);
53 |
54 | Button yesButton = (Button) findViewById(R.id.yesButton);
55 | yesButton.setOnClickListener(
56 | new View.OnClickListener() {
57 | @Override
58 | public void onClick(View view) {
59 | // Notify the permissionChangeReceiver that we want to add a new AP to the trusted list
60 | Intent addIntent = new Intent(getApplicationContext(), PermissionChangeReceiver.class);
61 | addIntent.putExtra("SSID", SSID).putExtra("BSSID", BSSID).putExtra("enable", true);
62 | sendBroadcast(addIntent);
63 | finish();
64 | }
65 | }
66 | );
67 |
68 | Button noButton = (Button) findViewById(R.id.noButton);
69 | noButton.setOnClickListener(
70 | new View.OnClickListener() {
71 | @Override
72 | public void onClick(View view) {
73 | // Notify the permissionChangeReceiver that we want to add a new AP to the untrusted list
74 | Intent addIntent = new Intent(getApplicationContext(), PermissionChangeReceiver.class);
75 | addIntent.putExtra("SSID", SSID).putExtra("BSSID", BSSID).putExtra("enable", false);
76 | sendBroadcast(addIntent);
77 | finish();
78 | }
79 | }
80 | );
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/privacypolice/src/main/java/be/uhasselt/privacypolice/LocationAccess.java:
--------------------------------------------------------------------------------
1 | package be.uhasselt.privacypolice;
2 |
3 | import android.Manifest;
4 | import android.content.BroadcastReceiver;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.content.pm.PackageManager;
8 | import android.location.LocationManager;
9 | import android.support.v4.content.ContextCompat;
10 | import android.util.Log;
11 |
12 | /**
13 | * Used in Android 6.0 and up, because Location provider needs to be enabled in order to receive
14 | * Wi-Fi scan results programmatically.
15 | */
16 | public class LocationAccess extends BroadcastReceiver {
17 | public static boolean isNetworkLocationEnabled(Context context) {
18 | if (android.os.Build.VERSION.SDK_INT < 23) {
19 | // Location access is not needed on Android versions < 6.0
20 | // See https://code.google.com/p/android/issues/detail?id=185370 for more information
21 | return true;
22 | }
23 | if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
24 | Log.e("PrivacyPolice", "I don't seem to have the correct runtime permission!");
25 | return false;
26 | }
27 | LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
28 | return locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
29 | }
30 |
31 | /**
32 | * Called for intent location.PROVIDERS_CHANGED, BOOT_COMPLETED
33 | */
34 | @Override
35 | public void onReceive(Context context, Intent intent) {
36 | checkAccessDisplayNotification(context);
37 | }
38 |
39 | public static void checkAccessDisplayNotification(Context context) {
40 | NotificationHandler notificationHandler = new NotificationHandler(context);
41 |
42 | if (!isNetworkLocationEnabled(context)) {
43 | notificationHandler.askLocationPermission();
44 | } else {
45 | // Make sure no location permission request is shown
46 | notificationHandler.cancelLocationPermissionRequest();
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/privacypolice/src/main/java/be/uhasselt/privacypolice/LocationNoticeActivity.java:
--------------------------------------------------------------------------------
1 | package be.uhasselt.privacypolice;
2 |
3 | import android.Manifest;
4 | import android.app.Activity;
5 | import android.app.FragmentManager;
6 | import android.app.FragmentTransaction;
7 | import android.content.Intent;
8 | import android.content.pm.PackageManager;
9 | import android.net.Uri;
10 | import android.os.Bundle;
11 | import android.preference.PreferenceFragment;
12 | import android.provider.Settings;
13 | import android.support.v4.app.ActivityCompat;
14 | import android.support.v4.content.ContextCompat;
15 | import android.util.Log;
16 | import android.view.View;
17 |
18 | /**
19 | * Activity that shows the user why location access might be needed, and that allows to take action
20 | * (either open location settings or disable the notification from showing)
21 | */
22 | public class LocationNoticeActivity extends Activity{
23 | public static int PERMISSION_REQUEST_CODE = 10;
24 |
25 | @Override
26 | public void onCreate(Bundle savedInstanceState) {
27 | super.onCreate(savedInstanceState);
28 |
29 | setContentView(R.layout.activity_locationnotice);
30 |
31 | // Display the location preferences fragment
32 | FragmentManager fragmentManager = getFragmentManager();
33 | FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
34 | PrefsFragment prefsFragment = new PrefsFragment();
35 | fragmentTransaction.replace(R.id.inflatable_locationprefs, prefsFragment);
36 | fragmentTransaction.commit();
37 | }
38 |
39 | public void checkAndRequestSettings(View view) {
40 | // First, check if we need to request the location permission
41 | if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
42 | // Permission not granted yet, display request
43 | ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_CODE);
44 | }
45 | else {
46 | // Permission has been granted already, go straight to the location settings
47 | openLocationSettings();
48 | }
49 | }
50 |
51 | private void openLocationSettings() {
52 | Intent locationSettingsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
53 | startActivity(locationSettingsIntent);
54 | }
55 |
56 | private void openAppSettings() {
57 | Intent appSettingsIntent = new Intent();
58 | appSettingsIntent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
59 | Uri packageName = Uri.fromParts("package", getPackageName(), null);
60 | appSettingsIntent.setData(packageName);
61 | startActivity(appSettingsIntent);
62 | }
63 |
64 | @Override
65 | public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
66 | if (requestCode != PERMISSION_REQUEST_CODE) {
67 | Log.e("PrivacyPolice", "Permissions result with unexpected request code: " + requestCode);
68 | return;
69 | }
70 |
71 | if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
72 | Log.i("PrivacyPolice", "User denied location access");
73 | // Let the user enable this permission through the settings, because he may have ticked
74 | // the 'do not ask me again' box.
75 | openAppSettings();
76 | } else {
77 | // Check if we also need the user to enable location on their phone
78 | if (!LocationAccess.isNetworkLocationEnabled(this)) {
79 | openLocationSettings();
80 | }
81 | }
82 | // Re-check if notification should be displayed
83 | LocationAccess.checkAccessDisplayNotification(this);
84 | }
85 |
86 | /**
87 | * Fragment that is automatically filled with all preferences described in xml/preferences_location.xml
88 | */
89 | public static class PrefsFragment extends PreferenceFragment {
90 | @Override
91 | public void onCreate(Bundle savedInstanceState) {
92 | super.onCreate(savedInstanceState);
93 |
94 | // Load the preferences from an XML resource
95 | addPreferencesFromResource(R.xml.preferences_location);
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/privacypolice/src/main/java/be/uhasselt/privacypolice/MACManagerActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, 2015 Bram Bonné
3 | *
4 | * This file is part of Wi-Fi PrivacyPolice.
5 | *
6 | * Wi-Fi PrivacyPolice is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 2 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Wi-Fi PrivacyPolice is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Wi-Fi PrivacyPolice. If not, see .
18 | **/
19 |
20 | package be.uhasselt.privacypolice;
21 |
22 | import android.app.AlertDialog;
23 | import android.content.DialogInterface;
24 | import android.net.wifi.ScanResult;
25 | import android.os.Bundle;
26 | import android.util.Log;
27 | import android.view.View;
28 | import android.widget.ListView;
29 |
30 | import java.util.ArrayList;
31 | import java.util.List;
32 | import java.util.Set;
33 |
34 | /**
35 | * Activity that allows the user to view and modify the stored list of allowed / blocked MAC
36 | * addresses for a specific network.
37 | */
38 | public class MACManagerActivity extends NetworkManagerActivity {
39 | private String SSID;
40 |
41 | @Override
42 | public void onCreate(Bundle savedInstanceState) {
43 | super.onCreate(savedInstanceState);
44 |
45 | SSID = getIntent().getStringExtra("SSID");
46 | Log.v("PrivacyPolice", "Creating MAC manager activity for network " + SSID);
47 | setTitle(SSID);
48 |
49 | adapter = new MACManagerAdapter();
50 | setListAdapter(adapter);
51 | }
52 |
53 | /**
54 | * When an access point is clicked, open a menu for removing that MAC address.
55 | * @param listView The listview containing the MAC item
56 | * @param view The clicked view
57 | * @param position The position of the clicked item in the list
58 | * @param id The row id of the clicked item
59 | */
60 | @Override
61 | protected void onListItemClick(ListView listView, View view, int position, long id) {
62 | final NetworkAvailability listItem = (NetworkAvailability) listView.getItemAtPosition(position);
63 | final String mac = listItem.getName();
64 | Log.v("PrivacyPolice", "Asking for confirmation to remove mac " + mac + " for network " + SSID);
65 | // Ask for confirmation first
66 | AlertDialog.Builder builder = new AlertDialog.Builder(this);
67 | builder.setMessage(String.format(getResources().getString(R.string.dialog_removetrustedmac), mac));
68 | builder.setPositiveButton(R.string.dialog_remove, new DialogInterface.OnClickListener() {
69 | public void onClick(DialogInterface dialog, int id) {
70 | // Actually remove the BSSID from the 'trusted' list
71 | PreferencesStorage prefs = new PreferencesStorage(MACManagerActivity.this);
72 | if (listItem.getAccessPointSafety() == ScanResultsChecker.AccessPointSafety.TRUSTED)
73 | prefs.removeAllowedBSSID(SSID, mac);
74 | else
75 | prefs.removeBlockedBSSID(SSID, mac);
76 | MACManagerActivity.this.refresh();
77 | }
78 | });
79 | builder.setNegativeButton(R.string.dialog_clearhotspots_no, new DialogInterface.OnClickListener() {
80 | public void onClick(DialogInterface dialog, int id) {
81 | // User canceled
82 | }
83 | });
84 | builder.show();
85 | }
86 |
87 | /**
88 | * Get the SSID which is managed by this MAC manager
89 | * @return the network name for this network
90 | */
91 | public String getSSID() {
92 | return SSID;
93 | }
94 |
95 | /**
96 | * Asks the user for confirmation, and then removes all trusted MAC addresses for the current
97 | * SSID.
98 | */
99 | @Override
100 | public void confirmClearAll() {
101 | // Ask for confirmation first
102 | AlertDialog.Builder builder = new AlertDialog.Builder(this);
103 | builder.setMessage(String.format(getResources().getString(R.string.dialog_clearhotspotsformac), SSID));
104 | builder.setPositiveButton(R.string.dialog_clearhotspots_yes, new DialogInterface.OnClickListener() {
105 | public void onClick(DialogInterface dialog, int id) {
106 | // Actually clear the list
107 | PreferencesStorage prefs = new PreferencesStorage(MACManagerActivity.this);
108 | prefs.clearBSSIDsForNetwork(MACManagerActivity.this.getSSID());
109 | MACManagerActivity.this.refresh();
110 | }
111 | });
112 | builder.setNegativeButton(R.string.dialog_clearhotspots_no, new DialogInterface.OnClickListener() {
113 | public void onClick(DialogInterface dialog, int id) {
114 | // User canceled
115 | }
116 | });
117 | builder.show();
118 | }
119 |
120 | protected class MACManagerAdapter extends NetworkManagerAdapter {
121 | public void refresh() {
122 | Log.v("PrivacyPolice", "Refreshing the SSID list adapter");
123 | // Use an ArrayMap so we can put available access points at the top
124 | networkList = new ArrayList<>();
125 |
126 | // Combine the access points that we know of with the access points that are available.
127 | List scanResults = wifiManager.getScanResults();
128 |
129 | Set trustedMACs = prefs.getAllowedBSSIDs(getSSID());
130 | // Add currently available access points that we trust to the list
131 | for (ScanResult scanResult : scanResults) {
132 | if (trustedMACs.contains(scanResult.BSSID)) {
133 | networkList.add(new NetworkAvailability(scanResult.BSSID, scanResult.level, ScanResultsChecker.AccessPointSafety.TRUSTED));
134 | trustedMACs.remove(scanResult.BSSID);
135 | }
136 | }
137 | Set blockedMACs = prefs.getBlockedBSSIDs(getSSID());
138 | // Add currently available access points that we block to the list
139 | for (ScanResult scanResult : scanResults) {
140 | if (blockedMACs.contains(scanResult.BSSID)) {
141 | networkList.add(new NetworkAvailability(scanResult.BSSID, scanResult.level, ScanResultsChecker.AccessPointSafety.UNTRUSTED));
142 | blockedMACs.remove(scanResult.BSSID);
143 | }
144 | }
145 |
146 | // Add all other (non-available) saved SSIDs to the list
147 | for (String MAC : trustedMACs) {
148 | networkList.add(new NetworkAvailability(MAC, -99999, ScanResultsChecker.AccessPointSafety.TRUSTED));
149 | }
150 | for (String MAC : blockedMACs) {
151 | networkList.add(new NetworkAvailability(MAC, -99999, ScanResultsChecker.AccessPointSafety.UNTRUSTED));
152 | }
153 |
154 | notifyDataSetChanged();
155 | }
156 | }
157 | }
--------------------------------------------------------------------------------
/privacypolice/src/main/java/be/uhasselt/privacypolice/NetworkManagerActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, 2015 Bram Bonné
3 | *
4 | * This file is part of Wi-Fi PrivacyPolice.
5 | *
6 | * Wi-Fi PrivacyPolice is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 2 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Wi-Fi PrivacyPolice is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Wi-Fi PrivacyPolice. If not, see .
18 | **/
19 |
20 | package be.uhasselt.privacypolice;
21 |
22 | import android.app.ListActivity;
23 | import android.content.Context;
24 | import android.net.wifi.WifiManager;
25 | import android.os.Bundle;
26 | import android.util.Log;
27 | import android.view.LayoutInflater;
28 | import android.view.Menu;
29 | import android.view.MenuInflater;
30 | import android.view.MenuItem;
31 | import android.view.View;
32 | import android.view.ViewGroup;
33 | import android.widget.BaseAdapter;
34 | import android.widget.ImageView;
35 | import android.widget.LinearLayout;
36 | import android.widget.TextView;
37 |
38 | import java.util.ArrayList;
39 |
40 | /**
41 | * Activity that allows the user to view and modify the stored list of allowed / blocked networks.
42 | * This activity contains only a list of the networks, and the option (in the menu) to remove
43 | * all stored networks.
44 | * This activity is subclassed by SSIDManagerActivity and MACManagerActivity, to manage respectively
45 | * the list of networks, and the list of access points for a specific network.
46 | */
47 |
48 | public abstract class NetworkManagerActivity extends ListActivity {
49 | protected NetworkManagerAdapter adapter;
50 |
51 | @Override
52 | public void onCreate(Bundle savedInstanceState) {
53 | super.onCreate(savedInstanceState);
54 | }
55 |
56 | /**
57 | * When bringing this activity to the foreground, refresh the network list.
58 | */
59 | @Override
60 | public void onResume() {
61 | super.onResume();
62 | refresh();
63 | }
64 |
65 | /**
66 | * Provide the option on the top right of the screen to remove all remembered networks
67 | * @param menu The options menu (provided by the Android OS)
68 | * @return success
69 | */
70 | @Override
71 | public boolean onCreateOptionsMenu(Menu menu) {
72 | MenuInflater inflater = getMenuInflater();
73 | // This menu contains only one item: the removal of all networks altogether
74 | inflater.inflate(R.menu.networkmanager, menu);
75 | return super.onCreateOptionsMenu(menu);
76 | }
77 |
78 | @Override
79 | public boolean onOptionsItemSelected(MenuItem item) {
80 | switch (item.getItemId()) {
81 | case R.id.action_removeall:
82 | // Ask the user to confirm that he/she wants to remove all networks
83 | confirmClearAll();
84 | return true;
85 | default:
86 | return super.onOptionsItemSelected(item);
87 | }
88 | }
89 |
90 | /**
91 | * Repopulate the list by getting the latest information on available networks, and
92 | * combining them with networks stored in the preferences.
93 | */
94 | public void refresh() {
95 | adapter.refresh();
96 | }
97 |
98 | /**
99 | * Ask the user for confirmation that he/she really wants to remove all trusted/untrusted
100 | * APs, and remove them if the user confirms.
101 | */
102 | public abstract void confirmClearAll();
103 |
104 | /**
105 | * Adapter that is responsible for populating the list of networks. In this case, the adapter
106 | * also contains all logic to sort the networks by availability, and for getting the list from
107 | * the preference storage.
108 | */
109 | protected abstract class NetworkManagerAdapter extends BaseAdapter {
110 | protected PreferencesStorage prefs = null;
111 | protected WifiManager wifiManager = null;
112 | private LayoutInflater layoutInflater = null;
113 | // Store the list of networks we know, together with their current availability
114 | protected ArrayList networkList = null;
115 |
116 | public NetworkManagerAdapter() {
117 | Context context = NetworkManagerActivity.this.getApplicationContext();
118 | prefs = new PreferencesStorage(context);
119 | wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
120 | layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
121 |
122 | // Creating the list for the first time
123 | refresh();
124 | }
125 |
126 | /**
127 | * Repopulate the list by getting the latest information on available networks, and
128 | * combining them with networks stored in the preferences.
129 | * Only displays networks that are stored in the preferences.
130 | */
131 | public abstract void refresh();
132 |
133 | @Override
134 | public int getCount() {
135 | return networkList.size();
136 | }
137 |
138 | @Override
139 | public Object getItem(int position) {
140 | return networkList.get(position);
141 | }
142 |
143 | @Override
144 | public long getItemId(int position) {
145 | return position;
146 | }
147 |
148 | /**
149 | * Get the layout for list item at position 'position'
150 | * @param position the position in the list
151 | * @param convertView a previously created view (if available)
152 | * @param parent the parent view
153 | * @return the layout that can be used in the list
154 | */
155 | @Override
156 | public View getView(int position, View convertView, ViewGroup parent) {
157 | LinearLayout layout;
158 | // Recycle a previous view, if available
159 | if (convertView == null) {
160 | // Not available, create a new view
161 | layout = (LinearLayout) layoutInflater.inflate(R.layout.item_networkmanager, null);
162 | } else {
163 | layout = (LinearLayout) convertView;
164 | }
165 |
166 | // Fill in the text part of the layout with the NetworkAvailability
167 | NetworkAvailability SSIDinfo = (NetworkAvailability) getItem(position);
168 | TextView SSIDtext = (TextView) layout.findViewById(R.id.SSIDname);
169 | SSIDtext.setText(SSIDinfo.getName());
170 | // Make the 'signal strength' icon visible if the network is available
171 | ImageView signalStrengthImage = (ImageView) layout.findViewById(R.id.signalStrength);
172 | Log.v("PrivacyPolice", "Adding network " + SSIDinfo.getName() + " with signal strength " + SSIDinfo.getSignalStrength());
173 | // Color signal strength teal (if trusted) or pink (if blocked)
174 | String color = "teal";
175 | if (SSIDinfo.getAccessPointSafety() == ScanResultsChecker.AccessPointSafety.UNTRUSTED)
176 | color = "pink";
177 | String resourceName = "ic_wifi_signal_" + SSIDinfo.getSignalStrength() + "_" + color;
178 | if (SSIDinfo.getSignalStrength() == -1)
179 | resourceName = "ic_wifi_unavailable_" + color;
180 | int resourceId = getResources().getIdentifier(resourceName, "drawable", getPackageName());
181 | signalStrengthImage.setImageResource(resourceId);
182 |
183 | return layout;
184 | }
185 | }
186 |
187 | /**
188 | * Helper class used for storing a network together with its safety (according to PrivacyPolice)
189 | * and its current signal strength
190 | */
191 | protected class NetworkAvailability {
192 | private String name;
193 | private int signalStrength;
194 | private ScanResultsChecker.AccessPointSafety accessPointSafety;
195 |
196 | public NetworkAvailability(String name, int rssi, ScanResultsChecker.AccessPointSafety accessPointSafety) {
197 | this.setName(name);
198 | this.setSignalStrength(rssi);
199 | this.setAccessPointSafety(accessPointSafety);
200 | }
201 |
202 | public String getName() {
203 | return name;
204 | }
205 |
206 | public void setName(String name) {
207 | this.name = name;
208 | }
209 |
210 | public boolean isAvailable() {
211 | return signalStrength >= 0;
212 | }
213 |
214 | public int getSignalStrength() {
215 | return signalStrength;
216 | }
217 |
218 | public void setSignalStrength(int rssi) {
219 | if (rssi < -999) {
220 | signalStrength = -1;
221 | } else {
222 | // Map the RSSI value to an integer in the range [0,4]
223 | signalStrength = WifiManager.calculateSignalLevel(rssi, 5);
224 | }
225 | }
226 |
227 | public ScanResultsChecker.AccessPointSafety getAccessPointSafety() {
228 | return accessPointSafety;
229 | }
230 |
231 | public void setAccessPointSafety(ScanResultsChecker.AccessPointSafety accessPointSafety) {
232 | this.accessPointSafety = accessPointSafety;
233 | }
234 | }
235 | }
236 |
--------------------------------------------------------------------------------
/privacypolice/src/main/java/be/uhasselt/privacypolice/NotificationHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, 2015 Bram Bonné
3 | *
4 | * This file is part of Wi-Fi PrivacyPolice.
5 | *
6 | * Wi-Fi PrivacyPolice is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 2 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Wi-Fi PrivacyPolice is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Wi-Fi PrivacyPolice. If not, see .
18 | */
19 |
20 | package be.uhasselt.privacypolice;
21 |
22 | import android.app.Notification;
23 | import android.app.NotificationManager;
24 | import android.app.PendingIntent;
25 | import android.content.Context;
26 | import android.content.Intent;
27 | import android.content.res.Resources;
28 | import android.support.v4.app.NotificationCompat;
29 | import android.util.Log;
30 |
31 | /**
32 | * Class used to show notifications to the user, and to ask permissions
33 | */
34 | public class NotificationHandler {
35 | public static final int PERMISSION_NOTIFICATION_ID = 0;
36 | public static final int LOCATION_NOTIFICATION_ID = 81;
37 |
38 | private Context context = null;
39 | private NotificationManager notificationManager = null;
40 |
41 | NotificationHandler(Context ctx) {
42 | this.context = ctx;
43 | notificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
44 | }
45 |
46 | /**
47 | * Disables all currently displayed network permissions notifications by PrivacyPolice. This
48 | * allows us to remove stale networks.
49 | */
50 | public void disableNetworkNotifications() {
51 | notificationManager.cancel(PERMISSION_NOTIFICATION_ID);
52 | }
53 |
54 | /**
55 | * Asks the user whether it is certain that a network should be currently available
56 | * @param SSID The name of the network
57 | * @param BSSID The MAC address of the access point that triggered this (only used when we will block the AP)
58 | */
59 | public void askNetworkPermission(String SSID, String BSSID) {
60 | Log.d("PrivacyPolice", "Asking permission for " + SSID + " (" + BSSID + ")");
61 | // Intent that will be used when the user allows the network
62 | Intent addIntent = new Intent(context, PermissionChangeReceiver.class);
63 | addIntent.putExtra("SSID", SSID).putExtra("BSSID", BSSID).putExtra("enable", true);
64 | PendingIntent addPendingIntent = PendingIntent.getBroadcast(context, 0, addIntent, PendingIntent.FLAG_CANCEL_CURRENT);
65 | // Intent that will be used when the user blocks the network
66 | Intent disableIntent = new Intent(context, PermissionChangeReceiver.class);
67 | disableIntent.putExtra("SSID", SSID).putExtra("BSSID", BSSID).putExtra("enable", false);
68 | PendingIntent disablePendingIntent = PendingIntent.getBroadcast(context, 1, disableIntent, PendingIntent.FLAG_CANCEL_CURRENT);
69 | // Intent that will be used when the user's OS does not support notification actions
70 | Intent activityIntent = new Intent(context, AskPermissionActivity.class);
71 | activityIntent.putExtra("SSID", SSID).putExtra("BSSID", BSSID);
72 | PendingIntent activityPendingIntent = PendingIntent.getActivity(context, 2, activityIntent, PendingIntent.FLAG_CANCEL_CURRENT);
73 |
74 | // Build the notification dynamically, based on the network name
75 | Resources res = context.getResources();
76 | String headerString = String.format(res.getString(R.string.permission_header), SSID);
77 | String permissionString = String.format(res.getString(R.string.ask_permission), SSID);
78 | String yes = res.getString(R.string.yes);
79 | String no = res.getString(R.string.no);
80 |
81 | // NotificationCompat makes sure that the notification will also work on Android <4.0
82 | NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context)
83 | .setSmallIcon(R.drawable.ic_notification)
84 | .setPriority(Notification.PRIORITY_MAX) // To force it to be first in list (and thus, expand)
85 | .setContentTitle(headerString)
86 | .setContentText(permissionString)
87 | .setStyle(new NotificationCompat.BigTextStyle().bigText(permissionString))
88 | .setContentIntent(activityPendingIntent)
89 | .addAction(android.R.drawable.ic_delete, no, disablePendingIntent)
90 | .addAction(android.R.drawable.ic_input_add, yes, addPendingIntent);
91 | notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
92 | notificationManager.notify(PERMISSION_NOTIFICATION_ID, notificationBuilder.build());
93 | }
94 |
95 | public void cancelPermissionRequest() {
96 | notificationManager.cancel(PERMISSION_NOTIFICATION_ID);
97 | }
98 |
99 | public void askLocationPermission() {
100 | PreferencesStorage prefs = new PreferencesStorage(context);
101 | if (!prefs.getLocationNoticeEnabled()) {
102 | Log.d("PrivacyPolice", "Location nagging is disabled. Not showing notification");
103 | return;
104 | }
105 |
106 | Log.d("PrivacyPolice", "Asking location permission");
107 | Resources res = context.getResources();
108 | Intent locationNoticeIntent = new Intent(context, LocationNoticeActivity.class);
109 | PendingIntent pendingIntent = PendingIntent.getActivity(context, 3, locationNoticeIntent, PendingIntent.FLAG_UPDATE_CURRENT);
110 |
111 | NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context)
112 | .setSmallIcon(R.drawable.ic_notification)
113 | .setContentTitle(res.getString(R.string.location_permission_header))
114 | .setContentText(res.getString(R.string.location_permission_explanation))
115 | .setStyle(new NotificationCompat.BigTextStyle().bigText(res.getString(R.string.location_permission_explanation)))
116 | .setOngoing(true)
117 | .setContentIntent(pendingIntent);
118 | notificationManager.notify(LOCATION_NOTIFICATION_ID, notificationBuilder.build());
119 | }
120 |
121 | public void cancelLocationPermissionRequest() {
122 | Log.d("PrivacyPolice", "Canceling location permission request");
123 | notificationManager.cancel(LOCATION_NOTIFICATION_ID);
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/privacypolice/src/main/java/be/uhasselt/privacypolice/PermissionChangeReceiver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, 2015 Bram Bonné
3 | *
4 | * This file is part of Wi-Fi PrivacyPolice.
5 | *
6 | * Wi-Fi PrivacyPolice is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 2 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Wi-Fi PrivacyPolice is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Wi-Fi PrivacyPolice. If not, see .
18 | */
19 |
20 | package be.uhasselt.privacypolice;
21 |
22 | import android.app.NotificationManager;
23 | import android.content.BroadcastReceiver;
24 | import android.content.Context;
25 | import android.content.Intent;
26 | import android.net.wifi.WifiManager;
27 | import android.util.Log;
28 |
29 | /**
30 | * Class that handles user actions deciding whether or not an AP should be trusted. Broadcasts are
31 | * sent out by NotificationHandler and AskPermissionActivity.
32 | */
33 | public class PermissionChangeReceiver extends BroadcastReceiver {
34 |
35 | private Context ctx;
36 | private PreferencesStorage prefs;
37 |
38 | @Override
39 | public void onReceive(Context context, Intent intent) {
40 | ctx = context;
41 | prefs = new PreferencesStorage(ctx);
42 |
43 | // Remove the notification that was used to make the decision
44 | removeNotification();
45 |
46 | boolean enable = intent.getBooleanExtra("enable", true);
47 | String SSID = intent.getStringExtra("SSID");
48 | String BSSID = intent.getStringExtra("BSSID");
49 |
50 | if (SSID == null || BSSID == null) {
51 | Log.e("PrivacyPolice", "Could not set permission because SSID or BSSID was null!");
52 | return;
53 | }
54 |
55 | Log.d("PrivacyPolice", "Permission change: " + SSID + " " + BSSID + " " + enable);
56 |
57 | if (enable) {
58 | prefs.addAllowedBSSIDsForLocation(SSID);
59 | // initiate rescan, to make sure our algorithm enables the network, and to make sure
60 | // that Android connects to it
61 | WifiManager wifiManager = (WifiManager) ctx.getSystemService(Context.WIFI_SERVICE);
62 | wifiManager.startScan();
63 | } else
64 | prefs.addBlockedBSSID(SSID, BSSID);
65 | }
66 |
67 | private void removeNotification() {
68 | NotificationHandler notificationHandler = new NotificationHandler(ctx);
69 | notificationHandler.cancelPermissionRequest();
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/privacypolice/src/main/java/be/uhasselt/privacypolice/PreferencesActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, 2015 Bram Bonné
3 | *
4 | * This file is part of Wi-Fi PrivacyPolice.
5 | *
6 | * Wi-Fi PrivacyPolice is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 2 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Wi-Fi PrivacyPolice is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Wi-Fi PrivacyPolice. If not, see .
18 | */
19 |
20 | package be.uhasselt.privacypolice;
21 |
22 | import android.app.Activity;
23 | import android.app.FragmentManager;
24 | import android.app.FragmentTransaction;
25 | import android.content.Context;
26 | import android.content.Intent;
27 | import android.content.SharedPreferences;
28 | import android.net.wifi.WifiManager;
29 | import android.os.Bundle;
30 | import android.preference.Preference;
31 | import android.preference.PreferenceFragment;
32 | import android.util.Log;
33 | import android.view.View;
34 | import android.widget.TextView;
35 |
36 | /**
37 | * Since PrivacyPolice does not need a real MainActivity, this class is used to modify the
38 | * preferences, and view the state of the application.
39 | */
40 | public class PreferencesActivity extends Activity {
41 | @Override
42 | public void onCreate(Bundle savedInstanceState) {
43 | super.onCreate(savedInstanceState);
44 |
45 | setContentView(R.layout.activity_preferences);
46 |
47 | // Display the preferences fragment as the main content.
48 | FragmentManager fragmentManager = getFragmentManager();
49 | FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
50 | PrefsFragment prefsFragment = new PrefsFragment();
51 | fragmentTransaction.replace(R.id.inflatable_prefs, prefsFragment);
52 | fragmentTransaction.commit();
53 |
54 | // Show the location notice if location is disabled
55 | TextView locationNotice = (TextView) findViewById(R.id.location_notice);
56 | LocationAccess locationAccess = new LocationAccess();
57 | if (!locationAccess.isNetworkLocationEnabled(getApplicationContext())) {
58 | locationNotice.setVisibility(View.VISIBLE);
59 | } else
60 | locationNotice.setVisibility(View.GONE);
61 | }
62 |
63 | /**
64 | * Called when location notification is clicked
65 | */
66 | public void openLocationNotice(View view) {
67 | Intent intent = new Intent(this, LocationNoticeActivity.class);
68 | startActivity(intent);
69 | }
70 |
71 | /**
72 | * Fragment that is automatically filled with all preferences described in xml/preferences.xml
73 | */
74 | public static class PrefsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
75 | @Override
76 | public void onCreate(Bundle savedInstanceState) {
77 | super.onCreate(savedInstanceState);
78 |
79 | // Load the preferences from an XML resource
80 | addPreferencesFromResource(R.xml.preferences);
81 | try {
82 | SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
83 | prefs.registerOnSharedPreferenceChangeListener(this);
84 | } catch (NullPointerException npe) {
85 | Log.e("PrivacyPolice", "Null pointer exception when trying to register shared preference change listener");
86 | }
87 |
88 | // Allow modifying of allowed & blocked APs, via a separate button
89 | Preference modifyHotspotsPreference = findPreference("modifyHotspots");
90 | modifyHotspotsPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
91 | @Override
92 | public boolean onPreferenceClick(Preference preference) {
93 | modifyHotspots();
94 | return true;
95 | }
96 | });
97 | }
98 |
99 | @Override
100 | public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
101 | {
102 | // Perform a rescan every time a preference has changed
103 | Log.v("PrivacyPolice", "Initiating rescan because preference " + key + " changed");
104 | try {
105 | // getApplicationContext() to prevent memory leaks on devices < Android N
106 | WifiManager wifiManager = (WifiManager) getActivity().getApplicationContext().getSystemService(Context.WIFI_SERVICE);
107 | wifiManager.startScan();
108 | } catch (NullPointerException npe) {
109 | Log.e("PrivacyPolice", "Could not get WifiManager from within prefsFragment");
110 | }
111 | }
112 |
113 | /**
114 | * Launch the SSID manager activity
115 | */
116 | public void modifyHotspots() {
117 | Log.v("PrivacyPolice", "Launching SSID manager");
118 | Intent intent = new Intent(getActivity(), SSIDManagerActivity.class);
119 | startActivity(intent);
120 | }
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/privacypolice/src/main/java/be/uhasselt/privacypolice/PreferencesStorage.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, 2015 Bram Bonné
3 | *
4 | * This file is part of Wi-Fi PrivacyPolice.
5 | *
6 | * Wi-Fi PrivacyPolice is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 2 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Wi-Fi PrivacyPolice is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Wi-Fi PrivacyPolice. If not, see .
18 | */
19 |
20 | package be.uhasselt.privacypolice;
21 |
22 | import android.content.Context;
23 | import android.content.SharedPreferences;
24 | import android.net.wifi.ScanResult;
25 | import android.net.wifi.WifiManager;
26 | import android.preference.PreferenceManager;
27 | import android.util.Log;
28 |
29 | import java.util.HashSet;
30 | import java.util.List;
31 | import java.util.Map;
32 | import java.util.Set;
33 |
34 | /* Class used for storing and retreiving user preferences, including the list of trusted and
35 | untrusted access points
36 | */
37 |
38 | public class PreferencesStorage {
39 | private SharedPreferences prefs;
40 | private WifiManager wifiManager;
41 | // String used to identify MAC addresses of allowed access points
42 | private final String ALLOWED_BSSID_PREFIX = "ABSSID//";
43 | private final String BLOCKED_BSSID_PREFIX = "BBSSID//";
44 |
45 | public PreferencesStorage(Context ctx) {
46 | this.prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
47 | this.wifiManager = (WifiManager) ctx.getSystemService(Context.WIFI_SERVICE);
48 | try {
49 | Log.v("PrivacyPolice", "Current preferences are: " + prefs.getAll().toString());
50 | } catch (NullPointerException npe) {
51 | Log.d("PrivacyPolice", "No preferences found!");
52 | }
53 | }
54 |
55 | public boolean getEnableOnlyAvailableNetworks() {
56 | return prefs.getBoolean("enableOnlyAvailableNetworks", true);
57 | }
58 |
59 | public boolean getOnlyConnectToKnownAccessPoints() {
60 | return prefs.getBoolean("onlyConnectToKnownAccessPoints", false);
61 | }
62 |
63 | public boolean getLocationNoticeEnabled() {
64 | return prefs.getBoolean("showLocationNotice", true);
65 | }
66 |
67 | /**
68 | * Will be enabled if we decide to implement tracking
69 | * @return
70 | *
71 | public boolean getTrackingAllowed() {
72 | return prefs.getBoolean("trackingAllowed", false);
73 | } */
74 |
75 | /**
76 | * Get a list of trusted MAC addresses for a given SSID
77 | @param SSID the SSID of the network
78 | */
79 | public Set getAllowedBSSIDs(String SSID) {
80 | return getBSSIDs(SSID, true);
81 | }
82 |
83 | /**
84 | * Get a list of blocked MAC addresses for a given SSID
85 | @param SSID the SSID of the network
86 | */
87 | public Set getBlockedBSSIDs(String SSID) {
88 | return getBSSIDs(SSID, false);
89 | }
90 |
91 | /**
92 | * Helper function for getAllowedBSSIDs and getBlockedSSIDs
93 | @param SSID the SSID of the network
94 | @param allowed when true, return the allowed BSSIDs, when false, return blocked BSSIDs
95 | */
96 | private Set getBSSIDs(String SSID, boolean allowed) {
97 | String prefix;
98 | if (allowed)
99 | prefix = ALLOWED_BSSID_PREFIX;
100 | else
101 | prefix = BLOCKED_BSSID_PREFIX;
102 | // Return a copy so the receiver cannot edit the list
103 | return new HashSet<>(prefs.getStringSet(prefix + SSID, new HashSet()));
104 | }
105 |
106 | /**
107 | * Get a list of SSIDs for which we remembered at least one BSSID (either allowed or blocked)
108 | */
109 | public Set getNonemptySSIDs() {
110 | Set results = new HashSet<>();
111 |
112 | Map allPrefs = prefs.getAll();
113 | for (String key : allPrefs.keySet()) {
114 | if (key.startsWith(ALLOWED_BSSID_PREFIX) && prefs.getStringSet(key, new HashSet()).size() > 0) {
115 | results.add(key.substring(ALLOWED_BSSID_PREFIX.length()));
116 | } else if (key.startsWith(BLOCKED_BSSID_PREFIX) && prefs.getStringSet(key, new HashSet()).size() > 0) {
117 | results.add(key.substring(BLOCKED_BSSID_PREFIX.length()));
118 | }
119 | }
120 | return results;
121 | }
122 |
123 | /**
124 | * Adds all BSSIDs that are currently in range for the specified SSID (prevents nagging)
125 | * We are assuming the user does not know the BSSID of the AP it wants to trust, anyway, and
126 | * choose the more useable option.
127 | * @param SSID the SSID of the network that needs to be allowed at this location
128 | */
129 | public void addAllowedBSSIDsForLocation(String SSID) {
130 | List scanResults = wifiManager.getScanResults();
131 | for (ScanResult result : scanResults) {
132 | if (SSID.equals(result.SSID))
133 | addAllowedBSSID(SSID, result.BSSID);
134 | }
135 | }
136 |
137 | public void addAllowedBSSID(String SSID, String BSSID) {
138 | Log.i("PrivacyPolice", "Adding allowed BSSID " + BSSID + " for network " + SSID);
139 | editBSSID(SSID, BSSID, true, true);
140 | }
141 |
142 | public void addBlockedBSSID(String SSID, String BSSID) {
143 | Log.i("PrivacyPolice", "Adding blocked BSSID " + BSSID + " for network " + SSID);
144 | editBSSID(SSID, BSSID, false, true);
145 | }
146 |
147 | /**
148 | * Remove a specific MAC address as trusted for the given SSID
149 | * @param SSID the SSID of the network
150 | * @param BSSID the MAC address of the trusted access point
151 | */
152 | public void removeAllowedBSSID(String SSID, String BSSID) {
153 | Log.i("PrivacyPolice", "Removing allowed BSSID " + BSSID + " for network " + SSID);
154 | editBSSID(SSID, BSSID, true, false);
155 | }
156 |
157 | public void removeBlockedBSSID(String SSID, String BSSID) {
158 | Log.i("PrivacyPolice", "Removing blocked BSSID " + BSSID + " for network " + SSID);
159 | editBSSID(SSID, BSSID, false, false);
160 | }
161 |
162 | /**
163 | * Helper function for addAllowedBSSID, addBlockedSSID, removedAllowedBSSID and removeBlockedBSSID
164 | * @param SSID the SSID of the network
165 | * @param BSSID the MAC address of the trusted access point
166 | * @param allowed when true, add to allowed BSSIDs, when false, add to blocked BSSIDs
167 | * @param add when true, add the network to the list, when false, remove the network
168 | */
169 | private void editBSSID(String SSID, String BSSID, boolean allowed, boolean add) {
170 | // Get the correct prefix (allowed or blocked hotspots)
171 | String prefix;
172 | if (allowed)
173 | prefix = ALLOWED_BSSID_PREFIX;
174 | else
175 | prefix = BLOCKED_BSSID_PREFIX;
176 |
177 | // Get the current list of known networks
178 | Set currentlyInList = prefs.getStringSet(prefix + SSID, new HashSet());
179 | // Create copy of list, because sharedPreferences only checks whether *reference* is the same
180 | // In order to add elements, we thus need a new object (otherwise nothing changes)
181 | Set newList = new HashSet<>(currentlyInList);
182 | if (add)
183 | newList.add(BSSID);
184 | else
185 | newList.remove(BSSID);
186 | SharedPreferences.Editor editor = prefs.edit();
187 | editor.putStringSet(prefix + SSID, newList);
188 | editor.commit();
189 | }
190 |
191 | /**
192 | * Erase all trusted and untrusted hotspots.
193 | */
194 | public void clearBSSIDLists() {
195 | Log.d("PrivacyPolice", "Removing all trusted/untrusted hotspots");
196 | SharedPreferences.Editor editor = prefs.edit();
197 |
198 | // Erase all allowed SSIDs, by emptying their MAC address lists.
199 | for (String key: prefs.getAll().keySet()) {
200 | if (key.startsWith(ALLOWED_BSSID_PREFIX) || key.startsWith(BLOCKED_BSSID_PREFIX))
201 | editor.putStringSet(key, new HashSet());
202 | }
203 |
204 | editor.commit();
205 | }
206 |
207 | /**
208 | * Erase all known hotspots for a specific SSID.
209 | */
210 | public void clearBSSIDsForNetwork(String SSID) {
211 | Log.d("PrivacyPolice", "Removing all known hotspots for network " + SSID);
212 | SharedPreferences.Editor editor = prefs.edit();
213 |
214 | // Erase all trusted network for this SSID, by emptying its MAC address list.
215 | editor.putStringSet(ALLOWED_BSSID_PREFIX + SSID, new HashSet());
216 | // Erase all blocked network for this SSID
217 | editor.putStringSet(BLOCKED_BSSID_PREFIX + SSID, new HashSet());
218 |
219 | editor.commit();
220 | }
221 | }
222 |
--------------------------------------------------------------------------------
/privacypolice/src/main/java/be/uhasselt/privacypolice/SSIDManagerActivity.java:
--------------------------------------------------------------------------------
1 | package be.uhasselt.privacypolice;
2 |
3 | import android.app.AlertDialog;
4 | import android.content.DialogInterface;
5 | import android.content.Intent;
6 | import android.net.wifi.ScanResult;
7 | import android.os.Bundle;
8 | import android.util.Log;
9 | import android.view.View;
10 | import android.widget.ListView;
11 |
12 | import java.util.ArrayList;
13 | import java.util.List;
14 | import java.util.Set;
15 |
16 | /**
17 | * Activity that allows the user to view and modify the stored list of allowed / blocked networks.
18 | * This activity contains only a list of the SSIDs, and the option (in the menu) to remove
19 | * all stored SSIDs.
20 | **/
21 | public class SSIDManagerActivity extends NetworkManagerActivity {
22 | private ScanResultsChecker scanResultsChecker;
23 |
24 | @Override
25 | public void onCreate(Bundle savedInstanceState) {
26 | super.onCreate(savedInstanceState);
27 | Log.v("PrivacyPolice", "Creating SSID manager activity");
28 |
29 | scanResultsChecker = new ScanResultsChecker(this);
30 | adapter = new SSIDManagerAdapter();
31 | setListAdapter(adapter);
32 | }
33 |
34 | /**
35 | * When an SSID is clicked, redirect to the MAC manager for that network.
36 | * @param listView The listview containing the SSID item
37 | * @param view The clicked view
38 | * @param position The position of the clicked item in the list
39 | * @param id The row id of the clicked item
40 | */
41 | @Override
42 | protected void onListItemClick(ListView listView, View view, int position, long id) {
43 | Intent intent = new Intent(this, MACManagerActivity.class);
44 | // Pass the SSID to the new activity
45 | NetworkAvailability listItem = (NetworkAvailability) listView.getItemAtPosition(position);
46 | String networkName = listItem.getName();
47 | intent.putExtra("SSID", networkName);
48 |
49 | startActivity(intent);
50 | }
51 |
52 | /**
53 | * Asks the user for confirmation, and then removes all trusted and untrusted access points.
54 | */
55 | @Override
56 | public void confirmClearAll() {
57 | // Ask for confirmation first
58 | AlertDialog.Builder builder = new AlertDialog.Builder(this);
59 | builder.setMessage(R.string.dialog_clearhotspots);
60 | builder.setPositiveButton(R.string.dialog_clearhotspots_yes, new DialogInterface.OnClickListener() {
61 | public void onClick(DialogInterface dialog, int id) {
62 | // Actually clear the list
63 | PreferencesStorage prefs = new PreferencesStorage(SSIDManagerActivity.this);
64 | prefs.clearBSSIDLists();
65 | SSIDManagerActivity.this.refresh();
66 | }
67 | });
68 | builder.setNegativeButton(R.string.dialog_clearhotspots_no, new DialogInterface.OnClickListener() {
69 | public void onClick(DialogInterface dialog, int id) {
70 | // User canceled
71 | }
72 | });
73 | builder.show();
74 | }
75 |
76 | protected class SSIDManagerAdapter extends NetworkManagerAdapter {
77 | public void refresh() {
78 | Log.v("PrivacyPolice", "Refreshing the network list adapter");
79 | // Use an ArrayMap so we can put available networks at the top
80 | networkList = new ArrayList<>();
81 |
82 | // Combine the SSIDs that we know of with the SSIDs that are available.
83 | List scanResults = wifiManager.getScanResults();
84 | Set knownSSIDs = prefs.getNonemptySSIDs();
85 |
86 | // Add currently available networks that are stored in the preferences to the list
87 | for (ScanResult scanResult : scanResults) {
88 | if (knownSSIDs.contains(scanResult.SSID)) {
89 | ScanResultsChecker.AccessPointSafety networkSafety = scanResultsChecker.getNetworkSafety(scanResult.SSID, scanResults);
90 | networkList.add(new NetworkAvailability(scanResult.SSID, scanResult.level, networkSafety));
91 | knownSSIDs.remove(scanResult.SSID);
92 | }
93 | }
94 |
95 | // Add all other (non-available) saved SSIDs to the list
96 | for (String SSID : knownSSIDs) {
97 | ScanResultsChecker.AccessPointSafety networkSafety = ScanResultsChecker.AccessPointSafety.UNKNOWN;
98 | networkList.add(new NetworkAvailability(SSID, -9999, networkSafety));
99 | }
100 | notifyDataSetChanged();
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/privacypolice/src/main/java/be/uhasselt/privacypolice/ScanResultsChecker.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, 2015 Bram Bonné
3 | *
4 | * This file is part of Wi-Fi PrivacyPolice.
5 | *
6 | * Wi-Fi PrivacyPolice is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 2 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Wi-Fi PrivacyPolice is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Wi-Fi PrivacyPolice. If not, see .
18 | */
19 |
20 | package be.uhasselt.privacypolice;
21 |
22 | import android.content.BroadcastReceiver;
23 | import android.content.Context;
24 | import android.content.Intent;
25 | import android.net.ConnectivityManager;
26 | import android.net.NetworkInfo;
27 | import android.net.wifi.ScanResult;
28 | import android.net.wifi.WifiConfiguration;
29 | import android.net.wifi.WifiManager;
30 | import android.os.Handler;
31 | import android.util.Log;
32 |
33 | import java.util.List;
34 | import java.util.Set;
35 |
36 | /**
37 | * This class contains the actual logic for deciding whether a network connection is allowed.
38 | * It receives the broadcast intents for new scan results, in order to decide whether a network is
39 | * available. It then checks whether we trust the AP's MAC address, based on the user's configuration.
40 | */
41 |
42 | public class ScanResultsChecker extends BroadcastReceiver {
43 |
44 | public enum AccessPointSafety {
45 | TRUSTED, UNTRUSTED, UNKNOWN
46 | }
47 |
48 | // The last time we checked all networks.
49 | private static long lastCheck = 0;
50 | private static PreferencesStorage prefs = null;
51 | private static WifiManager wifiManager = null;
52 | private static ConnectivityManager connectivityManager = null;
53 | private static NotificationHandler notificationHandler = null;
54 | private static Context context = null;
55 |
56 | /**
57 | * Default constructor allowing to use this class as a receiver.
58 | * DO NOT USE THIS CONSTRUCTOR WHEN INSTANTIATING THIS CLASS MANUALLY. Pass the context as the
59 | * single parameter to this constructor instead.
60 | */
61 | public ScanResultsChecker() {
62 | super();
63 | }
64 |
65 | /**
66 | * Non-default constructor which allows other classes to instantiate this class with a given context
67 | * @param ctx Context of the caller
68 | */
69 | public ScanResultsChecker(Context ctx) {
70 | init(ctx);
71 | }
72 |
73 | /**
74 | * Initialize static variables, depending on the current context
75 | * @param ctx The current context
76 | */
77 | public void init(Context ctx) {
78 | // Use getApplicationContext() to prevent memory leaks on devices < Android N
79 | wifiManager = (WifiManager) ctx.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
80 | connectivityManager = (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
81 | prefs = new PreferencesStorage(ctx);
82 | notificationHandler = new NotificationHandler(ctx);
83 | context = ctx;
84 | }
85 |
86 | /**
87 | * Called for the following intents:
88 | * - SCAN_RESULTS available
89 | * - BOOT_COMPLETED
90 | */
91 | public void onReceive(Context ctx, Intent intent) {
92 | if (wifiManager == null) // TODO: make this class a singleton
93 | init(ctx);
94 | // Make sure the wakelockHandler keeps running (to prevent Android 6.0 and up from completely suspending our operations)
95 | WakelockHandler.getInstance(ctx).ensureAwake();
96 |
97 | // WiFi scan performed
98 | // Older devices might try to scan constantly. Allow them some rest by checking max. once every 0.5 seconds
99 | if (System.currentTimeMillis() - lastCheck < 500)
100 | return;
101 | lastCheck = System.currentTimeMillis();
102 |
103 | // Check our location permission, and request if needed
104 | LocationAccess.checkAccessDisplayNotification(context);
105 |
106 | try {
107 | List scanResults = wifiManager.getScanResults();
108 | Log.d("PrivacyPolice", "Wi-Fi scan performed, results are: " + scanResults.toString());
109 | checkResults(scanResults);
110 | } catch (NullPointerException npe) {
111 | Log.e("PrivacyPolice", "Null pointer exception when handling networks. Wi-Fi was probably suddenly disabled after a scan", npe);
112 | }
113 | }
114 |
115 | /**
116 | * Check which networks should be enabled, and enable them accordingly. Ask for user input when
117 | * a network's safety level can not be determined
118 | * @param scanResults The results of the last network scan
119 | */
120 | private void checkResults(List scanResults) {
121 | // Keep whether the getNetworkSafety function asked the user for input (to know whether we
122 | // have to disable any notifications afterwards, and to keep the UX as smooth as possible).
123 | // Alternatively, we would disable previous notifications here, but that would lead to the
124 | // notification being jittery (disappearing and re-appearing instantly, instead of just
125 | // updating).
126 | boolean notificationShown = false;
127 |
128 | // Collect number of found networks, if allowed by user
129 | /*Analytics analytics = new Analytics(ctx);
130 | analytics.scanCompleted(scanResults.size());*/
131 |
132 | List networkList = wifiManager.getConfiguredNetworks();
133 | if (networkList == null) {
134 | Log.i("PrivacyPolice", "WifiManager did not return any configured networks. This is "+
135 | "most likely caused by background location services being allowed to scan for " +
136 | "Wi-Fi networks, while Wi-Fi is disabled. Keep all networks as before.");
137 | return;
138 | }
139 | // Check for every network in our network list whether it should be enabled
140 | for (WifiConfiguration network : networkList) {
141 | AccessPointSafety networkSafety = getNetworkSafety(network, scanResults);
142 | if (networkSafety == AccessPointSafety.TRUSTED) {
143 | Log.i("PrivacyPolice", "Enabling " + network.SSID);
144 | connectTo(network.networkId);
145 | } else if (networkSafety == AccessPointSafety.UNTRUSTED) {
146 | // Make sure all other networks are disabled, by disabling them separately
147 | // (See comment in connectTo() method to see why we don't disable all of them at the
148 | // same time)
149 | wifiManager.disableNetwork(network.networkId);
150 | } else if (networkSafety == AccessPointSafety.UNKNOWN) {
151 | wifiManager.disableNetwork(network.networkId);
152 | notificationShown = true;
153 | }
154 | }
155 |
156 | if (!notificationShown) {
157 | // Disable previous notifications, to make sure that we only request permission for the
158 | // currently available networks (and not at the wrong location)
159 | notificationHandler.disableNetworkNotifications();
160 | }
161 | }
162 |
163 | /**
164 | * Enable a given Wi-Fi network, and force Android to connect to it. This function makes sure
165 | * that connecting also works in Android 5.0 and up.
166 | * @param networkId The id of the network (found in its configuration) to enable
167 | */
168 | private void connectTo(int networkId) {
169 | // Do not disable other networks, as multiple networks may be available
170 | wifiManager.enableNetwork(networkId, false);
171 | // If we aren't already connected to a network, make sure that Android connects.
172 | // This is required for devices running Android Lollipop (5.0) and up, because
173 | // they would otherwise never connect.
174 | wifiManager.reconnect();
175 | // In some instances (since wpa_supplicant 2.3), even the previous is not sufficient
176 | // Check if we are in a CONNECTING state, or reassociate to force connection
177 | Handler handler = new Handler();
178 | // Wait for 1 second before checking
179 | handler.postDelayed(new Runnable() {
180 | public void run() {
181 | NetworkInfo wifiState = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
182 | if (!wifiState.isConnectedOrConnecting()) {
183 | Log.i("PrivacyPolice", "Reassociating, because WifiManager doesn't seem to be eager to reconnect.");
184 | wifiManager.reassociate();
185 | }
186 | }
187 | }, 1000);
188 | }
189 |
190 | /**
191 | * Checks whether we should allow connection to a given network, based on the user's preferences
192 | * It will also ask the user if it is unknown whether the network should be trusted.
193 | * @param network The network that should be checked
194 | * @param scanResults The networks that are currently available
195 | * @return TRUSTED or UNTRUSTED, based on the user's preferences, or UNKNOWN if the user didn't
196 | * specify anything yet
197 | */
198 | public AccessPointSafety getNetworkSafety(WifiConfiguration network, List scanResults) {
199 | // If all settings are disabled by the user, then allow every network
200 | // This effectively disables all of the app's functionalities
201 | if (!(prefs.getEnableOnlyAvailableNetworks() || prefs.getOnlyConnectToKnownAccessPoints())) {
202 | return AccessPointSafety.TRUSTED; // Allow every network
203 | }
204 | // If location access is disabled by the user (or if it is not granted to our app), allow
205 | // every network (as otherwise PrivacyPolice would block normal operation of the phone).
206 | // Rationale: a huge warning is displayed both as a notification, and in the main activity
207 | // when the user does not enable location access. It is unfortunately the only way for us
208 | // to view scan results
209 | // Some devices still allow scan results to be passed on even if the location is disabled.
210 | // In this case, we operate as normally by checking if any network is in range
211 | if (!LocationAccess.isNetworkLocationEnabled(context) && scanResults.size() == 0) {
212 | return AccessPointSafety.TRUSTED; // Allow every network
213 | }
214 |
215 | // Always enable hidden networks, since they *need* to use directed probe requests
216 | // in order to be discovered. Note that using hidden SSID's does not add any
217 | // real security , so it's best to avoid them whenever possible.
218 | if (network.hiddenSSID)
219 | return AccessPointSafety.TRUSTED;
220 |
221 | // Strip double quotes (") from the SSID string
222 | String plainSSID = network.SSID.substring(1, network.SSID.length() - 1);
223 |
224 | return getNetworkSafety(plainSSID, scanResults);
225 | }
226 |
227 | /**
228 | * Checks whether we should allow connection to a given SSID, based on the user's preferences
229 | * It will also ask the user if it is unknown whether the network should be trusted.
230 | * @param SSID The SSID of the network that should be checked
231 | * @param scanResults The networks that are currently available
232 | * @return TRUSTED or UNTRUSTED, based on the user's preferences, or UNKNOWN if the user didn't
233 | * specify anything yet
234 | */
235 | public AccessPointSafety getNetworkSafety(String SSID, List scanResults) {
236 | for (ScanResult scanResult : scanResults) {
237 | if (scanResult.SSID.equals(SSID)) {
238 | // Check whether the user wants to filter by MAC address
239 | if (!prefs.getOnlyConnectToKnownAccessPoints()) { // Any MAC address is fair game
240 | // Enabling now makes sure that we only want to connect when it is in range
241 | return AccessPointSafety.TRUSTED;
242 | } else { // Check access point's MAC address
243 | // Check if the MAC address is in the list of allowed MAC's for this SSID
244 | Set allowedBSSIDs = prefs.getAllowedBSSIDs(scanResult.SSID);
245 | if (allowedBSSIDs.contains(scanResult.BSSID)) {
246 | return AccessPointSafety.TRUSTED;
247 | } else {
248 | // Not an allowed BSSID
249 | if (prefs.getBlockedBSSIDs(scanResult.SSID).contains(scanResult.BSSID)) {
250 | // This SSID was explicitly blocked by the user!
251 | Log.w("PrivacyPolice", "Spoofed network for " + scanResult.SSID + " detected! (BSSID is " + scanResult.BSSID + ")");
252 | return AccessPointSafety.UNTRUSTED;
253 | } else {
254 | // We don't know yet whether the user wants to allow this network
255 | // Ask the user what needs to be done
256 | notificationHandler.askNetworkPermission(scanResult.SSID, scanResult.BSSID);
257 | return AccessPointSafety.UNKNOWN;
258 | }
259 | }
260 | }
261 | }
262 | }
263 | return AccessPointSafety.UNTRUSTED; // Network not in range
264 | }
265 | }
266 |
--------------------------------------------------------------------------------
/privacypolice/src/main/java/be/uhasselt/privacypolice/WakelockHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, 2015 Bram Bonné
3 | *
4 | * This file is part of Wi-Fi PrivacyPolice.
5 | *
6 | * Wi-Fi PrivacyPolice is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 2 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Wi-Fi PrivacyPolice is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with Wi-Fi PrivacyPolice. If not, see .
18 | */
19 |
20 | package be.uhasselt.privacypolice;
21 |
22 | import android.app.AlarmManager;
23 | import android.app.PendingIntent;
24 | import android.content.BroadcastReceiver;
25 | import android.content.Context;
26 | import android.content.Intent;
27 | import android.net.wifi.WifiManager;
28 | import android.util.Log;
29 |
30 | /**
31 | * This class makes sure that AppStandby on Android 6.0 and up does not interfere with PrivacyPolice
32 | * (and thus, with normal Wi-Fi operation) by scheduling conservative wakelocks/alarms regularly.
33 | * This prevents the kind of situation where all apps that need Wi-Fi access are woken up regularly
34 | * by the OS, whereas PrivacyPolice (having no Activities that are visited regularly by the user)
35 | * is kept idle, preventing the results of a scan from being passed on to to the
36 | * PermissionChangeReceiver, and preventing Wi-Fi access for the entire OS.
37 | * It works by triggering an alarm approximately every 15 minutes, while still adhering to Android's
38 | * doze mode.
39 | * TODO: check if this is still needed after the location services fix
40 | */
41 | public class WakelockHandler extends BroadcastReceiver {
42 | private static WakelockHandler instance = null;
43 | private Context context = null;
44 | private AlarmManager alarmManager = null;
45 |
46 | public static WakelockHandler getInstance(Context ctx) {
47 | if (instance == null) {
48 | instance = new WakelockHandler(ctx);
49 | }
50 | return instance;
51 | }
52 |
53 | public WakelockHandler(Context ctx) {
54 | this.context = ctx;
55 | this.alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
56 | ensureAwake();
57 | }
58 |
59 | public void scheduleAlarms() {
60 | Intent wakeupIntent = new Intent(context, WakelockHandler.class);
61 | PendingIntent pendingIntent = PendingIntent.getBroadcast(context, this.hashCode(), wakeupIntent, PendingIntent.FLAG_UPDATE_CURRENT);
62 | alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 0, AlarmManager.INTERVAL_FIFTEEN_MINUTES, pendingIntent);
63 | }
64 |
65 | public void ensureAwake() {
66 | Log.v("PrivacyPolice", "Ensuring we're still awake");
67 | Intent wakeupIntent = new Intent(context, WakelockHandler.class);
68 | // Check if the alarm is still scheduled
69 | if (PendingIntent.getBroadcast(context, this.hashCode(), wakeupIntent, PendingIntent.FLAG_NO_CREATE) == null) {
70 | Log.w("PrivacyPolice", "Re-scheduling alarms, since our alarm manager didn't seem to be running");
71 | scheduleAlarms();
72 | }
73 | }
74 |
75 | public WakelockHandler() {
76 | // Only used for the BroadcastReceiver aspect of this class
77 | super();
78 | }
79 |
80 | @Override
81 | public void onReceive(Context context, Intent intent) {
82 | Log.v("PrivacyPolice", "Waking up because of alarm");
83 | // Start a Wi-Fi scan
84 | WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
85 | wifiManager.startScan();
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-hdpi-v11/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-hdpi-v11/ic_notification.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-hdpi-v9/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-hdpi-v9/ic_notification.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-hdpi/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-hdpi/ic_notification.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-hdpi/ic_wifi_signal_0_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-hdpi/ic_wifi_signal_0_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-hdpi/ic_wifi_signal_1_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-hdpi/ic_wifi_signal_1_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-hdpi/ic_wifi_signal_2_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-hdpi/ic_wifi_signal_2_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-hdpi/ic_wifi_signal_3_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-hdpi/ic_wifi_signal_3_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-hdpi/ic_wifi_signal_4_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-hdpi/ic_wifi_signal_4_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-mdpi-v11/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-mdpi-v11/ic_notification.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-mdpi-v9/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-mdpi-v9/ic_notification.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-mdpi/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-mdpi/ic_notification.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-mdpi/ic_wifi_signal_0_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-mdpi/ic_wifi_signal_0_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-mdpi/ic_wifi_signal_1_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-mdpi/ic_wifi_signal_1_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-mdpi/ic_wifi_signal_2_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-mdpi/ic_wifi_signal_2_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-mdpi/ic_wifi_signal_3_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-mdpi/ic_wifi_signal_3_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-mdpi/ic_wifi_signal_4_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-mdpi/ic_wifi_signal_4_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xhdpi-v11/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xhdpi-v11/ic_notification.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xhdpi-v9/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xhdpi-v9/ic_notification.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xhdpi/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xhdpi/ic_notification.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xhdpi/ic_wifi_signal_0_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xhdpi/ic_wifi_signal_0_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xhdpi/ic_wifi_signal_1_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xhdpi/ic_wifi_signal_1_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xhdpi/ic_wifi_signal_2_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xhdpi/ic_wifi_signal_2_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xhdpi/ic_wifi_signal_3_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xhdpi/ic_wifi_signal_3_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xhdpi/ic_wifi_signal_4_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xhdpi/ic_wifi_signal_4_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xxhdpi-v11/border.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xxhdpi-v11/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xxhdpi-v11/ic_notification.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xxhdpi-v9/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xxhdpi-v9/ic_notification.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xxhdpi/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xxhdpi/ic_notification.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xxhdpi/ic_wifi_signal_0_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xxhdpi/ic_wifi_signal_0_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xxhdpi/ic_wifi_signal_1_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xxhdpi/ic_wifi_signal_1_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xxhdpi/ic_wifi_signal_2_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xxhdpi/ic_wifi_signal_2_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xxhdpi/ic_wifi_signal_3_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xxhdpi/ic_wifi_signal_3_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xxhdpi/ic_wifi_signal_4_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xxhdpi/ic_wifi_signal_4_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_signal_0_pink.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_signal_0_pink.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_signal_0_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_signal_0_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_signal_1_pink.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_signal_1_pink.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_signal_1_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_signal_1_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_signal_2_pink.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_signal_2_pink.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_signal_2_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_signal_2_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_signal_3_pink.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_signal_3_pink.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_signal_3_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_signal_3_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_signal_4_pink.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_signal_4_pink.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_signal_4_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_signal_4_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_unavailable_pink.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_unavailable_pink.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_unavailable_teal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/drawable-xxxhdpi/ic_wifi_unavailable_teal.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/layout/activity_askpermission.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 |
16 |
17 |
31 |
32 |
42 |
43 |
49 |
55 |
56 |
--------------------------------------------------------------------------------
/privacypolice/src/main/res/layout/activity_locationnotice.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
9 |
10 |
16 |
17 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/privacypolice/src/main/res/layout/activity_preferences.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
16 |
17 |
22 |
23 |
--------------------------------------------------------------------------------
/privacypolice/src/main/res/layout/item_networkmanager.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
23 |
--------------------------------------------------------------------------------
/privacypolice/src/main/res/menu/ask_permission.xml:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/privacypolice/src/main/res/menu/networkmanager.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/privacypolice/src/main/res/mipmap-hdpi/ic_menu_clear_playlist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/mipmap-hdpi/ic_menu_clear_playlist.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/mipmap-mdpi/ic_menu_clear_playlist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/mipmap-mdpi/ic_menu_clear_playlist.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/mipmap-xhdpi/ic_menu_clear_playlist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/mipmap-xhdpi/ic_menu_clear_playlist.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/mipmap-xxhdpi/ic_menu_clear_playlist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/mipmap-xxhdpi/ic_menu_clear_playlist.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/mipmap-xxxhdpi/ic_menu_clear_playlist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BramBonne/privacypolice/9b2d032fab6f8fb39ab338881f9d578985fbc19e/privacypolice/src/main/res/mipmap-xxxhdpi/ic_menu_clear_playlist.png
--------------------------------------------------------------------------------
/privacypolice/src/main/res/values-de/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Wi-Fi Privacy Police
5 | Privatsphäre
6 | Schützen Sie sich davor, dass Fremde die Liste genutzter WLAN-Netwerke sehen, indem Sie einzelne Netzwerke nur aktivieren, wenn sie in Reichweite sind.
7 | Datenschutz
8 | Verbinden Sie sich nur mit WLAN-Zugangspunkten, wenn diese verfügbar sein sollten (Sie werden dazu beim ersten Mal vor dem Verbinden gefragt).
9 | Sollte das Netzwerk "%1$s" jetzt verfügbar sein?
10 | Ja
11 | Nein
12 | \"%1$s\" gefunden
13 | Einstellungen
14 | Wi-Fi Privacy Police schützt Sie im Hintergrund. Sie können diese Anwendung schließen und müssen sich nicht weiter um diese Aspekte des Schutzes Ihrer Privatsphäre sorgen.
15 | Erlaubte und blockierte Hotspots löschen
16 | Hiermit wird die Liste aller vertrauenswürdigen und nicht vertrauenswürdigen Hotspots gelöscht.
17 | Sind Sie sicher, dass Sie die Liste aller vertrauenswürdigen und nicht vertrauenswürdigen Hotspots entfernen möchten? Dies wird dazu führen, dass Privacy Police bei jedem Hotspot nachfrägt, ob er verfügbar sein sollte.
18 | Löschen
19 | Abbrechen
20 | Anonyme Nutzungsstatistiken senden
21 | Die Aktivierung dieser Funktion hilft bei der Weiterentwicklung dieser App. Wir sammeln keine personenbezogenen Daten, wie z.B. Netzwerknamen.
22 | Known hotspots
23 | Remove hotspots from your list of trusted and blocked hotspots (advanced)
24 | Are you sure you want to remove access point \"%1$s\"?
25 | Remove
26 | Are you sure you want to remove all hotspots for the network \"%1$s\"?
27 | Location access disabled
28 | Wi-Fi PrivacyPolice might need (limited) location access in order to function correctly. Click here for more info.
29 | Starting with Android version 6.0 (Marshmallow), apps can only view the list of Wi-Fi networks that are in range while location access is enabled. Your mileage may vary (depending on the device you\'re using, this might not be the case), but if you experience problems when using Wi-Fi PrivacyPolice, consider enabling location access. Coarse location access (only using Wi-Fi networks and cell towers, and not your actual GPS chip) should be sufficient.
30 | Open location settings
31 | Show location notice
32 | Remind me via a notification when coarse location access is disabled
33 |
34 |
--------------------------------------------------------------------------------
/privacypolice/src/main/res/values-es/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Wi-Fi Privacy Police
5 | Protección de la privacidad
6 | Evitar que otras personas vean tu lista de redes habilitándolas solamente cuando están en el rango
7 | Protección de los datos
8 | Permitir conexiones a puntos de acceso cuando deberían estar disponibles (consultando la primera vez que se conecta a un nuevo punto de acceso)
9 | ¿Seguro que "%1$s" debería estar disponible ahora?
10 | Sí
11 | No
12 | Encontrada \"%1$s\"
13 | Ajustes
14 | Wi-Fi Privacy Police continuará la protección en segundo plano. Puedes elegir cerrar esta ventana y dejar de preocuparte por información sensible que pueda ser filtrada desde tu dispositivo.
15 | Limpiar todos los puntos de acceso
16 | Pulsa aquí para eliminar de la lista todos los puntos de acceso, se confíe en ellos o no
17 | ¿Seguro que quieres eliminar todos los puntos de acceso? Esto resultará en que Privacy Police preguntará para cada punto de acceso, si debe estar disponible
18 | Limpiar
19 | Cancelar
20 | ¿Seguro que quieres eliminar todos los puntos de acceso de la red \"%1$s\"?
21 | Permitir estadísticas anónimas de uso
22 | Habilitándolas ayudas a la investigación enviando periódicamente datos anónimos de uso, como si aún sigues usando la aplicación o no. No recolectamos ningún dato personal o información identificable, como nombres de redes.
23 | Puntos de acceso conocidos
24 | Eliminar puntos de acceso de la lista de puntos de acceso en los que se confía y puntos de acceso bloqueados (avanzado)
25 | ¿Seguro que quieres eliminar el punto de acceso \"%1$s\"?
26 | Eliminar
27 | Acceso a ubicación deshabilitado
28 | Wi-Fi PrivacyPolice puede necesitar acceso (limitado) a la ubicación para poder funcionar correctamente. Pulsa aquí para más información.
29 | Comenzando con la versión 6.0 de Android (Marshmallow), las aplicaciones solo pueden ver la lista de redes Wi-Fi que están en el rango si el acceso a la ubicación está habilitado. Puede variar según el caso (dependiendo del dispositivo que usas, esto puede que no sea el caso), pero si experimentas problemas usando Wi-Fi PrivacyPolice, considera habilitar el acceso a la ubicación. Acceso a una ubicación aproximada (usando solamente redes Wi-Fi y torres de telefonía, y no el chip GPS) debería ser suficiente.
30 | Abrir ajustes de ubicación
31 | Mostrar aviso de ubicación
32 | Recordarme con una notificación cuando el acceso a ubicación aproximada está deshabilitado
33 |
34 |
--------------------------------------------------------------------------------
/privacypolice/src/main/res/values-fr/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Wi-Fi Privacy Police
5 | Protection de la vie privée
6 | Empêcher que d\'autres personnes puissent accéder à votre liste des points d\'accès connus
7 | Protection des données
8 | Autoriser que les connexions aux points d\'accès de confiance (une confirmation vous sera demandée lors de la première connexion)
9 | Faites-vous confiance au réseau "%1$s"\u00a0?
10 | Oui
11 | Non
12 | \"%1$s\" rencontré
13 | Paramètres
14 | Wi-Fi Privacy Police continue de vous protéger en arrière-plan. Vous pouvez fermer cette fenêtre.
15 | Retirer tous les points d\'accès
16 | Appuyez ici pour retirer votre liste de points d\'accès
17 | Êtes-vous sûr de vouloir retirer la liste de points d\'accès\u00a0? Wi-Fi Privacy Police vous redemandera confirmation à chaque première connexion au point d\'accès
18 | Retirer
19 | Annuler
20 | Êtes-vous sûr de vouloir retirer tous les points d\'accès du réseau \"%1$s\"\u00a0?
21 | Autoriser les statistiques d\'utilisation anonymes
22 | Activer cette option aide au développement en envoyant périodiquement des données anonymes, comme par exemple si vous vous servez encore de l\'application. Nous ne collectons pas d\'informations personnelles telles que les noms des réseaux.
23 | Points d\'accès connus
24 | Retirer les points d\'accès de la liste de confiance ou de celle des points d\'accès bloqués (avancé)
25 | Êtes-vous sûr de vouloir retirer le point d\'accès \"%1$s\" de cette liste\u00a0?
26 | Retirer
27 | Location access disabled
28 | Wi-Fi PrivacyPolice might need (limited) location access in order to function correctly. Click here for more info.
29 | Starting with Android version 6.0 (Marshmallow), apps can only view the list of Wi-Fi networks that are in range while location access is enabled. Your mileage may vary (depending on the device you\'re using, this might not be the case), but if you experience problems when using Wi-Fi PrivacyPolice, consider enabling location access. Coarse location access (only using Wi-Fi networks and cell towers, and not your actual GPS chip) should be sufficient.
30 | Open location settings
31 | Show location notice
32 | Remind me via a notification when coarse location access is disabled
33 |
34 |
--------------------------------------------------------------------------------
/privacypolice/src/main/res/values-it/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Wi-Fi Privacy Police
5 | Protezione della privacy
6 | Evita che terze persone possano vedere la lista delle reti Wi-Fi a cui ti sei connesso, abilitandola solo quando le suddette reti sono rilevate
7 | Protezione dei dati
8 | Abilita la connessione agli hotspot solo quando questi dovrebbero essere disponibili (alla prima connessione ad un nuovo hotspot viene richiesta una conferma)
9 | Sei sicuro che la rete "%1$s" dovrebbe essere disponibile in questo momento?
10 | Si
11 | No
12 | \"%1$s\" trovata
13 | Opzioni
14 | Wi-Fi Privacy Police continuerá a proteggerti in background. Puoi chiudere questa finestra e smettere di preoccuparti che i tuoi dati sensibili, presenti nel dispositivo, vengano fatti trapelare.
15 | Pulisci tutti gli hotspots
16 | Clicca qui per rimuovere tutti gli hotspot, fidati e non, dalla tua lista
17 | Sei sicuro di voler rimuovere tutti gli hotspot, fidati e non? Privacy Police ti richiederá nuovamente di tutti questi hotspot nel caso l\'opzione sia stata abilitata
18 | Pulisci
19 | Annulla
20 | Sei sicuro di voler rimuovere tutti gli hotspot per la rete \"%1$s\"?
21 | Permetti statistiche anonime sull\'utilizzo
22 | Abilitando questa opzione aiuterai la ricerca futura, mandando statistiche anonime e periodiche sull\'utilizzo, come per esempio se stai utilizzando l\'app. Non raccogliamo informazioni che possano identificarti, come i nomi delle reti.
23 | Hotspot conosciuti
24 | Rimuovi gli hotspot dalla tua lista degli hotspot abilitati e bloccati (avanzato)
25 | Sei sicuro di voler rimuovere l\'hotspot \"%1$s\"?
26 | Rimuovi
27 | Accesso alla posizione disabilitato
28 | Wi-Fi PrivacyPolice potrebbe aver bisogno di accedere (in maniera limitata) alla tua posizione per poter funzionare correttamente. Clicca qui per maggiori informazioni.
29 | A partire da Android 6.0 (Marshmallow), le applicazioni possono vedere la lista delle reti Wi-Fi sotto portata solo se l\'accesso alla posizione é abilitata. La situazione potrebbe essere diversa (a seconda del dispositivo che stai utilizzando), ma se hai dei problemi nell\'utilizzo di Wi-Fi PrivacyPolice, prova ad abilitare l\'accesso alla posizione. Un accesso sommario alla posizione (alle sole reti Wi-Fi ed alle celle, e non al vero e proprio GPS) dovrebbe essere sufficiente.
30 | Apri le opzioni sulla posizione
31 | Mostra nota sulla posizione
32 | Ricordami tramite una notifica quando l\'accesso alla posizione sommaria é disabilitata
33 |
34 |
--------------------------------------------------------------------------------
/privacypolice/src/main/res/values-nl/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Wi-Fi Privacy Police
4 | Privacy bescherming
5 | Voorkom dat andere mensen je netwerklijst kunnen zien door netwerken enkel te activeren wanneer ze beschikbaar zijn
6 | Data bescherming
7 | Laat enkel verbindingen toe wanneer we zeker zijn dat het netwerk beschikbaar is (er wordt voor elk netwerk één keer gevraagd of het beschikbaar zou moeten zijn op de huidige locatie)
8 | Ben je zeker dat \"%1$s\" hier aanwezig is?
9 | Ja
10 | Nee
11 | \"%1$s\" lijkt beschikbaar
12 | Instellingen
13 | Wi-Fi Privacy Police zal je automatisch beschermen. Je kan dit venster gewoon sluiten.
14 | Vergeet alle gekende hotspots
15 | Klik hier om alle vertrouwde en onvertrouwde hotspots te vergeten
16 | Ben je zeker dat je alle vertrouwde en onvertrouwde hotspots wil vergeten? Dit zal ervoor zorgen dat Privacy Police je voor elke hotspot opnieuw zal vragen of je ermee wil verbinden
17 | Verwijder
18 | Annuleer
19 | Laat anonieme gebruikersstatistieken toe
20 | Laat toe om periodiek anonieme gebruikersstatistieken, zoals frequentie van het gebruik van de applicatie, toe om verder onderzoek te helpen. We verzamelen geen persoonlijke informatie, zoals netwerknamen.
21 | Lijst van hotspots
22 | Verwijder hotspots uit de lijst van vertrouwde en geblokkeerde hotspots (geavanceerd)
23 | Ben je zeker dat je hotspot \"%1$s\" wilt verwijderen?
24 | Verwijder
25 | Ben je zeker dat je alle hotspots voor het netwerk \"%1$s\" wilt verwijderen?
26 | Locatietoegang uitgeschakeld
27 | Wi-Fi PrivacyPolice heeft (beperkte) locatietoegang nodig om correct te functioneren. Klik hier voor meer informatie.
28 | Sinds Android versie 6.0 (Marshmallow) kunnen applicaties enkel de beschikbare Wi-Fi netwerken zijn wanneer locatietoegang is ingeschakeld. Dit verschilt van apparaat tot apparaat, maar indien je problemen ondervindt bij het gebruik van Wi-Fi Privacypolice, overweeg dan om locatietoegang in te schakelen. Beperkte toegang (waarbij enkel Wi-Fi netwerken en zendmasten, en niet de GPS chip gebruikt worden) zou voldoende moeten zijn.
29 | Open locatie instellingen
30 | Laat locatie waarschuwing zien
31 | Herinner me via een notificatie wanneer locatietoegang is uitgeschakeld
32 |
33 |
--------------------------------------------------------------------------------
/privacypolice/src/main/res/values-pt-rPT/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Wi-Fi Privacy Police
5 | Proteção de privacidade
6 | Prevenir que outras pessoas vejam a sua lista de redes ativando-as apenas quando estiverem na proximidade
7 | Proteção de dados
8 | Permitir apenas ligações a pontos de acesso quando estes deveriam estar disponíveis (ao perguntar-lhe na primeira vez que ligar a um novo ponto de acesso)
9 | Tem a certeza que a rede "%1$s" deveria estar disponível agora?
10 | Sim
11 | Não
12 | Encontrado \"%1$s\"
13 | Definições
14 | O Wi-Fi Privacy Police continuará a proteção em segundo plano. Pode fechar esta janela e não se preocupar com as fugas de informação privada e sensível do seu dispositivo.
15 | Limpar todos os pontos de acesso
16 | Clique aqui para remover todos os pontos de acesso confiáveis e não confiáveis da sua lista
17 | Pretende mesmo remover todos os pontos de acesso confiáveis e não confiáveis? Após isto o Privacy Police perguntar-lhe-á em cada ponto de acesso se este deve ou não ser permitido
18 | Limpar
19 | Cancelar
20 | Pretende mesmo remover todos os pontos de acesso da rede \"%1$s\"?
21 | Permitir estatísticas de uso anónimas
22 | Permitir isto ajuda a investigação ao enviar periodicamente estatísticas de uso anónimas, como por exemplo, se ainda continua a usar a aplicação. Não recolhemos nenhuma informação pessoal identificativa, tal como nomes de redes.
23 | Pontos de acesso conhecidos
24 | Remover pontos de acesso da sua lista de pontos de acesso confiáveis e bloqueados (avançado)
25 | Pretende mesmo remover o ponto de acesso \"%1$s\"?
26 | Remover
27 | Acesso à localização desativado
28 | O Wi-Fi Privacy Police poderá precisar de acesso (limitado) à localização para poder funcionar corretamente. Clique aqui para mais informações.
29 | A começar pela versão 6.0 do Android (Marshmallow), as aplicações apenas podem ver a lista de redes Wi-Fi que estão na proximidade se o acesso à localização for concedido. Pode variar consoante o caso (dependendo do dispositivo que estiver a usar, ou outro motivo), mas se experiênciar problemas ao usar o Wi-Fi Privacy Police, considere ativar o acesso à localização. Acesso à localização aproximada (usando apenas redes Wi-Fi e torres de telecomunicações e não propriamente o seu chip GPS) deverá ser suficiente.
30 | Abrir definições de localização
31 | Mostrar aviso de localização
32 | Lembrar-me com uma notificação quando a localização aproximada estiver desativada
33 |
34 |
--------------------------------------------------------------------------------
/privacypolice/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/privacypolice/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/privacypolice/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
7 |
--------------------------------------------------------------------------------
/privacypolice/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Wi-Fi Privacy Police
5 | Privacy protection
6 | Prevent other people from viewing your list of networks by only enabling them when they are in range
7 | Data protection
8 | Only allow connections to hotspots when they should be available (by asking you the first time you connect to a new hotspot)
9 | Are you sure network "%1$s" should be available right now?
10 | Yes
11 | No
12 | \"%1$s\" encountered
13 | Settings
14 | Wi-Fi Privacy Police will keep protecting you in the background. You can close this window and stop worrying about privacy sensitive information leaking from your device.
15 | Clear all hotspots
16 | Click here to remove all trusted and untrusted hotspots from your list
17 | Are you sure you want to remove all trusted and untrusted hotspots? This will result in Privacy Police asking you for every hotspot whether it should be allowed
18 | Clear
19 | Cancel
20 | Are you sure you want to remove all hotspots for the network \"%1$s\"?
21 | Allow anonymous usage statistics
22 | Enabling this helps further research by periodically sending anonymous usage data, such as whether you are still using the app. We do not collect any personally identifiable information, such as network names.
23 | Known hotspots
24 | Remove hotspots from your list of trusted and blocked hotspots (advanced)
25 | Are you sure you want to remove hotspot \"%1$s\"?
26 | Remove
27 | Location access disabled
28 | Wi-Fi PrivacyPolice might need (limited) location access in order to function correctly. Click here for more info.
29 | Starting with Android version 6.0 (Marshmallow), apps can only view the list of Wi-Fi networks that are in range while location access is enabled. Your mileage may vary (depending on the device you\'re using, this might not be the case), but if you experience problems when using Wi-Fi PrivacyPolice, consider enabling location access. Coarse location access (only using Wi-Fi networks and cell towers, and not your actual GPS chip) should be sufficient.
30 | Open location settings
31 | Show location notice
32 | Remind me via a notification when coarse location access is disabled
33 |
34 |
--------------------------------------------------------------------------------
/privacypolice/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/privacypolice/src/main/res/xml/preferences.xml:
--------------------------------------------------------------------------------
1 |
4 |
11 |
18 |
25 |
26 |
32 |
33 |
--------------------------------------------------------------------------------
/privacypolice/src/main/res/xml/preferences_location.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
12 |
--------------------------------------------------------------------------------
/privacypolice/src/main/res/xml/tracker.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 300
4 |
5 |
6 | true
7 |
8 |
9 |
10 | PrivacyPolice MainActivity
11 |
12 |
13 | PrivacyPolice AskPermissionActivity
14 |
15 |
16 |
17 | UA-59173049-2
18 |
19 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':privacypolice'
2 |
--------------------------------------------------------------------------------