├── .classpath
├── .gitattributes
├── .gitignore
├── .project
├── .settings
├── org.eclipse.jdt.core.prefs
└── org.eclipse.jdt.ui.prefs
├── AndroidManifest.xml
├── LICENSE
├── README.md
├── assets
└── xposed_init
├── lib
└── XposedBridgeApi-52.jar
├── project.properties
├── res
├── drawable-hdpi
│ ├── ic_launcher.png
│ └── ic_menu_save.png
├── drawable-ldpi
│ ├── ic_launcher.png
│ └── ic_menu_save.png
├── drawable-mdpi
│ ├── ic_launcher.png
│ └── ic_menu_save.png
├── drawable-xhdpi
│ ├── ic_launcher.png
│ └── ic_menu_save.png
├── layout
│ ├── about.xml
│ ├── app_list_item.xml
│ ├── app_permission_item.xml
│ ├── app_settings.xml
│ ├── filter_dialog.xml
│ ├── filter_item.xml
│ ├── main.xml
│ ├── permission_search.xml
│ ├── permissions_dialog.xml
│ └── recent_item.xml
├── menu
│ ├── menu_app.xml
│ └── menu_main.xml
├── values-cs
│ └── strings.xml
├── values-de
│ └── strings.xml
├── values-el
│ └── strings.xml
├── values-es
│ └── strings.xml
├── values-fr
│ └── strings.xml
├── values-hu
│ └── strings.xml
├── values-ja
│ └── strings.xml
├── values-ko
│ └── strings.xml
├── values-pt-rBR
│ └── strings.xml
├── values-ru
│ └── strings.xml
├── values-sk
│ └── strings.xml
├── values-zh-rCN
│ └── strings.xml
├── values-zh-rTW
│ └── strings.xml
└── values
│ ├── attrs.xml
│ ├── donottranslate.xml
│ └── strings.xml
├── screenshots
├── app_menu.png
├── app_permissions.png
├── app_resources.png
├── app_settings.png
├── apps_list.png
├── filter.png
└── search_permissions.png
└── src
└── de
└── robv
└── android
└── xposed
└── mods
└── appsettings
├── Common.java
├── FilterItemComponent.java
├── XposedMod.java
├── XposedModActivity.java
├── hooks
├── Activities.java
└── PackagePermissions.java
└── settings
├── ApplicationSettings.java
├── LocaleList.java
├── PermissionSettings.java
└── PermissionsListAdapter.java
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.java text
2 | *.xml text
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /.idea
2 | /bin
3 | /gen
4 | /out
5 | *.apk
6 | *.iml
7 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | XposedAppSettings
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.ui.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | formatter_profile=_Xposed
3 | formatter_settings_version=12
4 |
--------------------------------------------------------------------------------
/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
19 |
23 |
24 |
25 |
26 |
27 |
28 |
33 |
34 |
35 |
38 |
41 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | AppSettings
2 | ===========
3 |
4 | A modification using the Xposed framework to change settings like density per app.
5 |
6 |
7 |
8 | License
9 | -------
10 |
11 | Copyright 2014 rovo89, Tungstwenty
12 |
13 | Licensed under the Apache License, Version 2.0 (the "License");
14 | you may not use this file except in compliance with the License.
15 | You may obtain a copy of the License at
16 |
17 | http://www.apache.org/licenses/LICENSE-2.0
18 |
19 | Unless required by applicable law or agreed to in writing, software
20 | distributed under the License is distributed on an "AS IS" BASIS,
21 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 | See the License for the specific language governing permissions and
23 | limitations under the License.
24 |
--------------------------------------------------------------------------------
/assets/xposed_init:
--------------------------------------------------------------------------------
1 | de.robv.android.xposed.mods.appsettings.XposedMod
2 |
--------------------------------------------------------------------------------
/lib/XposedBridgeApi-52.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rovo89/XposedAppSettings/09ab9ee3b47260d071873d9b3b0f0304dd3c8fd4/lib/XposedBridgeApi-52.jar
--------------------------------------------------------------------------------
/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}\tools\proguard\proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-19
15 |
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rovo89/XposedAppSettings/09ab9ee3b47260d071873d9b3b0f0304dd3c8fd4/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_menu_save.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rovo89/XposedAppSettings/09ab9ee3b47260d071873d9b3b0f0304dd3c8fd4/res/drawable-hdpi/ic_menu_save.png
--------------------------------------------------------------------------------
/res/drawable-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rovo89/XposedAppSettings/09ab9ee3b47260d071873d9b3b0f0304dd3c8fd4/res/drawable-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-ldpi/ic_menu_save.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rovo89/XposedAppSettings/09ab9ee3b47260d071873d9b3b0f0304dd3c8fd4/res/drawable-ldpi/ic_menu_save.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rovo89/XposedAppSettings/09ab9ee3b47260d071873d9b3b0f0304dd3c8fd4/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/ic_menu_save.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rovo89/XposedAppSettings/09ab9ee3b47260d071873d9b3b0f0304dd3c8fd4/res/drawable-mdpi/ic_menu_save.png
--------------------------------------------------------------------------------
/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rovo89/XposedAppSettings/09ab9ee3b47260d071873d9b3b0f0304dd3c8fd4/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-xhdpi/ic_menu_save.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rovo89/XposedAppSettings/09ab9ee3b47260d071873d9b3b0f0304dd3c8fd4/res/drawable-xhdpi/ic_menu_save.png
--------------------------------------------------------------------------------
/res/layout/about.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
19 |
20 |
25 |
26 |
32 |
33 |
39 |
40 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/res/layout/app_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
19 |
20 |
25 |
26 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/res/layout/app_permission_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/res/layout/app_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
18 |
19 |
25 |
26 |
33 |
34 |
35 |
39 |
40 |
44 |
45 |
49 |
50 |
54 |
55 |
56 |
64 |
65 |
66 |
70 |
71 |
72 |
80 |
81 |
82 |
87 |
88 |
89 |
93 |
94 |
98 |
99 |
100 |
105 |
106 |
111 |
112 |
113 |
118 |
119 |
123 |
124 |
129 |
130 |
135 |
136 |
137 |
141 |
142 |
147 |
148 |
153 |
154 |
159 |
160 |
161 |
165 |
166 |
171 |
172 |
178 |
179 |
180 |
184 |
185 |
190 |
191 |
196 |
197 |
198 |
202 |
203 |
208 |
209 |
214 |
215 |
216 |
220 |
221 |
226 |
227 |
233 |
234 |
235 |
239 |
240 |
245 |
246 |
251 |
252 |
253 |
258 |
259 |
264 |
265 |
270 |
271 |
272 |
275 |
276 |
281 |
282 |
287 |
288 |
289 |
292 |
293 |
298 |
299 |
304 |
305 |
306 |
311 |
312 |
313 |
314 |
315 |
--------------------------------------------------------------------------------
/res/layout/filter_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
19 |
20 |
27 |
28 |
35 |
36 |
43 |
44 |
48 |
49 |
50 |
51 |
52 |
53 |
60 |
61 |
67 |
68 |
74 |
75 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/res/layout/filter_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
15 |
20 |
21 |
28 |
29 |
35 |
36 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/res/layout/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
12 |
13 |
20 |
21 |
31 |
32 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/res/layout/permission_search.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/res/layout/permissions_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
16 |
17 |
25 |
26 |
33 |
34 |
40 |
41 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/res/layout/recent_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
18 |
19 |
24 |
25 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/res/menu/menu_app.xml:
--------------------------------------------------------------------------------
1 |
2 |
25 |
--------------------------------------------------------------------------------
/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
27 |
--------------------------------------------------------------------------------
/res/values-cs/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Možnost nastavit několik základních nastavení pro jednotlivé aplikace:
4 | DPI, velikost písma, jazyk, načítání zdrojů, zobrazení na celou obrazovku, skrýt záhlaví, ponechat obrazovku zapnutou, zobrazit nad uzamykací obrazovkou, ponechat v paměti, no fullscreen IME, orientace, neústupné oznámení, zrušit povolení
5 |
6 |
7 |
8 | Načítám aplikace, prosím čekejte
9 | Jméno nebo balíček
10 | Xposed modul od
11 | rovo89 a Tungstwenty.
12 | \nMůžete použít toto vlákno pro otázky a návrhy.
13 | Tento modul vám umožní změnit několik základních nastavení pro jednotlivé aplikace bez nutnosti upravovat APK:
14 | \n- DPI
15 | \n- velikost písma
16 | \n- falešná velikost obrazovky pro načítání zdrojů
17 | \n- jazyk
18 | \n- režim na celou obrazovku
19 | \n- skrýt záhlaví
20 | \n- nevypínat obrazovku, když je aplikace aktivní
21 | \n- zobrazit aplikaci nad uzamykací obrazovkou
22 | \n- ponechat v paměti
23 | \n- disable fullscreen keyboard input
24 | \n- vynutit orientaci (na výšku, na šírku, autom.)
25 | \n- neústupné oznámení (opakovat zvuk)
26 | \n- zrušit velké (rozšířené) oznámení
27 | \n- zakázat oznámení
28 | Verze: %s
29 | Překladatel: %s
30 | Poznámka: I když nastavení můžou být změněné, vliv na aplikace budou mýt jen když bude Xposed framework nainstalovaný a tento modul bude povolený!
31 |
32 |
33 |
34 | Exportovat
35 | Importovat
36 | O aplikaci
37 |
38 |
39 | Soubor neexistuje: %s
40 | Nahradit všechny nastavení nastaveními, které se chystáte importovat?
41 | Nastavení byli exportované do souboru: %s
42 | Export selhal: %s
43 | Import selhal: %s
44 | Neplatný nebo prázdný soubor na import: %s
45 | Import byl úspěšný; nastavení bylo nahrazeno
46 |
47 |
48 |
49 | Uložit
50 | Spustit
51 | Nastavení
52 | Obchod Play
53 |
54 |
55 |
56 | Nastavení
57 | DPI
58 | Zvětšení písma
59 | Zdroje
60 | Rozlišení obrazovky
61 | extra rozl.
62 | Jazyk
63 | Na celou obrazovku
64 | Bez záhlaví
65 | Ponechat zap. obrazovku
66 | Zobrazit při uzamknuté obrazovce
67 | Ponechat v paměti
68 | No Fullscreen IME
69 | Orientace
70 | Neústupné oznámení
71 | Nezobrazovat velké oznámení
72 | Povolení
73 |
74 | (předvolené)
75 |
76 | Vynutit
77 | Zabránit
78 | Celá obrazovka
79 |
80 | Předvolené otočení
81 | Vždy na výšku
82 | Vždy na šírku
83 | Vynutit automatické otáčaní
84 |
85 |
86 | Zdroje
87 | Nenašli jsme žádné zdroje
88 | Chyba při načítaní obsahu APK
89 |
90 |
91 | Povolení
92 | Zakázat povolení
93 | UPOZORNENIE: Sdílený balíček!
94 | Jméno nebo popis
95 | (není dostupný žiadny popis)
96 | Vyberte povolení pro filtrování, nebo Zrušte pro zobrazení všech
97 |
98 |
99 | Upozornení
100 | Neuložili jste nastavení.
101 | Opravdu se chcete vrátit a zrušit změny?
102 | Použít nastavení
103 | Chcete ukončit aplikaci, aby po opětovném spuštění použila nové nastavení?
104 |
105 |
106 |
107 | Filtr
108 | Všechny
109 | Přepsané
110 | Nezměnené
111 | Typ
112 | Užívatelské
113 | Systémové
114 | Aktivní nastavení
115 | Aktivní
116 | Neaktivní
117 | Načítané zdroje
118 | Zrušit
119 | Vyčistit
120 | Použít
121 |
122 |
123 | ja_som (Slovenština) korekce pro češtinu WodokCZ
124 |
125 |
--------------------------------------------------------------------------------
/res/values-de/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Möglichkeit einige Einstellungen auf Pro-App-Basis zu setzen:
4 | DPI; Schriftgröße; geladene Resourcen überschreiben; Sprache ändern;
5 | Vollbild; Kein Titel; Bildschirm anbehalten; Über Sperrbildschirm anzeigen;
6 | Im Speicher behalten; keine Eingabeauswahl bei Vollbild; Orientierung; bleibende Benachrichtigungen; keine erweiterten Benachrichtigungen; Berechtigungen bearbeiten
7 |
8 |
9 |
10 | Apps laden, bitte warten
11 | Name oder Paket
12 | Ein Xposed-Module von
13 | rovo89 und Tungstwenty.
14 | \nDu kannst diesen Thread für Fragen und Wünsche benutzen.
15 | Diese Mod erlaubt bestimmte generische Einstellungen auf Pro-App-Basis, ohne die APKs zu editieren:
16 | \n- Auflösung / DPI
17 | \n- Schriftgröße
18 | \n- Gefälschte Bildschirmgröße für das Laden von Resourcen
19 | \n- Locale (Sprache)
20 | \n- Vollbild-Modus
21 | \n- Titelleiste ausblenden
22 | \n- Bildschirm anbehalten
23 | \n- App über Sperrbildschirm anzeigen
24 | \n- Im Speicher behalten
25 | \n- Tastatur-Eingabe im Vollbildmodus deaktivieren
26 | \n- Ausrichtung erzwingen (Portät/Landschaft/automatisch)
27 | \n- dauerhafte Beanchrichtigungen (Ton als Schleife)
28 | \n- Große (erweiterte) Benachrichtigungen deaktivieren
29 | \n- Berechtigungen entziehen
30 | Version: %s
31 | Übersetzer: %s
32 | Anmerkung: Obwohl die Einstellungs-Ansicht auch so genutzt werden kann, werden die Einstellungen nur übernommen, falls das Xposed-Framework installiert ist und dieses Modul aktiviert wurde!
33 |
34 |
35 |
36 | Exportieren
37 | Importieren
38 | Über
39 |
40 |
41 | Datei existiert nicht: %s
42 | Alle Einstellungen mit den zu importierenden ersetzen?
43 | Einstellungen in Datei exportiert: %s
44 | Export fehlgeschlagen: %s
45 | Import fehlgeschlagen: %s
46 | Ungültige oder leere Datei zum importieren: %s
47 | Import vollständig, Einstellungen überschrieben
48 |
49 |
50 |
51 | Speichern
52 | Starten
53 | Einstellungen
54 | Play Store
55 |
56 |
57 |
58 | Einstellungen
59 | DPI
60 | Schriftgröße
61 | Res.zeigen
62 | Bildschirm (dp)
63 | extragroße Res.
64 | Sprache
65 | Vollbild
66 | Kein Titel
67 | Bildschirm anlassen
68 | Anzeigen, wenn gesperrt
69 | Permanent
70 | Keine Vollbild-Eingabe
71 | Ausrichtung
72 | Dauerhafte Beanchrichtigung
73 | Keine großen Benachrichtigungen
74 | Berechtigungen
75 |
76 | (Standard)
77 |
78 | Erzwingen
79 | Verhinden
80 | Immersive
81 |
82 | Normale Rotation
83 | Immer vertikal
84 | Immer horizontal
85 | Auto-Rotation erzwingen
86 | Immer vertikal (sensor)
87 | Immer horizontal (sensor)
88 | Immer vertikal (umgedreht)
89 | Immer horizontal (umgedreht)
90 | Erzwinge Auto-Rotation (4-Weg)
91 |
92 |
93 | Resourcen
94 | Keine Resourcen gefunden
95 | APK-Inhalte konnten nicht geladen werden
96 |
97 |
98 | Berechtigungen
99 | Berechtigungen entziehen
100 | WARNUNG: Gemeinsam genutztes Paket!
101 | Name oder Beschreibung
102 | ( keine Beschreibung gefunden )
103 | Wähle Berechtigung, um nach ihr zu filtern, oder Abbrechen, um alle zu zeigen
104 |
105 |
106 | Warnung
107 | Du hast die Konfiguration nicht gespeichert. Möchtest du wirklich zurückgehen und die Änderungen rückgängig machen?
108 | Einstellungen anwenden
109 | Anwendung zusätzlich schließen, damit die neuen Einstellungen beim nächsten Start angewendet werden?
110 |
111 |
112 |
113 | Filter
114 | Alle
115 | Überschrieben
116 | Unverändert
117 | Typ
118 | Nutzer
119 | System
120 | Einstellungen aktiv
121 | Aktiv
122 | Nicht aktiv
123 | Resourcen werden geladen
124 | Abbrechen
125 | Löschen
126 | Anwenden
127 |
128 |
129 | Sanguinus, Paul27
130 |
131 |
--------------------------------------------------------------------------------
/res/values-el/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Δυνατότητα να ρυθμιστούν γενικές ρυθμίσεις ανά εφαρμογή:
4 | DPI, Μέγεθος γραμματοσειράς, Αλλαγή φορτωμένων πώρων, Γλώσσα, Πλήρης οθόνη, Απόκρυψη τίτλου, Διατήρηση αναμμένης οθόνης, Εμφάνιση πάνω από την οθόνη κλειδώματος, Μόνιμο στην μνήμη, No fullscreen IME, Προσανατολισμός οθόνης, Επίμονες ειδοποιήσεις, Όχι μεγάλες ειδοποιήσεις, Άρνηση αδειών
5 |
6 |
7 |
8 | Φόρτωση εφαρμογών, παρακαλώ περιμένετε...
9 | όνομα ή όνομα πακέτου
10 | Ένα Xposed module από
11 | rovo89 και Tungstwenty.
12 | \nΜπορείτε να χρησιμοποιήσετε αυτό το θέμα για ερωτήσεις ή προτάσεις.
13 | Αυτό το mod επιτρέπει σε μερικές γενικές ρυθμίσεις να αλλάξουν ανά εφαρμογή, χωρίς να χρειάζεται να επεξεργαστήτε αρχεία APK:
14 | \n- πυκνότητα οθόνης / dpi
15 | \n- μέγεθος γραμματοσειράς
16 | \n- ψεύτικο μέγεθος οθόνης για φόρτωση πώρων
17 | \n- τοπικότητα (γλώσσα)
18 | \n- λειτουργία πλήρης οθόνης
19 | \n- απόκρυψη μπάρας τίτλου
20 | \n- διατήρηση αναμμένης οθόνης όσο η εφαρμογή είναι ορατή
21 | \n- εμφάνιση εφαρμογής πάνω από την οθόνη κλειδώματος
22 | \n- μόνιμο στη μνήμη
23 | \n- disable fullscreen keyboard input
24 | \n- προσανατολισμός (portrait/landscape/αυτόματο)
25 | \n- επίμονες ειδοποιήσεις (loop the sound)
26 | \n- απενεργοποίηση μεγάλων (επεκταμένων) ειδοποιήσεων
27 | \n- άρνηση αδειών
28 | Έκδοση: %s
29 | Μεταφραστής: %s
30 | Σημείωση: Αν και οι ρυθμίσεις μπορούν να χρησιμοποιηθούν όπως είναι,
31 | οι εφαρμογές θα επηρεαστούν μόνο αν το Xposed framework είναι εγκατεστημένο και αν αυτό το module
32 | είναι ενεργοποιημένο στις ρυθμίσεις του!
33 |
34 |
35 |
36 | Εξαγωγή
37 | Εισαγωγή
38 | Σχετικά
39 |
40 |
41 | Το αρχείο δεν υπάρχει: %s
42 | Αντικατάσταση όλων των ρυθμίσεων με αυτές που θα εισαχθούν;
43 | Οι ρυθμίσεις εξάχθηκαν στο αρχείο: %s
44 | Εξαγωγή απέτυχε: %s
45 | Εισαγωγή απέτυχε: %s
46 | Άκυρο ή άδειο αρχείο για εισαγωγή: %s
47 | Εισαγωγή επιτυχής. Οι ρυθμίσεις αντικαταστάθηκαν.
48 |
49 |
50 |
51 | Αποθήκευση
52 | Τρέξιμο
53 | Ρυθμίσεις
54 | Play Store
55 |
56 |
57 |
58 | Ρυθμίσεις
59 | DPI
60 | Μέγεθος γραμματοσειράς
61 | Κατάλογος των πόρων
62 | Οθόνη (dp)
63 | xlarge πόροι
64 | Τοπικότητα
65 | Πλήρης οθόνη
66 | Χωρίς τίτλο
67 | Διατήρηση αναμμένης οθόνης
68 | Εμφάνιση πάνω από την οθόνη κλειδώματος
69 | Μόνιμο
70 | Όχι πληρης οθόνη IME
71 | Προσανατολισμός
72 | Επίμονες ειδοποιήσεις
73 | Όχι μεγάλες ειδοποιήσεις
74 | Άδειες
75 |
76 | (προεπιλογή)
77 |
78 | Επιβολή
79 | Αποτροπή
80 | Μοναδικό
81 |
82 | Κανονική περιστροφή
83 | Πάντα portrait
84 | Πάντα landscape
85 | Επιβολή auto-rotation
86 |
87 |
88 | Πόροι
89 | Δεν βρέθηκαν πόροι
90 | Αποτυχία φόρτωσης πόρων του APK
91 |
92 |
93 | Άδειες
94 | Άρνηση αδειών
95 | ΠΡΟΣΟΧΉ: Διαμοιραζόμενο πακέτο!
96 | όνομα ή περιγραφή
97 | ( δεν υπάρχει περιγραφή διαθέσιμη )
98 | Επιλέξτε μια άδεια για φίλτρο, ή πατήστε Άκυρο για να εμφανιστούν όλα
99 |
100 |
101 | Προσοχή
102 | Δεν αποθηκεύσατε τις ρυθμίσεις.
103 | Αλήθεια θέλετε να πάτε πίσω και να ακυρώσετε τις αλλαγές;
104 | Επιβολή ρυθμίσεων
105 | Επίσης τερματισμός εφαρμογής για να χρησιμοποιεί τις καινούριες ρυθμίσεις όταν ξανανοίξει;
106 |
107 |
108 |
109 | Φιλτράρισμα
110 | Όλα
111 | Αλλαγμένο
112 | Μη αλλαγμένο
113 | Τύπος
114 | Χρήστης
115 | Σύστημα
116 | Ρυθμίσεις ενεργές
117 | Ενεργό
118 | Μη ενεργό
119 | Φόρτωση πόρων
120 | Άκυρο
121 | Διαγραφή
122 | Επιβολή
123 |
124 |
125 | Vagelis1608
126 |
127 |
--------------------------------------------------------------------------------
/res/values-es/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Ajustar configuraciones genéricas por aplicación:
4 | DPI; sobreescribir recursos cargados; lenguaje; pantalla completa;
5 | residente en memoria; orientación; revocar permisos; …
6 |
7 |
8 |
9 | Cargando aplicaciones, por favor espere...
10 | nombre o paquete
11 | Un módulo Xposed creado por
12 | rovo89 y Tungstwenty.
13 | \nPuede ingresar a este hilo para realizar preguntas o sugerencias.
14 | Este módulo permite cambiar ciertos ajustes genéricos para cada aplicación sin la necesidad de editar APKs:
15 | \n- densidad / dpi
16 | \n- escala de la fuente
17 | \n- simular tamaño de pantalla para cargar recursos
18 | \n- lenguaje
19 | \n- modo a pantalla completa
20 | \n- ocultar la barra de título
21 | \n- mantener la pantalla encendida mientras la aplicación sea visible
22 | \n- mostrar aplicación por encima de la pantalla de bloque
23 | \n- mantener residente en memoria
24 | \n- desactivar teclado a pantalla completa
25 | \n- forzar orientación (retrato/paisaje/auto)
26 | \n- notificaciones insistentes (sonido en bucle)
27 | \n- desactivar notificaciones expandidas
28 | \n- prioridad de notificaciones
29 | \n- excluir aplicaciones de la lista de recientes
30 | \n- silenciar sonidos (en la mayoría de las aplicaciones)
31 | \n- forzar el uso del botón de menú heredado (navbar)
32 | \n- revocar permisos
33 | Versión: %s
34 | Traductor: %s
35 | Nota: Aunque los paneles de configuración pueden ser usados como están, solo tendrán efecto sobre las aplicaciones si el marco Xposed se encuentra instalado y si éste módulo se encuentra activo en su configuración.
36 |
37 |
38 |
39 | Exportar
40 | Importar
41 | Acerca de...
42 |
43 |
44 | Archivo no existe: %s
45 | ¿Reemplazar toda la configuración con los valores a punto de ser importados?
46 | Configuración exportada al archivo: %s
47 | Falló la exportación: %s
48 | Falló la importación: %s
49 | Archivo a importar no válido o vacío: %s
50 | Importación exitosa; valores reemplazados
51 |
52 |
53 |
54 | Guardar
55 | Ejecutar
56 | Ajustes
57 | Play Store
58 |
59 |
60 |
61 | Ajustes
62 | DPI
63 | Escala de fuente
64 | Lista res.
65 | Pantalla (dp)
66 | Res. xlarge
67 | Aplicar resolución a widgets
68 | Lenguaje
69 | Pantalla completa
70 | Sin título
71 | Mantener pantalla encendida
72 | Mostrar en bloqueo
73 | Residente
74 | Sin teclado pant. completa
75 | Orientación
76 | Notificaciones insistentes
77 | Sin notificaciones expandidas
78 | Prioridad de notificación
79 | Silenciar sonidos
80 | Botón de menú heredado
81 | Permisos
82 | Mostrar en recientes
83 |
84 | (predeterminado)
85 |
86 | Forzar
87 | Prevenir
88 | Inmersivo
89 |
90 | Rotación normal
91 | Siempre retrato
92 | Siempre paisaje
93 | Forzar rotación automática
94 | Siempre retrato (sensor)
95 | Siempre paisaje (sensor)
96 | Siempre retrato (inverso)
97 | Siempre paisaje (inverso)
98 | Forzar rotación automática (4 caras)
99 |
100 | Máx
101 | Alto
102 | Normal
103 | Bajo
104 | Mín
105 |
106 |
107 | Recursos
108 | No se encontraron recursos
109 | Fallo al cargar contenido de APK
110 |
111 |
112 | Permisos
113 | Revocar permisos
114 | ATENCIÓN: ¡Paquete compartido!
115 | nombre o descripción
116 | ( no tiene descripción )
117 | Seleccione los permisos por los que filtrar o presione Cancelar para mostrar todos
118 |
119 |
120 | Atención
121 | No ha guardado los ajustes.
122 | ¿Desea realmente volver y descartar los cambios?
123 | Aplicar ajustes
124 | ¿También terminar aplicación para que cuando sea ejecutada nuevamente utilice los nuevos ajustes?
125 |
126 |
127 |
128 | Filtro
129 | Todo
130 | Sobreescrito
131 | Sin cambios
132 | Tipo
133 | Usuario
134 | Sistema
135 | Ajustes activos
136 | Activo
137 | No activo
138 | Carga de recursos
139 | Cancelar
140 | Limpiar
141 | Aplicar
142 |
143 |
144 | José Vera (J_M_V_S @xda)
145 |
146 |
--------------------------------------------------------------------------------
/res/values-fr/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Possibilité de modifier plusieurs points de configuration générale pour des applis individuels
4 | DPI; Taille des polices; Remplacement des ressouces; Locale;
5 | Plein écran; Sans titre; Garder l\'écran allumé; Montrer au dessus de l\'écran de verrouillage;
6 | Garder résident en mémoire; Pas de plein écran IME; Orientation; Notifications persistentes; Pas de notifications agrandies; Refuser Permissions
7 |
8 |
9 |
10 | Chargement des applis, attendez s.v.p.
11 | nom ou packet
12 | Un module Xposed écrit par
13 | rovo89 et Tungstwenty.
14 | \nVous pouvez utiliser ce forum pour vos questions ou suggestions.
15 | Ce module permet de modifier certains points de configuration général pour des applis individuels, sans modification de fichier APK:
16 | \n- densité / dpi
17 | \n- taille des polices
18 | \n- taille d\'écran faux pour le chargement des ressources
19 | \n- locale (langage)
20 | \n- mode plein écran
21 | \n- cacher la barre de titre
22 | \n- garder l\'écran allumé quand l\'appli est visible
23 | \n- montrer au-dessus de l\'écran de verrouillage
24 | \n- garder résident en mémoire
25 | \n- empêcher le clavier de prendre tout l\'écran
26 | \n- forcer l\'orientation (portrait/paysage/auto)
27 | \n- notifications persistentes (le son en boucle)
28 | \n- empêcher l\'agrandissement des notifications
29 | \n- refuser permissions
30 | Vérsion: %s
31 | Traducteur: %s
32 | N.B.: Même si les pages de configuration peuvent être utilisées comme tel
33 | elles n\'auront d\'effet que si la structure Xposed est installé et que ce
34 | module est activé dans sa configuration!
35 |
36 |
37 |
38 | Exporter
39 | Importer
40 | A propos
41 |
42 |
43 | Fichier inexistant: %s
44 | Replacer toutes les réglages par ceux qui vont être importés?
45 | Réglages exportés vers: %s
46 | Exportation échouée: %s
47 | Importation échouée: %s
48 | Fichier vide ou non-valide: %s
49 | Importation réussie; réglages replacés
50 |
51 |
52 |
53 | Enregistrer
54 | Lancer
55 | Paramètres
56 | Play Store
57 |
58 |
59 |
60 | Paramètres
61 | DPI
62 | Taille polices
63 | Liste res.
64 | Ecran (dp)
65 | t.grand rés.
66 | Locale
67 | Plein écran
68 | Sans titre
69 | Garder allumé
70 | Montrer qd vérrouillé
71 | Résident
72 | Orientation
73 | Notifs persistentes
74 | Pas de gds notifs
75 | Permissions
76 |
77 | (defaut)
78 |
79 | Forcer
80 | Empêcher
81 | Immersive
82 |
83 | Rotation normale
84 | Toujours portrait
85 | Toujours paysage
86 | Forcer auto-rotation
87 |
88 |
89 | Ressources
90 | Aucunes ressources trouvées
91 | La lecture du contenu de l\'APK échoué
92 |
93 |
94 | Permissions
95 | Refuser Permissions
96 | ATTENTION: Packet partagé!
97 | nom ou description
98 | ( aucune description fournie )
99 | Choisir filtre de permission, ou Annuler pour tout voir
100 |
101 |
102 | Attention
103 | Vous n\'avez pas sauvegardé la configuration.
104 | Voulez-vous vraiment abandonner les modifs?
105 | Appliquer paramètres
106 | Voulez-vous aussi tuer l\'appli pour qu\'une fois relancé il utilise les nouveaux paramètres?
107 |
108 |
109 |
110 | Filtrer
111 | Tout
112 | Modifié
113 | D\'origine
114 | Type
115 | Utilisateur
116 | Système
117 | Paramètres actifs
118 | Actif
119 | Inactif
120 | Chargement des ressources
121 | Annuler
122 | Vider
123 | Appliquer
124 |
125 |
126 | jpeg729
127 |
128 |
--------------------------------------------------------------------------------
/res/values-hu/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Megváltoztathat néhány általános konfigurációt egy-egy alklamazásban: DPI, Betűméret, Erőforrások felülbirálása, Nyelv, Teljes képernyő, Címsor rejtése, Bekapcsolva tartja a képernyőt, Tájolás, Kitartó és kis értesítések ; Engedélyek visszavonása …
4 |
5 |
6 |
7 | Alkalmazások betöltése, kérem várjon...
8 | Név vagy csomag
9 | Ez egy Xposed mudul
10 | rovo89 és Tungstwenty től.
11 | \nHasználhatja ezt a témát ha kérdése, vagy javaslata van.
12 | "Ez a modul lehetővé teszi bizonyos általános konfigurációk megváltoztatását egy-egy alkalmazáson, anélkül, hogy szerkeszteni kellene az APK-t:
13 | \n- sűrűség / dpi
14 | \n- betűméret
15 | \n- hamis képméret betöltéskor
16 | \n- hely (nyelv)
17 | \n- teljes képernyős mód
18 | \n- címsor elrejtése
19 | \n- folyamatos képernyőkép, amíg az alkalmazást használja
20 | \n- megjeleniti az alklamazást zárképernyőn feloldáskor
21 | \n- memóriában tartás
22 | \n- tiltja a teljes képernyős billentyűzetet
23 | \n- tájolás (álló / fekvő / auto)
24 | \n- folyamatos értesítések (folyamatos hang)
25 | \n- tiltja a nagy (bővíthető) értesítéseket
26 | \n- értesítések prioritása
27 | \n- kizárja az alkalmazást a Legutóbbiak menüből
28 | \n- néma hang (nem fog működni néhány alkalmazásnál)
29 | \n- kényszeríti a régi (Navigációs sáv) menü gombot
30 | \n- engedélyek visszavonása
31 | Verzió: %s
32 | Forditó: %s
33 | Megjegyzés:Az alkalmazás csak akkor befolyásolja az alkalmazásokat, ha az Xposed keretrendszer telepítve van, és ha ez a modul engedélyezve van a keretrendszerben!
34 |
35 |
36 |
37 | Exportálás
38 | Importálás
39 | Névjegy
40 |
41 |
42 | A fájl nem létezik: %s
43 | Kicseréli az összes beállitást, biztos importálja?
44 | Beállítások exportálása fájlba: %s
45 | Exportálás sikertelen: %s
46 | Importálás sikertelen: %s
47 | Érvénytelen, vagy üres fájlt akar importálni: %s
48 | Importálása sikeres; beállítások lecserélve
49 |
50 |
51 |
52 | Mentés
53 | Indítás
54 | Beállítások
55 | Play Store
56 |
57 |
58 |
59 | Beállítások
60 | DPI
61 | Betűméret
62 | Erőf.lista
63 | Képernyő (dp)
64 | xlarge res.
65 | Alkalmazza widgeteken
66 | Hely
67 | Teljes képernyő
68 | Címsor rejtése
69 | Folyamatos képernyő
70 | Megjeleniti lezárt állapotban
71 | Tartozkodó
72 | Nincs teljes képernyős billentyűzet
73 | Tájolás
74 | Folyamatos értesítések
75 | Nem Nagy értesítések
76 | Értesítések prioritása
77 | Néma hang
78 | Régi Menü gomb
79 | Engedélyek
80 | Legutóbbiakban megjelenítés
81 |
82 | ((Alapértelmezett)
83 |
84 | Kényszeritett
85 | Megakadályozva
86 | Magával ragadó mód
87 |
88 | Normál forgatás
89 | Mindig álló
90 | Mindig fekvő
91 | Automatikus forgatás
92 | Mindig álló (érzékelő)
93 | Mindig fekvő (érzékelő)
94 | Mindig álló (fordított)
95 | Mindig fekvő (fordított)
96 | Kényszeritett automatikus elforgatás
97 |
98 | Max
99 | Magas
100 | Normál
101 | Alacsony
102 | Min
103 |
104 |
105 | Erőforrás
106 | Források nem találhatóak
107 | Nem sikerült betölteni az APK tartalmat
108 |
109 |
110 | Engedélyek
111 | Engedélyek visszavonása
112 | FIGYELEM: Megosztott csomag!
113 | Neve vagy leírása
114 | ( Nincs ilyen leírás )
115 | Válassza ki a szűrőt, vagy -Mégse- az összes
116 |
117 |
118 | Figyelmeztetés
119 | Nem mentette el a konfigurációt! Visszalép és törli a változásokat?
120 | Beállítások alkalmazása
121 | Kilövi az alkalmazásokat, újraindítja, és használja az új beállítások?
122 |
123 |
124 |
125 | Szűrő
126 | Összes
127 | Módositott
128 | Változatlan
129 | Tipus
130 | Felhasználói
131 | Rendszer
132 | Beállítások aktívak
133 | Aktív
134 | Nem aktív
135 | Erőforrás-terhelés
136 | Mégsem
137 | Tisztít
138 | Alkalmaz
139 |
140 |
141 | szunyi77
142 |
143 |
--------------------------------------------------------------------------------
/res/values-ja/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | アプリ毎に様々な設定ができます:
4 | DPI; フォントスケール; 言語;全画面; タイトル非表示; 画面常時点灯; ロック画面上に表示;
5 | 常駐化; 画面の向き; 通知の繰り返し; 権限の拒否など
6 |
7 |
8 |
9 | アプリの読み込み中
10 | 名前かパッケージ名
11 | このXposedモジュールはrovo89とTungstwentyにより制作されました。
12 | \nこのスレで質問や提案をしてください。
13 | このモジュールではapkを編集することなくアプリ毎に様々な設定ができます:
14 | \n- 画面密度 / dpi
15 | \n- フォントスケール
16 | \n- リソース読み込み変更用の画面サイズ偽装
17 | \n- 言語
18 | \n- 全画面モード
19 | \n- タイトルバーの非表示(アプリが起動しない場合があります)
20 | \n- アプリ起動中に画面を常時点灯する
21 | \n- ロック画面上にアプリを表示する
22 | \n- メモリに常駐するようにする
23 | \n- 全画面キーボードの無効化
24 | \n- 画面の向きの強制(縦/横/自動)
25 | \n- 通知の繰り返し(通地音をループ)
26 | \n- 大きな(拡大された)通知の無効化
27 | \n- 通知の優先度
28 | \n- アプリ履歴からの除外
29 | \n- 無音化(たいていの場合)
30 | \n- ナビバーのメニューボタンを使うようにする
31 | \n- 権限の拒否
32 | バージョン: %s
33 | 翻訳: %s
34 | 注意:Xposedフレームワークがインストールされていてこのモジュールが有効化されているときのみ設定が反映されます!
35 |
36 |
37 |
38 | 保存
39 | 読み込み
40 | 情報
41 |
42 |
43 | ファイルがありません: %s
44 | 読み込んだファイルで全ての設定を置換しますか?
45 | 設定の保存先: %s
46 | 保存失敗: %s
47 | 読み込み失敗: %s
48 | 不正か壊れたファイルです: %s
49 | 読み込み成功; 設定を置換しました。
50 |
51 |
52 |
53 | 保存
54 | 起動
55 | 設定
56 | Playストア
57 |
58 |
59 |
60 | 設定
61 | DPI
62 | フォントスケール
63 | リソースリスト
64 | 画面サイズ(dp)
65 | リソース拡大
66 | リソースをウィジェットに適用
67 | 言語
68 | 全画面
69 | タイトル非表示
70 | 画面常時点灯
71 | ロック画面に表示
72 | 常駐化
73 | 全画面IME無効化
74 | 画面の向き
75 | 通知の繰り返し
76 | 大きい通知無効化
77 | 通知の優先度
78 | 無音化
79 | メニューボタン表示
80 | 権限
81 | アプリ履歴に表示
82 |
83 | (デフォルト)
84 |
85 | 強制
86 | 阻止
87 | 没入モード
88 |
89 | 通常の向き
90 | 常に縦向き
91 | 常に横向き
92 | 自動回転を強制
93 | 常に縦向き(センサー)
94 | 常に横向き(センサー)
95 | 常に縦向き(逆転)
96 | 常に横向き(逆転)
97 | 自動回転を強制(4方向)
98 |
99 | 最高
100 | 高
101 | 中
102 | 低
103 | 最低
104 |
105 |
106 | リソース
107 | リソースなし
108 | APKコンテンツの読み込み失敗
109 |
110 |
111 | 権限
112 | 権限の拒否
113 | 警告: 共有パッケージです!
114 | 名前か説明
115 | (説明無し)
116 | 絞り込む権限を選択します。キャンセルで全て表示します。
117 |
118 |
119 | 警告
120 | 設定をまだ保存していません。
121 | 変更を破棄しますか?
122 | 設定の適用
123 | 設定を反映させるためアプリを終了させますか?
124 |
125 |
126 |
127 | 絞り込み
128 | 全て
129 | 変更済み
130 | 未変更
131 | タイプ
132 | ユーザー
133 | システム
134 | アプリ毎の設定
135 | 有効化済み
136 | 無効
137 | リソース読み込み
138 | キャンセル
139 | 消去
140 | 適用
141 |
142 |
143 | @WedyDQ10
144 |
145 |
--------------------------------------------------------------------------------
/res/values-ko/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 앱마다 다른 설정을 적용시켜줍니다. :
6 | DPI; 글씨 크기; 특정 리소스만 사용; 언어;
7 | 전체 화면 여부; 타이틀바 여부; 화면 계속 켜기 여부; 잠금 화면에서 보이기;
8 | 메모리에 유지; 풀스크린 IME 방지; 화면 방향; 집요한 알림; 알림 확장 가능 여부; 권한 수정
9 |
10 |
11 |
12 | 어플리케이션을 불러오는 중입니다. 잠시만 기다려 주세요!
13 | 이름 혹은 패키지
14 | 이 어플리케이션은 Xposed 모듈 중 하나입니다.
15 | 개발자 : rovo89와 Tungstwenty.
16 | \n이 스레드에서 질문과 의견을 나눌 수 있습니다.
17 | APK 파일을 수정하지 않고 앱마다 각각 다른 설정을 적용시켜줍니다. :
18 | \n- 화면 밀도 / DPI
19 | \n- 글씨 크기
20 | \n- 특정 리소스만 사용하기 위한 가짜 화면 크기
21 | \n- 언어
22 | \n- 전체 화면 모드
23 | \n- 타이틀바 숨기기
24 | \n- 앱 실행 중 화면 꺼짐 방지
25 | \n- 앱이 켜져 있을 때 잠금 화면 바이패스
26 | \n- RAM에 앱 상주
27 | \n- 풀스크린 IME 방지
28 | \n- 강제 화면 방향 (세로 / 가로 / 자동)
29 | \n- 집요한 알림 (알림 소리 반복)
30 | \n- 확장 알림 비활성화
31 | \n- 권한 수정
32 | 버전 : %s
33 | 번역자 : %s
34 | 알림 : 앱 별로 설정할 수 있는 패널은 들어갈 수 있지만,
35 | Xposed 프레임워크가 설치되어 있고 이 모듈을 활성화해야만 설정한 값들이 적용됩니다!
36 |
37 |
38 |
39 | 내보내기
40 | 가져오기
41 | 어플리케이션 정보
42 |
43 |
44 | 파일이 존재하지 않음 : %s
45 | 가져오기를 진행하면 기존 설정은 전부 지워지고 교체될 것입니다. 계속 하시겠습니까?
46 | 설정이 파일로 내보내짐 : %s
47 | 내보내기 실패 : %s
48 | 가져오기 실패 : %s
49 | 파일이 잘못됬거나 비어있음 : %s
50 | 가져오기가 완료되었습니다. 설정이 교체됩니다.
51 |
52 |
53 |
54 | 설정 저장
55 | 어플리케이션 실행
56 | 어플리케이션 설정
57 | Play 스토어
58 |
59 |
60 |
61 | 설정
62 | DPI
63 | 글자 크기
64 | 리소스 목록
65 | 화면 크기 (dp)
66 | xlarge 리소스 사용
67 | 언어
68 | 전체 화면
69 | 타이틀바 숨기기
70 | 화면 꺼짐 방지
71 | 잠금 화면 바이패스 (잠금 화면 생략)
72 | RAM에 상주
73 | 풀스크린 IME 방지
74 | 화면 방향
75 | 집요한 알림
76 | 확장 알림 방지
77 | 권한 수정
78 |
79 | (기본 값 사용)
80 |
81 | 강제
82 | 방지
83 | Immersive 모드
84 |
85 | 기본 회전
86 | 항상 세로 회전
87 | 항상 가로 회전
88 | 강제로 자동 회전
89 |
90 |
91 | 리소스
92 | 리소스를 찾을 수 없음
93 | APK 컨텐츠를 로드할 수 없음
94 |
95 |
96 | 권한
97 | 권한 수정
98 | 경고 : 공유된 패키지입니다!
99 | 이름이나 상세 정보
100 | ( 상세 정보 없음 )
101 | 권한을 선택하여 필터링하거나, 취소를 눌러서 모든 앱이 보여지게 합니다.
102 |
103 |
104 | 경고!
105 | 현재 설정을 저장하지 않으셨습니다.
106 | 정말 뒤로 이동하고 설정을 저장하지 않으시겠습니까?
107 | 설정 저장하기
108 | 선택한 어플리케이션은 종료됩니다. 해당 어플리케이션을 다시 실행하면 새로운 값이 적용됩니다.
109 |
110 |
111 |
112 | 필터링
113 | 모두
114 | 설정됨
115 | 변경되지 않음
116 | 종류
117 | 사용자 앱
118 | 시스템 앱
119 | 설정 활성화 여부
120 | 활성화됨
121 | 비활성화됨
122 | 리소스 불러오는 중
123 | 취소
124 | 비우기
125 | 적용
126 |
127 |
128 | SDKoongchi
129 |
130 |
--------------------------------------------------------------------------------
/res/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Capaz de definir uma série de configurações comuns individualmente por app:
4 | DPI; Escala de fonte; Substituir recursos carregados; Localidade;
5 | Tela cheia; Remover barra de título; Manter tela ligada; Exibir sobre a tela de bloqueio;
6 | Permanecer na memória; No Fullscreen IME; Orientação; Notificações persistentes; Sem notificações grandes; Revogar permissões
7 |
8 |
9 |
10 | Carregando apps, aguarde
11 | nome ou pacote
12 | Um módulo Xposed por
13 | rovo89 e Tungstwenty.
14 | \nVocê pode usar este tópico para questões ou sugestões.
15 | Este mod permite que certas configurações genéricas sejam mudadas individualmente por app, sem a necessidade de editar APKs:
16 | \n- densidade / dpi
17 | \n- escala de fonte
18 | \n- falsificar a densidade da tela para carregamento de recursos
19 | \n- localidade (idioma)
20 | \n- modo tela cheia
21 | \n- ocultar barra de título
22 | \n- manter a tela ligada enquanto o app estiver visível
23 | \n- mostrar o app sobre a lockscreen
24 | \n- permanecer na memória RAM
25 | \n- disable fullscreen keyboard input
26 | \n- forçar orientação (retrato/paisagem/auto)
27 | \n- notificações persistentes (repetir os sons)
28 | \n- desativar notificações expandidas
29 | \n- revogar permissões
30 | Versão: %s
31 | Tradutor: %s
32 | Nota: Apesar das configurações poderem ser ajustadas do jeito que estão,
33 | elas só afetarão os apps se o Xposed framework estiver instalado e este módulo
34 | ativado nas configurações!
35 |
36 |
37 |
38 | Exportar
39 | Importar
40 | Sobre
41 |
42 |
43 | O arquivo %s não existe
44 | Todas as configurações atuais serão substituídas pelas importadas, confirma?
45 | Configurações exportadas para o arquivo: %s
46 | Falha na exportação: %s
47 | Falha na importação: %s
48 | Arquivo de importação vazio ou inválido: %s
49 | Importação concluída; configurações substituídas
50 |
51 |
52 |
53 | Salvar
54 | Abrir
55 | Configurações
56 | Play Store
57 |
58 |
59 |
60 | Configurações
61 | DPI
62 | Escala de fonte
63 | Lista de res.
64 | Tela (dp)
65 | Rec xlarge
66 | Local
67 | Tela cheia
68 | Sem título
69 | Manter tela
70 | Exibir bloqueado
71 | Residente
72 | No Fullscreen IME
73 | Orientação
74 | Notificações insistentes
75 | Sem expansão de notif.
76 | Permissões
77 |
78 | (padrão)
79 |
80 | Forçar
81 | Previnir
82 |
83 | Rotação normal
84 | Sempre retrato
85 | Sempre paisagem
86 | Forçar auto-rotação
87 |
88 |
89 | Recursos
90 | Nenhum recurso encontrado
91 | Falha ao carregar conteúdo do APK
92 |
93 |
94 | Permissões
95 | Revogar Permissões
96 | AVISO: Pacote compartilhado!
97 | nome ou descrição
98 | (nenhuma descrição)
99 | Selecione uma permissão para filtrar, ou Cancelar para exibir todas
100 |
101 |
102 | Aviso
103 | Você não salvou as configurações.
104 | Confirma descartar as mudanças e voltar?
105 | Aplicar configurações
106 | Também matar o aplicativo para que na sua próxima execução ele use as novas configurações?
107 |
108 |
109 |
110 | Filtrar
111 | Todos
112 | Sobreposto
113 | Inalterado
114 | Tipo
115 | Usuário
116 | Sistema
117 | Configurações ativas
118 | Ativo
119 | Não inativo
120 | Carregamento de recursos
121 | Cancelar
122 | Limpar
123 | Aplicar
124 |
125 |
126 | Marcio Andrade (@marciozomb13)
127 |
128 |
--------------------------------------------------------------------------------
/res/values-ru/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Изменение настроек для каждого приложения:
4 | DPI; Замена ресурсов; Язык; Полный экран;
5 | Удержание в памяти; Ориентация; Изменение прав; …
6 |
7 |
8 |
9 | Загрузка приложений, подождите
10 | имя или пакет
11 | Xposed модуль от
12 | rovo89 и Tungstwenty.
13 | \nВы можете открыть этот топик для вопросов и предложений (на английском).
14 | Этот модуль позволяет изменить некоторые общие настройки без необходимости редактирования APK, для каждого приложения:
15 | \n- плотность / dpi
16 | \n- масштаб шрифта
17 | \n- подделка размера экрана
18 | \n- локаль (язык)
19 | \n- полный экран
20 | \n- скрыть заголовок
21 | \n- удержание экрана
22 | \n- удержание приложения поверх локскрина
23 | \n- держать в памяти
24 | \n- отключение клавиатуры в полном экране
25 | \n- форсирование ориентации (портрет/ландшафт/авто)
26 | \n- настойчивые уведомления (повтор звука)
27 | \n- отключение увеличенных уведомлений
28 | \n- приоритет уведомлений
29 | \n- удаление приложения из недавних
30 | \n- отключение звука (большинство приложений)
31 | \n- активация старой кнопки меню
32 | \n- изменение прав
33 | Версия: %s
34 | Перевод: %s
35 | Примечание: хотя панели конфигурации могут быть использованы как есть, они могут влиять на приложения, только если установлен Xposed framework и модуль активирован!
36 |
37 |
38 |
39 | Экспорт
40 | Импорт
41 | О программе
42 |
43 |
44 | Файл не существует: %s
45 | Заменить все настройки импортированными?
46 | Настройки экспортированы в файл: %s
47 | Ошибка экспорта: %s
48 | Ошибка импорта: %s
49 | Неверный или пустой файл для импорта: %s
50 | Импорт успешен; настройки заменены
51 |
52 |
53 |
54 | Сохранить
55 | Запустить
56 | Настройки
57 | Play Store
58 |
59 |
60 |
61 | Настройки
62 | DPI
63 | Масштаб
64 | Ресурсы
65 | Экран (dp)
66 | xlarge рес.
67 | Вкл. для виджета
68 | Язык
69 | Полный экран
70 | Нет титла
71 | Держать экран
72 | Показ. заблок.
73 | Резидент
74 | Нет клав. в полном экране
75 | Ориентация
76 | Настойчивые уведомления
77 | Нет больших уведомлений
78 | Приоритет уведомлений
79 | Без звука
80 | Старая кнопка меню
81 | Права
82 | Показ. в недавних
83 |
84 | (по умолч.)
85 |
86 | Принудительно
87 | Запретить
88 | Погружение
89 |
90 | Нормальное вращение
91 | Всегда портрет
92 | Всегда ландшафт
93 | Всегда вращаться
94 | Всегда портрет (сенсор)
95 | Всегда ландшафт (сенсор)
96 | Всегда портрет (обратно)
97 | Всегда ландшафт (обратно)
98 | Всегда вращаться (все стороны)
99 |
100 | Max
101 | High
102 | Normal
103 | Low
104 | Min
105 |
106 |
107 | Ресурсы
108 | Ресурсы не найдены
109 | Ошибка загрузки ресурсов APK
110 |
111 |
112 | Права
113 | Изменить права
114 | Внимание: Общий пакет!
115 | имя или описание
116 | (описание отсутствует)
117 | Выберите права для фильтрации, или отмените, чтобы показать все
118 |
119 |
120 | Внимание
121 | Вы не сохранили настройки.
122 | Вы действительно хотите отменить их?
123 | Применить
124 | Так же, убить приложение, чтобы оно подхватило новые настройки?
125 |
126 |
127 |
128 | Фильтр
129 | Все
130 | Изменен
131 | Не изменен
132 | Тип
133 | Пользовательские
134 | Системные
135 | Настройки активны
136 | Активны
137 | Не активны
138 | Загрузка ресурсов
139 | Отменить
140 | Очистить
141 | Применить
142 |
143 |
144 | webserfer
145 |
146 |
--------------------------------------------------------------------------------
/res/values-sk/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Možnosť nastaviť niekoľko základných nastavení pre jednotlivé aplikácie:
4 | DPI, veľkosť písma, jazyk, načítať zdroje, zobraziť na celú obrazovku, bez názvu (skryť záhlavie), ponechať obrazovku zapnutú, zobraziť nad uzamykacou obrazovkou, ponechať v pamäti, žiadna celá obrazovka pre IME, orientácia, neústupné oznámenia, zrušiť povolenia
5 |
6 |
7 |
8 | Načítavam aplikácie, prosím čakajte
9 | meno alebo balíček
10 | Xposed modul od
11 | rovo89 a Tungstwenty.
12 | \nMôžete použiť toto vlákno pre otázky a návrhy. Ak nájdete chybu v preklade, nahláste ju prosím tu.
13 | Tento modul vám umožní zmeniť niekoľko základných nastavení pre jednotlivé aplikácie beznutnosti upravovať APK:
14 | \n- dpi
15 | \n- veľkosť písma
16 | \n- fake screen size for resources loading
17 | \n- jazyk
18 | \n- režim na celú obrazovku
19 | \n- skryť záhlavie
20 | \n- nevypínať obrazovku, ak je aplikácia aktívna
21 | \n- zobraziť aplikáciu nad uzamykacou obrazovkou
22 | \n- ponechať v pamäti
23 | \n- zakázať vstup cez klávesnicu na celú obrazovku
24 | \n- vynútiť orientáciu (na výšku, na šírku, autom.)
25 | \n- neústupné oznámenia (opakovať zvuk)
26 | \n- zrušiť veľké (rozšírené) oznámenia
27 | \n- priorita oznámení
28 | \n- vylúčiť aplikáciu z panela nedávnych aplikácií
29 | \n- vypnúť zvuk (pre väčšinu aplikácií)
30 | \n- vynútiť zobrazenie tlačidla Menu v navigačnej lište
31 | \n- zakázať oznámenia
32 | Verzia: %s
33 | Prekladateľ: %s
34 | Poznámka: Aj keď nastavenia môžu byť zmenené, vplyv na aplikácie budú mať iba ak bude Xposed framework nainštalovaný a tento modul bude povolený!
35 |
36 |
37 |
38 | Nedávne apl.
39 | Export
40 | Import
41 | O aplikácii
42 |
43 |
44 | Súbor neexistuje: %s
45 | Nahradiť všetky nastavenia tými, ktoré chcete importovať?
46 | Nastavenia exportované do súboru: %s
47 | Export zlyhal: %s
48 | Import zlyhal: %s
49 | Neplatný, alebo prázdny súbor importu: %s
50 | Import úspešný; nastavenia prepísané
51 |
52 |
53 |
54 | Uložiť
55 | Spustiť
56 | Nastavenia
57 | Obchod Play
58 |
59 |
60 |
61 | Nastavenia
62 | DPI
63 | Zväčšenie písma
64 | Zdroje
65 | Rozlíšenie obrazovky
66 | extra rozl.
67 | Použiť rozl. na miniaplikácie
68 | Jazyk
69 | Na celú obrazovku
70 | Bez záhlavia
71 | Ponechať zap. obrazovku
72 | Zobraziť pri uzamknutej obrazovke
73 | Ponechať v pamäti
74 | Žiadna celá obrazovka pre IME
75 | Orientácia
76 | Neústupné oznámenia
77 | Prebiehajúce oznámenia
78 | Nezobrazovať veľké oznámenia
79 | Priorita oznámení
80 | Vypnúť zvuk
81 | Zobraziť tlačidlo Menu
82 | Povolenia
83 | Zobraziť medzi nedávnymi aplikáciami
84 |
85 | (predvolené)
86 |
87 | Vynútiť
88 | Zabrániť
89 | Režim na celú obrazovku
90 |
91 | Predvolené otočenie
92 | Vždy na výšku
93 | Vždy na šírku
94 | Vynútiť autom. otáčanie
95 | Vždy na výšku (senzor)
96 | Vždy na šírku (senzor)
97 | Vždy na výšku (opačne)
98 | Vždy na šírku (opačne)
99 | Vynútiť autom. otáčanie (4-smery)
100 | Vždy na výšku (užívateľské nast.)
101 | Vždy na šírku (užívateľské nast.)
102 | Otáčanie na všetky strany (užívateľské nast.)
103 |
104 | Maximálna
105 | Vysoká
106 | Normálna
107 | Nízka
108 | Minimálna
109 |
110 |
111 | Nedávne aplikácie
112 |
113 |
114 | Zdroje
115 | Nenašli sa žiadne zdroje
116 | Chyba pri načítaní obsahu APK
117 |
118 |
119 | Povolenia
120 | Zakázať povolenia
121 | UPOZORNENIE: Zdieľaný balíček!
122 | meno alebo popis
123 | ( nie je dostupný žiadny opis )
124 | Vyberte povolenie pre filtrovanie, alebo Zrušiť pre zobrazenie všetkých
125 |
126 |
127 | Upozornenie
128 | Neuložili ste nastavenie.
129 | Naozaj sa chcete vrátiť a zrušiť zmeny?
130 | Použiť nastavenia
131 | Chcte aj ukončiť aplikáciu aby po opätovnom spustení použila nové nastavenia?
132 |
133 |
134 |
135 | Filter
136 | Všetky
137 | Prepísané
138 | Nezmenené
139 | Typ
140 | Užívateľské
141 | Systemové
142 | Aktívne nastavenia
143 | Aktívne
144 | Neaktívne
145 | Načítané zdroje
146 | Zrušiť
147 | Vyčistiť
148 | Použiť
149 |
150 |
151 | ja_som
152 |
153 |
--------------------------------------------------------------------------------
/res/values-zh-rCN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 允许为每个程序设置一些通用配置:\n
4 | DPI、字体大小、覆盖资源、语言、全屏、隐藏标题、保持屏幕开启、在锁屏界面上显示、常驻内存、方向、持续通知、撤销权限等
5 |
6 |
7 |
8 | 正在加载程序,请稍候
9 | 名称或包名
10 | 由 rovo89 和 Tungstwenty 开发的 Xposed 模块。
11 | \n您可访问此帖提问及建议。
12 | 本模块允许您在不修改资源文件的情况下,修改应用程序的一些通用配置:
13 | \n- 像素密度/DPI
14 | \n- 字体大小
15 | \n- 伪装屏幕尺寸以加载资源
16 | \n- 语言设置
17 | \n- 全屏模式
18 | \n- 隐藏标题栏
19 | \n- 程序运行时保持屏幕常亮
20 | \n- 在锁屏界面上面显示程序
21 | \n- 常驻内存
22 | \n- 禁止全屏键盘输入
23 | \n- 强制方向(纵向/横向/自动)
24 | \n- 持续通知(循环提示音)
25 | \n- 禁用大型(扩展)通知
26 | \n- 通知优先级
27 | \n- 在最近任务中隐藏
28 | \n- 静音(支持大多数应用)
29 | \n- 强制使用传统(导航栏)的菜单按钮
30 | \n- 撤销权限
31 | 版本: %s
32 | 翻者: %s
33 | 注意:虽然您现在可以直接进行配置,但只有在已安装 Xposed 框架并启用本模块时才会生效!
34 |
35 |
36 |
37 | 导出
38 | 导入
39 | 关于
40 |
41 |
42 | 文件不存在:%s
43 | 是否使用导入文件覆盖所有设置?
44 | 设置已导出到:%s
45 | 导出失败:%s
46 | 导入失败:%s
47 | 导入文件无效或为空:%s
48 | 导入成功,设置已覆盖!
49 |
50 |
51 |
52 | 保存
53 | 启动
54 | 设置
55 | Play 商店
56 |
57 |
58 |
59 | 设置
60 | DPI
61 | 字体大小
62 | 资源列表
63 | 分辨率(dp)
64 | 超大资源
65 | 同时应用资源到小部件
66 | 语言
67 | 全屏
68 | 隐藏标题
69 | 屏幕常亮
70 | 锁屏时显示
71 | 常驻内存
72 | 禁用全屏输入
73 | 方向
74 | 常驻通知
75 | 禁用扩展通知
76 | 通知优先级
77 | 静音
78 | 传统菜单按钮
79 | 权限管理
80 | 在最近任务中显示
81 |
82 | 默认
83 |
84 | 强制
85 | 阻止
86 | 沉浸
87 |
88 | 采用系统设置
89 | 强制正向竖屏
90 | 强制正向横屏
91 | 强制自动旋转
92 | 通过传感器判断竖屏方向
93 | 通过传感器判断横屏方向
94 | 通过传感器反向竖屏
95 | 通过传感器反向横屏
96 | 强制四向自动旋转
97 |
98 | 最高
99 | 较高
100 | 普通
101 | 较低
102 | 最低
103 |
104 |
105 | 资源
106 | 未找到资源
107 | 加载资源内容失败
108 |
109 |
110 | 权限管理
111 | 修改权限
112 | 警告:共享包!
113 | 权限名称及描述
114 | (未提供描述)
115 | 选择要过滤的权限,或取消显示全部
116 |
117 |
118 | 警告
119 | 您尚未保存设置。\n确定放弃修改直接返回?
120 | 应用设置
121 | 是否终止进程以便下次启动时采用新设置?
122 |
123 |
124 |
125 | 过滤
126 | 全部
127 | 已覆盖
128 | 未修改
129 | 应用类型
130 | 用户
131 | 系统
132 | 设置状态
133 | 已激活
134 | 未激活
135 | 资源设置
136 | 取消
137 | 清除
138 | 应用
139 |
140 |
141 | qhq、liudongmiao、Felix2yu
142 |
143 |
--------------------------------------------------------------------------------
/res/values-zh-rTW/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 針對每個程式設定環境變數,包括:
4 | DPI、字體大小、資源存取、語言、
5 | 全螢幕、有無標題列、保持螢幕開啟、顯示在鎖定螢幕、
6 | 常駐背景、關閉全螢幕輸入、橫/豎介面、常駐通知、關閉大型通知、存取權限
7 |
8 |
9 |
10 | 載入已安裝程式中....
11 | 程式名稱
12 | 本Xposed模組由rovo89及Tungstwenty設計纂寫,
13 | \n如有任何建議或問題請洽本討論串。
14 |
15 |
16 | 本模組可針對每個程式設定環境變數而不需自行修改APK檔;可修改功能包括:
17 | \n- DPI
18 | \n- 字體大小
19 | \n- 改變程式解析度
20 | \n- 區域/語言設定
21 | \n- 全螢幕模式
22 | \n- 隱藏標題列
23 | \n- 程式使用中保持螢幕開啟
24 | \n- 顯示於鎖定螢幕
25 | \n- 常駐背景
26 | \n- 關閉全螢幕輸入
27 | \n- 指定螢幕方向(垂直/水平/自動)
28 | \n- 常駐通知(播放音效)
29 | \n- 停用大型通知
30 | \n- 通知優先順序
31 | \n- 不顯示在最近開啟程式
32 | \n- 靜音(支援大多數app)
33 | \n- 強制使用傳統選單按鈕 (黑海苔)
34 | \n- 限制存取權限
35 | 版本: %s
36 | 譯者: %s
37 | 注意:就算設定介面正常顯示,但本程式需要在Xposed framework中啟用才可以發揮作用!
38 |
39 |
40 |
41 | 匯出設定
42 | 匯入設定
43 | 關於
44 |
45 |
46 | 找不到檔案:%s
47 | 確定以匯入資料取代現有設定?
48 | 設定已匯出至:%s
49 | 匯出失敗:%s
50 | 匯入失敗:%s
51 | 無效或空白設定檔: %s
52 | 匯入成功,設定已變更。
53 |
54 |
55 |
56 | 儲存
57 | 啟動
58 | 設定
59 | Play 商店
60 |
61 |
62 |
63 | 設定
64 | DPI
65 | 字體大小
66 | 資源
67 | 螢幕(dp)
68 | 放大
69 | 同時套用資源到小工具
70 | 區域設定
71 | 全螢幕
72 | 無標題列
73 | 保持螢幕開啟
74 | 於鎖定螢幕顯示
75 | 常駐背景
76 | 關閉全螢幕輸入
77 | 方向
78 | 常駐通知
79 | 停用大型通知
80 | 通知優先順序
81 | 靜音
82 | 傳統選單按鈕
83 | 權限設定
84 | 於最近開啟程式中顯示
85 |
86 | (預設-依程式設定)
87 |
88 | 強制
89 | 停用
90 | 沉浸
91 |
92 | 採用系統設定
93 | 強制垂直
94 | 強制水平
95 | 強制自動旋轉
96 | 垂直(感應器方向)
97 | 水平(感應器方向)
98 | 反向垂直(感應器方向)
99 | 反向水平(感應器方向)
100 | 強制四向任意旋轉
101 |
102 | 最高
103 | 較高
104 | 普通
105 | 較低
106 | 最低
107 |
108 |
109 | 資源列表
110 | 沒有使用資源
111 | 載入資源列表失敗
112 |
113 |
114 | 權限設定
115 | 啟用
116 | 警告:共享程式!
117 | 權限名稱或描述
118 | (沒有描述)
119 | 權限篩選器
120 |
121 |
122 | 警告
123 | 尚未儲存設定,確定離開?
124 | 已儲存新設定
125 | 是否同時關閉程式,以便在下次開啟時使新設定生效?
126 |
127 |
128 |
129 | 篩選器
130 | 全部
131 | 已修改
132 | 未修改
133 | 程式類型
134 | 使用者
135 | 系統
136 | 設定狀態
137 | 已啟用
138 | 未啟用
139 | 資源設定
140 | 取消
141 | 清除
142 | 套用
143 |
144 |
145 | Chih-Hsun、Liao @TAIWAN、ROC、Felix2yu、momomok
146 |
147 |
--------------------------------------------------------------------------------
/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/res/values/donottranslate.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | App Settings
5 |
6 |
7 |
--------------------------------------------------------------------------------
/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Set generic configurations on a per-app basis:
4 | DPI; Override loaded resouces; Locale; Fullscreen;
5 | Resident in memory; Orientation; Revoke Permissions; …
6 |
7 |
8 |
9 | Loading apps, please wait
10 | name or package
11 | An Xposed module by
12 | rovo89 and Tungstwenty.
13 | \nYou can use this thread for questions or suggestions.
14 | This mod allows certain generic configurations to be changed on a per-app basis, without needing to edit APKs:
15 | \n- density / dpi
16 | \n- font scale
17 | \n- fake screen size for resources loading
18 | \n- locale (language)
19 | \n- fullscreen mode
20 | \n- hide title bar
21 | \n- keep screen on while app is visible
22 | \n- show app above lockscreen
23 | \n- stay resident in memory
24 | \n- disable fullscreen keyboard input
25 | \n- force orientation (portrait/landscape/auto)
26 | \n- insistent notifications (loop the sound)
27 | \n- disable big (expanded) notifications
28 | \n- force or prevent ongoing notifications
29 | \n- notifications priority
30 | \n- force or exclude app from recents
31 | \n- mute audio (for most apps) including notifications
32 | \n- force using legacy (navbar) menu button
33 | \n- revoke permissions
34 | Version: %s
35 | Translator: %s
36 | Note: Although the configuration panels can be used as-is,
37 | they will only affect the apps if the Xposed framework is installed and if this module
38 | is enabled in its configuration!
39 |
40 |
41 |
42 | Refresh
43 | Recent apps
44 | Export
45 | Import
46 | About
47 |
48 |
49 | File does not exist: %s
50 | Replace all settings with the ones that are about to be imported?
51 | Settings exported to file: %s
52 | Export failed: %s
53 | Import failed: %s
54 | Invalid or empty file to import: %s
55 | Import successful; settings replaced
56 |
57 |
58 |
59 | Save
60 | Launch
61 | Settings
62 | Play Store
63 |
64 |
65 |
66 | Settings
67 | DPI
68 | Font scale
69 | List res.
70 | Screen (dp)
71 | xlarge res.
72 | Apply res to widgets
73 | Locale
74 | Fullscreen
75 | No title
76 | Keep screen on
77 | Show when locked
78 | Resident
79 | No Fullscreen IME
80 | Orientation
81 | Insistent notifications
82 | No big notifications
83 | Ongoing notifications
84 | Notifications priority
85 | Mute audio
86 | Legacy menu button
87 | Permissions
88 | Show in recents
89 |
90 | (default)
91 |
92 | Force
93 | Prevent
94 | Immersive
95 |
96 | Normal rotation
97 | Always portrait
98 | Always landscape
99 | Force auto-rotation
100 | Always portrait (sensor)
101 | Always landscape (sensor)
102 | Always portrait (reverse)
103 | Always landscape (reverse)
104 | Force auto-rotation (4-way)
105 | Always portrait (user setting)
106 | Always landscape (user setting)
107 | 4-way rotation (user setting)
108 |
109 | Max
110 | High
111 | Normal
112 | Low
113 | Min
114 |
115 |
116 | Recent Applications
117 |
118 |
119 | Resources
120 | No resources found
121 | Failed to load APK contents
122 |
123 |
124 | Permissions
125 | Revoke Permissions
126 | WARNING: Shared package!
127 | name or description
128 | ( no description provided )
129 | Select permission to filter for, or Cancel to show all
130 |
131 |
132 | Warning
133 | You didn\'t save the configuration.
134 | Really go back and discard changes?
135 | Apply settings
136 | Also kill the application so when it\'s relaunched it uses the new settings?
137 |
138 |
139 |
140 | Filter
141 | All
142 | Overridden
143 | Unchanged
144 | Type
145 | User
146 | System
147 | State
148 | Enabled
149 | Disabled
150 | Settings active
151 | Active
152 | Not active
153 | Resource loading
154 | Cancel
155 | Clear
156 | Apply
157 |
158 |
159 |
160 |
161 |
--------------------------------------------------------------------------------
/screenshots/app_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rovo89/XposedAppSettings/09ab9ee3b47260d071873d9b3b0f0304dd3c8fd4/screenshots/app_menu.png
--------------------------------------------------------------------------------
/screenshots/app_permissions.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rovo89/XposedAppSettings/09ab9ee3b47260d071873d9b3b0f0304dd3c8fd4/screenshots/app_permissions.png
--------------------------------------------------------------------------------
/screenshots/app_resources.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rovo89/XposedAppSettings/09ab9ee3b47260d071873d9b3b0f0304dd3c8fd4/screenshots/app_resources.png
--------------------------------------------------------------------------------
/screenshots/app_settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rovo89/XposedAppSettings/09ab9ee3b47260d071873d9b3b0f0304dd3c8fd4/screenshots/app_settings.png
--------------------------------------------------------------------------------
/screenshots/apps_list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rovo89/XposedAppSettings/09ab9ee3b47260d071873d9b3b0f0304dd3c8fd4/screenshots/apps_list.png
--------------------------------------------------------------------------------
/screenshots/filter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rovo89/XposedAppSettings/09ab9ee3b47260d071873d9b3b0f0304dd3c8fd4/screenshots/filter.png
--------------------------------------------------------------------------------
/screenshots/search_permissions.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rovo89/XposedAppSettings/09ab9ee3b47260d071873d9b3b0f0304dd3c8fd4/screenshots/search_permissions.png
--------------------------------------------------------------------------------
/src/de/robv/android/xposed/mods/appsettings/Common.java:
--------------------------------------------------------------------------------
1 | package de.robv.android.xposed.mods.appsettings;
2 |
3 | import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR;
4 | import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_FULL_USER;
5 | import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
6 | import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
7 | import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
8 | import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
9 | import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_SENSOR;
10 | import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
11 | import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
12 | import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
13 | import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE;
14 | import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT;
15 | import android.annotation.TargetApi;
16 | import android.app.Notification;
17 | import android.os.Build;
18 |
19 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
20 | public class Common {
21 |
22 | public static final String TAG = "AppSettings";
23 | public static final String MY_PACKAGE_NAME = Common.class.getPackage().getName();
24 |
25 | public static final String ACTION_PERMISSIONS = "update_permissions";
26 |
27 |
28 | public static final String PREFS = "ModSettings";
29 |
30 | public static final String PREF_DEFAULT = "default";
31 |
32 | public static final String PREF_ACTIVE = "/active";
33 | public static final String PREF_DPI = "/dpi";
34 | public static final String PREF_FONT_SCALE = "/font-scale";
35 | public static final String PREF_LOCALE = "/locale";
36 | public static final String PREF_SCREEN = "/screen";
37 | public static final String PREF_XLARGE = "/tablet";
38 | public static final String PREF_RES_ON_WIDGETS = "/res-on-widgets";
39 | public static final String PREF_RESIDENT = "/resident";
40 | public static final String PREF_NO_FULLSCREEN_IME = "/no-fullscreen-ime";
41 | public static final String PREF_NO_BIG_NOTIFICATIONS = "/no-big-notifications";
42 | public static final String PREF_INSISTENT_NOTIF = "/insistent-notif";
43 | public static final String PREF_ONGOING_NOTIF = "/ongoing-notif";
44 | public static final String PREF_NOTIF_PRIORITY = "/notif-priority";
45 | public static final String PREF_REVOKEPERMS = "/revoke-perms";
46 | public static final String PREF_REVOKELIST = "/revoke-list";
47 | public static final String PREF_FULLSCREEN = "/fullscreen";
48 | public static final String PREF_NO_TITLE = "/no-title";
49 | public static final String PREF_ALLOW_ON_LOCKSCREEN = "/allow-on-lockscreen";
50 | public static final String PREF_SCREEN_ON = "/screen-on";
51 | public static final String PREF_ORIENTATION = "/orientation";
52 | public static final String PREF_RECENTS_MODE = "/recents-mode";
53 | public static final String PREF_MUTE = "/mute";
54 | public static final String PREF_LEGACY_MENU = "/legacy-menu";
55 |
56 | public static final int[] swdp = { 0, 320, 480, 600, 800, 1000 };
57 | public static final int[] wdp = { 0, 320, 480, 600, 800, 1000 };
58 | public static final int[] hdp = { 0, 480, 854, 1024, 1280, 1600 };
59 |
60 | public static int[] orientationCodes = { Integer.MIN_VALUE,
61 | SCREEN_ORIENTATION_UNSPECIFIED,
62 | SCREEN_ORIENTATION_PORTRAIT, SCREEN_ORIENTATION_LANDSCAPE,
63 | SCREEN_ORIENTATION_SENSOR,
64 | SCREEN_ORIENTATION_SENSOR_PORTRAIT, SCREEN_ORIENTATION_SENSOR_LANDSCAPE,
65 | SCREEN_ORIENTATION_REVERSE_PORTRAIT, SCREEN_ORIENTATION_REVERSE_LANDSCAPE,
66 | SCREEN_ORIENTATION_FULL_SENSOR,
67 | // These require API 18
68 | SCREEN_ORIENTATION_USER_PORTRAIT, SCREEN_ORIENTATION_USER_LANDSCAPE,
69 | SCREEN_ORIENTATION_FULL_USER };
70 | {
71 | if (Build.VERSION.SDK_INT < 18) {
72 | // Strip out the last 3 entries
73 | int[] newCodes = new int[orientationCodes.length - 3];
74 | System.arraycopy(orientationCodes, 0, newCodes, 0, orientationCodes.length - 3);
75 | orientationCodes = newCodes;
76 | }
77 | }
78 | public static int[] orientationLabels = { R.string.settings_default,
79 | R.string.settings_ori_normal,
80 | R.string.settings_ori_portrait, R.string.settings_ori_landscape,
81 | R.string.settings_ori_forceauto,
82 | R.string.settings_ori_portrait_sensor, R.string.settings_ori_landscape_sensor,
83 | R.string.settings_ori_portrait_reverse, R.string.settings_ori_landscape_reverse,
84 | R.string.settings_ori_forceauto_4way,
85 | // These require API 18
86 | R.string.settings_ori_portrait_user, R.string.settings_ori_landscape_user,
87 | R.string.settings_ori_user_4way };
88 | {
89 | if (Build.VERSION.SDK_INT < 18) {
90 | // Strip out the last 3 entries
91 | int[] newLabels = new int[orientationLabels.length - 3];
92 | System.arraycopy(orientationLabels, 0, newLabels, 0, orientationLabels.length - 3);
93 | orientationLabels = newLabels;
94 | }
95 | }
96 |
97 | public static final int[] notifPriCodes = { Integer.MIN_VALUE,
98 | Notification.PRIORITY_MAX, Notification.PRIORITY_HIGH,
99 | Notification.PRIORITY_DEFAULT,
100 | Notification.PRIORITY_LOW, Notification.PRIORITY_MIN };
101 | public static final int[] notifPriLabels = { R.string.settings_default,
102 | R.string.settings_npri_max, R.string.settings_npri_high,
103 | R.string.settings_npri_normal,
104 | R.string.settings_npri_low,
105 | R.string.settings_npri_min };
106 |
107 | public static final int FULLSCREEN_DEFAULT = 0;
108 | public static final int FULLSCREEN_FORCE = 1;
109 | public static final int FULLSCREEN_PREVENT = 2;
110 | public static final int FULLSCREEN_IMMERSIVE = 3;
111 |
112 | public static final int ONGOING_NOTIF_DEFAULT = 0;
113 | public static final int ONGOING_NOTIF_FORCE = 1;
114 | public static final int ONGOING_NOTIF_PREVENT = 2;
115 |
116 | public static final int PREF_RECENTS_DEFAULT = 0;
117 | public static final int PREF_RECENTS_FORCE = 1;
118 | public static final int PREF_RECENTS_PREVENT = 2;
119 |
120 | }
121 |
--------------------------------------------------------------------------------
/src/de/robv/android/xposed/mods/appsettings/FilterItemComponent.java:
--------------------------------------------------------------------------------
1 | package de.robv.android.xposed.mods.appsettings;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.util.AttributeSet;
6 | import android.view.LayoutInflater;
7 | import android.widget.LinearLayout;
8 | import android.widget.RadioGroup;
9 | import android.widget.TextView;
10 |
11 | /**
12 | * Composite component that displays a header and a triplet of radio buttons for
13 | * selection of All / Overridden / Unchanged settings for each parameter
14 | */
15 | public class FilterItemComponent extends LinearLayout {
16 |
17 | private OnFilterChangeListener listener;
18 |
19 | /** Constructor for designer instantiation */
20 | public FilterItemComponent(Context context, AttributeSet attrs) {
21 | super(context, attrs);
22 |
23 | LayoutInflater.from(context).inflate(R.layout.filter_item, this);
24 |
25 | TypedArray atts = context.obtainStyledAttributes(attrs, R.styleable.FilterItem);
26 |
27 | // Load label values, if any
28 | setLabel(R.id.txtFilterName, atts.getString(R.styleable.FilterItem_label));
29 | setLabel(R.id.radAll, atts.getString(R.styleable.FilterItem_all_label));
30 | setLabel(R.id.radOverridden, atts.getString(R.styleable.FilterItem_overridden_label));
31 | setLabel(R.id.radUnchanged, atts.getString(R.styleable.FilterItem_unchanged_label));
32 | atts.recycle();
33 |
34 | setupListener();
35 | }
36 |
37 | /** Constructor for programmatic instantiation */
38 | public FilterItemComponent(Context context, String filterName, String labelAll, String labelOverriden, String labelUnchanged) {
39 | super(context);
40 |
41 | LayoutInflater.from(context).inflate(R.layout.filter_item, this);
42 |
43 | // Load label values, if any
44 | setLabel(R.id.txtFilterName, filterName);
45 | setLabel(R.id.radAll, labelAll);
46 | setLabel(R.id.radOverridden, labelOverriden);
47 | setLabel(R.id.radUnchanged, labelUnchanged);
48 |
49 | setupListener();
50 | }
51 |
52 | private void setupListener() {
53 | // Notify any listener of changes in the selected option
54 | ((RadioGroup) findViewById(R.id.radOptions)).setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
55 | @Override
56 | public void onCheckedChanged(RadioGroup group, int checkedId) {
57 | if (listener != null) {
58 | switch (checkedId) {
59 | case R.id.radOverridden:
60 | listener.onFilterChanged(FilterItemComponent.this, FilterState.OVERRIDDEN);
61 | break;
62 | case R.id.radUnchanged:
63 | listener.onFilterChanged(FilterItemComponent.this, FilterState.UNCHANGED);
64 | break;
65 | default:
66 | listener.onFilterChanged(FilterItemComponent.this, FilterState.ALL);
67 | break;
68 | }
69 | }
70 | }
71 | });
72 | }
73 |
74 | /*
75 | * Update the label of a view id, if non-null
76 | */
77 | private void setLabel(int id, CharSequence value) {
78 | TextView label = (TextView) findViewById(id);
79 | if (label != null && value != null) {
80 | label.setText(value);
81 | }
82 | }
83 |
84 | /**
85 | * Enable or disable all the items within this compound component
86 | */
87 | @Override
88 | public void setEnabled(boolean enabled) {
89 | findViewById(R.id.radOptions).setEnabled(enabled);
90 | findViewById(R.id.radAll).setEnabled(enabled);
91 | findViewById(R.id.radOverridden).setEnabled(enabled);
92 | findViewById(R.id.radUnchanged).setEnabled(enabled);
93 | }
94 |
95 | /**
96 | * Check if this compound component is enabled
97 | */
98 | @Override
99 | public boolean isEnabled() {
100 | return findViewById(R.id.radOptions).isEnabled();
101 | }
102 |
103 | /**
104 | * Get currently selected filter option
105 | */
106 | public FilterState getFilterState() {
107 | switch (((RadioGroup) findViewById(R.id.radOptions)).getCheckedRadioButtonId()) {
108 | case R.id.radOverridden:
109 | return FilterState.OVERRIDDEN;
110 | case R.id.radUnchanged:
111 | return FilterState.UNCHANGED;
112 | default:
113 | return FilterState.ALL;
114 | }
115 | }
116 |
117 | /**
118 | * Activate one of the 3 options as the selected one
119 | */
120 | public void setFilterState(FilterState state) {
121 | // Handle null values and use the default "All"
122 | if (state == null)
123 | state = FilterState.ALL;
124 |
125 | switch (state) {
126 | case OVERRIDDEN:
127 | ((RadioGroup) findViewById(R.id.radOptions)).check(R.id.radOverridden);
128 | break;
129 | case UNCHANGED:
130 | ((RadioGroup) findViewById(R.id.radOptions)).check(R.id.radUnchanged);
131 | break;
132 | default:
133 | ((RadioGroup) findViewById(R.id.radOptions)).check(R.id.radAll);
134 | break;
135 | }
136 | }
137 |
138 | /**
139 | * Register a listener to be notified when the selection changes
140 | */
141 | public void setOnFilterChangeListener(OnFilterChangeListener listener) {
142 | this.listener = listener;
143 | }
144 |
145 | /**
146 | * Interface for listeners that will be notified of selection changes
147 | */
148 | public static interface OnFilterChangeListener {
149 | /**
150 | * Notification that this filter item has changed to a new selected state
151 | */
152 | public void onFilterChanged(FilterItemComponent item, FilterState state);
153 | }
154 |
155 | /**
156 | * Possible values for the filter state: All / Overridden / Unchanged
157 | */
158 | public static enum FilterState {
159 | ALL, OVERRIDDEN, UNCHANGED;
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/src/de/robv/android/xposed/mods/appsettings/XposedMod.java:
--------------------------------------------------------------------------------
1 | package de.robv.android.xposed.mods.appsettings;
2 |
3 |
4 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
5 | import static de.robv.android.xposed.XposedHelpers.getAdditionalInstanceField;
6 | import static de.robv.android.xposed.XposedHelpers.getObjectField;
7 | import static de.robv.android.xposed.XposedHelpers.removeAdditionalInstanceField;
8 | import static de.robv.android.xposed.XposedHelpers.setAdditionalInstanceField;
9 | import static de.robv.android.xposed.XposedHelpers.setFloatField;
10 | import static de.robv.android.xposed.XposedHelpers.setIntField;
11 | import static de.robv.android.xposed.XposedHelpers.setObjectField;
12 | import java.util.Locale;
13 | import android.annotation.SuppressLint;
14 | import android.annotation.TargetApi;
15 | import android.app.AndroidAppHelper;
16 | import android.app.Notification;
17 | import android.content.res.Configuration;
18 | import android.content.res.Resources;
19 | import android.content.res.XResources;
20 | import android.content.res.XResources.DimensionReplacement;
21 | import android.media.AudioTrack;
22 | import android.media.JetPlayer;
23 | import android.media.MediaPlayer;
24 | import android.media.SoundPool;
25 | import android.os.Build;
26 | import android.util.DisplayMetrics;
27 | import android.util.TypedValue;
28 | import android.view.Display;
29 | import android.view.Surface;
30 | import android.view.SurfaceHolder;
31 | import android.view.ViewConfiguration;
32 | import de.robv.android.xposed.IXposedHookLoadPackage;
33 | import de.robv.android.xposed.IXposedHookZygoteInit;
34 | import de.robv.android.xposed.XC_MethodHook;
35 | import de.robv.android.xposed.XC_MethodReplacement;
36 | import de.robv.android.xposed.XSharedPreferences;
37 | import de.robv.android.xposed.XposedBridge;
38 | import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
39 | import de.robv.android.xposed.mods.appsettings.hooks.Activities;
40 | import de.robv.android.xposed.mods.appsettings.hooks.PackagePermissions;
41 |
42 | public class XposedMod implements IXposedHookZygoteInit, IXposedHookLoadPackage {
43 |
44 | public static final String this_package = XposedMod.class.getPackage().getName();
45 |
46 | private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
47 | private static final String[] SYSTEMUI_ADJUSTED_DIMENSIONS = {
48 | "status_bar_height",
49 | "navigation_bar_height", "navigation_bar_height_landscape",
50 | "navigation_bar_width",
51 | "system_bar_height"
52 | };
53 |
54 | public static XSharedPreferences prefs;
55 |
56 | @Override
57 | public void initZygote(IXposedHookZygoteInit.StartupParam startupParam) throws Throwable {
58 | loadPrefs();
59 |
60 | adjustSystemDimensions();
61 |
62 | // Hook to override DPI (globally, including resource load + rendering)
63 | try {
64 | if (Build.VERSION.SDK_INT < 17) {
65 | findAndHookMethod(Display.class, "init", int.class, new XC_MethodHook() {
66 | @Override
67 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
68 | String packageName = AndroidAppHelper.currentPackageName();
69 |
70 | if (!isActive(packageName)) {
71 | // No overrides for this package
72 | return;
73 | }
74 |
75 | int packageDPI = prefs.getInt(packageName + Common.PREF_DPI,
76 | prefs.getInt(Common.PREF_DEFAULT + Common.PREF_DPI, 0));
77 | if (packageDPI > 0) {
78 | // Density for this package is overridden, change density
79 | setFloatField(param.thisObject, "mDensity", packageDPI / 160.0f);
80 | }
81 | };
82 | });
83 | } else {
84 | findAndHookMethod(Display.class, "updateDisplayInfoLocked", new XC_MethodHook() {
85 | @Override
86 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
87 | String packageName = AndroidAppHelper.currentPackageName();
88 |
89 | if (!isActive(packageName)) {
90 | // No overrides for this package
91 | return;
92 | }
93 |
94 | int packageDPI = prefs.getInt(packageName + Common.PREF_DPI,
95 | prefs.getInt(Common.PREF_DEFAULT + Common.PREF_DPI, 0));
96 | if (packageDPI > 0) {
97 | // Density for this package is overridden, change density
98 | Object mDisplayInfo = getObjectField(param.thisObject, "mDisplayInfo");
99 | setIntField(mDisplayInfo, "logicalDensityDpi", packageDPI);
100 | }
101 | };
102 | });
103 | }
104 | } catch (Throwable t) {
105 | XposedBridge.log(t);
106 | }
107 |
108 | // Override settings used when loading resources
109 | try {
110 | findAndHookMethod(Resources.class, "updateConfiguration",
111 | Configuration.class, DisplayMetrics.class, "android.content.res.CompatibilityInfo",
112 | new XC_MethodHook() {
113 |
114 | @Override
115 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
116 | if (param.args[0] == null)
117 | return;
118 |
119 | /* Starting with XposedBridge v52, by the time updateConfiguration is called this object
120 | * might not yet be an XResources instance where the package name can be fetched fom.
121 | * If that's the case, use the newly introduced getPackageNameDuringConstruction method
122 | * which was introduced for this purpose and fetches the package name for this Resource
123 | * in the middle of initialization.
124 | */
125 | String packageName;
126 | Resources res = ((Resources) param.thisObject);
127 | if (res instanceof XResources) {
128 | packageName = ((XResources) res).getPackageName();
129 | } else {
130 | try {
131 | packageName = XResources.getPackageNameDuringConstruction();
132 | } catch (IllegalStateException e) {
133 | // That's ok, we might have been called for
134 | // non-standard resources
135 | return;
136 | }
137 | }
138 |
139 | String hostPackageName = AndroidAppHelper.currentPackageName();
140 | boolean isActiveApp = hostPackageName.equals(packageName);
141 |
142 | // Workaround for KitKat. The keyguard is a different package now but runs in the
143 | // same process as SystemUI and displays as main package
144 | if (Build.VERSION.SDK_INT >= 19 && hostPackageName.equals("com.android.keyguard"))
145 | hostPackageName = SYSTEMUI_PACKAGE;
146 |
147 | // If setting enabled to also modify resources on other host packages (typically
148 | // for widgets), simulate that this package is not hosted by another one
149 | // For everything except the process-wide default Locale - see below
150 | if (isActive(packageName, Common.PREF_RES_ON_WIDGETS))
151 | hostPackageName = packageName;
152 |
153 | // settings related to the density etc. are calculated for the running app...
154 | Configuration newConfig = null;
155 | if (hostPackageName != null && isActive(hostPackageName)) {
156 | int screen = prefs.getInt(hostPackageName + Common.PREF_SCREEN,
157 | prefs.getInt(Common.PREF_DEFAULT + Common.PREF_SCREEN, 0));
158 | if (screen < 0 || screen >= Common.swdp.length)
159 | screen = 0;
160 |
161 | int dpi = prefs.getInt(hostPackageName + Common.PREF_DPI,
162 | prefs.getInt(Common.PREF_DEFAULT + Common.PREF_DPI, 0));
163 | int fontScale = prefs.getInt(hostPackageName + Common.PREF_FONT_SCALE,
164 | prefs.getInt(Common.PREF_DEFAULT + Common.PREF_FONT_SCALE, 0));
165 | int swdp = Common.swdp[screen];
166 | int wdp = Common.wdp[screen];
167 | int hdp = Common.hdp[screen];
168 |
169 | boolean xlarge = prefs.getBoolean(hostPackageName + Common.PREF_XLARGE, false);
170 |
171 | if (swdp > 0 || xlarge || dpi > 0 || fontScale > 0) {
172 | newConfig = new Configuration((Configuration) param.args[0]);
173 |
174 | DisplayMetrics newMetrics;
175 | if (param.args[1] != null) {
176 | newMetrics = new DisplayMetrics();
177 | newMetrics.setTo((DisplayMetrics) param.args[1]);
178 | param.args[1] = newMetrics;
179 | } else {
180 | newMetrics = res.getDisplayMetrics();
181 | }
182 |
183 | if (swdp > 0) {
184 | newConfig.smallestScreenWidthDp = swdp;
185 | newConfig.screenWidthDp = wdp;
186 | newConfig.screenHeightDp = hdp;
187 | }
188 | if (xlarge)
189 | newConfig.screenLayout |= Configuration.SCREENLAYOUT_SIZE_XLARGE;
190 | if (dpi > 0) {
191 | newMetrics.density = dpi / 160f;
192 | newMetrics.densityDpi = dpi;
193 |
194 | if (Build.VERSION.SDK_INT >= 17)
195 | setIntField(newConfig, "densityDpi", dpi);
196 | }
197 | if (fontScale > 0)
198 | newConfig.fontScale = fontScale / 100.0f;
199 | }
200 | }
201 |
202 | // ... whereas the locale is taken from the app for which resources are loaded
203 | if (packageName != null && isActive(packageName)) {
204 | Locale loc = getPackageSpecificLocale(packageName);
205 | if (loc != null) {
206 | if (newConfig == null)
207 | newConfig = new Configuration((Configuration) param.args[0]);
208 |
209 | setConfigurationLocale(newConfig, loc);
210 | // Also set the locale as the app-wide default,
211 | // for purposes other than resource loading
212 | // Only do this when the package's res are not being loaded by a different
213 | // host, regardless of the Widgets setting
214 | if (isActiveApp)
215 | Locale.setDefault(loc);
216 | }
217 | }
218 |
219 | if (newConfig != null)
220 | param.args[0] = newConfig;
221 | }
222 | });
223 | } catch (Throwable t) {
224 | XposedBridge.log(t);
225 | }
226 |
227 | try {
228 | final int sdk = Build.VERSION.SDK_INT;
229 | XC_MethodHook notifyHook = new XC_MethodHook() {
230 | @SuppressWarnings("deprecation")
231 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
232 | @Override
233 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
234 | String packageName = (String) param.args[0];
235 |
236 | Notification n;
237 | if (sdk <= 15 || sdk >= 18)
238 | n = (Notification) param.args[6];
239 | else
240 | n = (Notification) param.args[5];
241 |
242 | prefs.reload();
243 | if (!isActive(packageName))
244 | return;
245 |
246 | if (isActive(packageName, Common.PREF_INSISTENT_NOTIF)) {
247 | n.flags |= Notification.FLAG_INSISTENT;
248 | }
249 | if (isActive(packageName, Common.PREF_NO_BIG_NOTIFICATIONS)) {
250 | try {
251 | setObjectField(n, "bigContentView", null);
252 | } catch (Exception e) { }
253 | }
254 | int ongoingNotif = XposedMod.prefs.getInt(packageName + Common.PREF_ONGOING_NOTIF,
255 | Common.ONGOING_NOTIF_DEFAULT);
256 | if (ongoingNotif == Common.ONGOING_NOTIF_FORCE) {
257 | n.flags |= Notification.FLAG_ONGOING_EVENT;
258 | } else if (ongoingNotif == Common.ONGOING_NOTIF_PREVENT) {
259 | n.flags &= ~Notification.FLAG_ONGOING_EVENT & ~Notification.FLAG_FOREGROUND_SERVICE;
260 | }
261 |
262 | if (isActive(packageName, Common.PREF_MUTE)) {
263 | n.sound = null;
264 | n.flags &= ~Notification.DEFAULT_SOUND;
265 | }
266 | if (sdk >= 16 && isActive(packageName) && prefs.contains(packageName + Common.PREF_NOTIF_PRIORITY)) {
267 | int priority = XposedMod.prefs.getInt(packageName + Common.PREF_NOTIF_PRIORITY, 0);
268 | if (priority > 0 && priority < Common.notifPriCodes.length) {
269 | n.flags &= ~Notification.FLAG_HIGH_PRIORITY;
270 | n.priority = Common.notifPriCodes[priority];
271 | }
272 | }
273 | }
274 | };
275 | if (sdk <= 15) {
276 | findAndHookMethod("com.android.server.NotificationManagerService", null, "enqueueNotificationInternal", String.class, int.class, int.class,
277 | String.class, int.class, int.class, Notification.class, int[].class,
278 | notifyHook);
279 | } else if (sdk == 16) {
280 | findAndHookMethod("com.android.server.NotificationManagerService", null, "enqueueNotificationInternal", String.class, int.class, int.class,
281 | String.class, int.class, Notification.class, int[].class,
282 | notifyHook);
283 | } else if (sdk == 17) {
284 | findAndHookMethod("com.android.server.NotificationManagerService", null, "enqueueNotificationInternal", String.class, int.class, int.class,
285 | String.class, int.class, Notification.class, int[].class, int.class,
286 | notifyHook);
287 | } else if (sdk >= 18) {
288 | findAndHookMethod("com.android.server.NotificationManagerService", null, "enqueueNotificationInternal", String.class, String.class,
289 | int.class, int.class, String.class, int.class, Notification.class, int[].class, int.class,
290 | notifyHook);
291 | }
292 | } catch (Throwable t) {
293 | XposedBridge.log(t);
294 | }
295 |
296 | PackagePermissions.initHooks();
297 | Activities.hookActivitySettings();
298 | }
299 |
300 |
301 | @SuppressLint("NewApi")
302 | private void setConfigurationLocale(Configuration config, Locale loc) {
303 | config.locale = loc;
304 | if (Build.VERSION.SDK_INT >= 17) {
305 | // Don't use setLocale() in order not to trigger userSetLocale
306 | config.setLayoutDirection(loc);
307 | }
308 | }
309 |
310 |
311 | /** Adjust all framework dimensions that should reflect
312 | * changes related with SystemUI, namely statusbar and navbar sizes.
313 | * The values are adjusted and replaced system-wide by fixed px values.
314 | */
315 | private void adjustSystemDimensions() {
316 | if (!isActive(SYSTEMUI_PACKAGE))
317 | return;
318 |
319 | int systemUiDpi = prefs.getInt(SYSTEMUI_PACKAGE + Common.PREF_DPI,
320 | prefs.getInt(Common.PREF_DEFAULT + Common.PREF_DPI, 0));
321 | if (systemUiDpi <= 0)
322 | return;
323 |
324 | // SystemUI had its DPI overridden.
325 | // Adjust the relevant framework dimen resources.
326 | Resources sysRes = Resources.getSystem();
327 | float sysDensity = sysRes.getDisplayMetrics().density;
328 | float scaleFactor = (systemUiDpi / 160f) / sysDensity;
329 |
330 | for (String resName : SYSTEMUI_ADJUSTED_DIMENSIONS) {
331 | int id = sysRes.getIdentifier(resName, "dimen", "android");
332 | if (id != 0) {
333 | float original = sysRes.getDimension(id);
334 | XResources.setSystemWideReplacement(id,
335 | new DimensionReplacement(original * scaleFactor, TypedValue.COMPLEX_UNIT_PX));
336 | }
337 | }
338 | }
339 |
340 | @Override
341 | public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {
342 | prefs.reload();
343 |
344 | // Override the default Locale if one is defined (not res-related, here)
345 | if (isActive(lpparam.packageName)) {
346 | Locale packageLocale = getPackageSpecificLocale(lpparam.packageName);
347 | if (packageLocale != null)
348 | Locale.setDefault(packageLocale);
349 | }
350 |
351 | if (this_package.equals(lpparam.packageName)) {
352 | findAndHookMethod("de.robv.android.xposed.mods.appsettings.XposedModActivity",
353 | lpparam.classLoader, "isModActive", XC_MethodReplacement.returnConstant(true));
354 | }
355 |
356 | try {
357 | if (isActive(lpparam.packageName, Common.PREF_LEGACY_MENU))
358 | findAndHookMethod(ViewConfiguration.class, "hasPermanentMenuKey",
359 | XC_MethodReplacement.returnConstant(true));
360 | } catch (Throwable t) {
361 | XposedBridge.log(t);
362 | }
363 |
364 | try {
365 | if (isActive(lpparam.packageName, Common.PREF_MUTE)) {
366 |
367 | // Hook the AudioTrack API
368 | findAndHookMethod(AudioTrack.class, "play", XC_MethodReplacement.returnConstant(null));
369 |
370 | // Hook the JetPlayer API
371 | findAndHookMethod(JetPlayer.class, "play", XC_MethodReplacement.returnConstant(null));
372 |
373 | // Hook the MediaPlayer API
374 | XC_MethodHook displayHook = new XC_MethodHook() {
375 | @Override
376 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
377 | // Detect if video will be used for this media
378 | if (param.args[0] != null)
379 | setAdditionalInstanceField(param.thisObject, "HasVideo", true);
380 | else
381 | removeAdditionalInstanceField(param.thisObject, "HasVideo");
382 | }
383 | };
384 | findAndHookMethod(MediaPlayer.class, "setSurface", Surface.class, displayHook);
385 | findAndHookMethod(MediaPlayer.class, "setDisplay", SurfaceHolder.class, displayHook);
386 | findAndHookMethod(MediaPlayer.class, "start", new XC_MethodHook() {
387 | @Override
388 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
389 | if (getAdditionalInstanceField(param.thisObject, "HasVideo") != null)
390 | // Video will be used - still start the media but with muted volume
391 | ((MediaPlayer) param.thisObject).setVolume(0, 0);
392 | else
393 | // No video - skip starting to play the media altogether
394 | param.setResult(null);
395 | }
396 | });
397 |
398 | // Hook the SoundPool API
399 | findAndHookMethod(SoundPool.class, "play", int.class, float.class, float.class,
400 | int.class, int.class, float.class,
401 | XC_MethodReplacement.returnConstant(0));
402 | findAndHookMethod(SoundPool.class, "resume", int.class, XC_MethodReplacement.returnConstant(null));
403 | }
404 | } catch (Throwable t) {
405 | XposedBridge.log(t);
406 | }
407 | }
408 |
409 | private static Locale getPackageSpecificLocale(String packageName) {
410 | String locale = prefs.getString(packageName + Common.PREF_LOCALE, null);
411 | if (locale == null || locale.isEmpty())
412 | return null;
413 |
414 | String[] localeParts = locale.split("_", 3);
415 | String language = localeParts[0];
416 | String region = (localeParts.length >= 2) ? localeParts[1] : "";
417 | String variant = (localeParts.length >= 3) ? localeParts[2] : "";
418 | return new Locale(language, region, variant);
419 | }
420 |
421 |
422 | public static void loadPrefs() {
423 | prefs = new XSharedPreferences(Common.MY_PACKAGE_NAME, Common.PREFS);
424 | prefs.makeWorldReadable();
425 | }
426 |
427 | public static boolean isActive(String packageName) {
428 | return prefs.getBoolean(packageName + Common.PREF_ACTIVE, false);
429 | }
430 |
431 | public static boolean isActive(String packageName, String sub) {
432 | return prefs.getBoolean(packageName + Common.PREF_ACTIVE, false) && prefs.getBoolean(packageName + sub, false);
433 | }
434 | }
435 |
--------------------------------------------------------------------------------
/src/de/robv/android/xposed/mods/appsettings/hooks/Activities.java:
--------------------------------------------------------------------------------
1 | package de.robv.android.xposed.mods.appsettings.hooks;
2 |
3 | import static de.robv.android.xposed.XposedBridge.hookAllConstructors;
4 | import static de.robv.android.xposed.XposedBridge.hookMethod;
5 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
6 | import static de.robv.android.xposed.XposedHelpers.findClass;
7 | import static de.robv.android.xposed.XposedHelpers.findMethodExact;
8 | import static de.robv.android.xposed.XposedHelpers.getAdditionalInstanceField;
9 | import static de.robv.android.xposed.XposedHelpers.getObjectField;
10 | import static de.robv.android.xposed.XposedHelpers.getStaticIntField;
11 | import static de.robv.android.xposed.XposedHelpers.setAdditionalInstanceField;
12 | import static de.robv.android.xposed.XposedHelpers.setIntField;
13 |
14 | import java.lang.reflect.Method;
15 |
16 | import android.annotation.SuppressLint;
17 | import android.annotation.TargetApi;
18 | import android.app.Activity;
19 | import android.content.Context;
20 | import android.content.Intent;
21 | import android.content.pm.ActivityInfo;
22 | import android.inputmethodservice.InputMethodService;
23 | import android.os.Build;
24 | import android.view.View;
25 | import android.view.Window;
26 | import android.view.WindowManager;
27 | import android.view.inputmethod.EditorInfo;
28 | import android.view.inputmethod.InputConnection;
29 | import de.robv.android.xposed.XC_MethodHook;
30 | import de.robv.android.xposed.XposedBridge;
31 | import de.robv.android.xposed.mods.appsettings.Common;
32 | import de.robv.android.xposed.mods.appsettings.XposedMod;
33 |
34 |
35 | public class Activities {
36 |
37 | private static final String PROP_FULLSCREEN = "AppSettings-Fullscreen";
38 | private static final String PROP_IMMERSIVE = "AppSettings-Immersive";
39 | private static final String PROP_KEEP_SCREEN_ON = "AppSettings-KeepScreenOn";
40 | private static final String PROP_LEGACY_MENU = "AppSettings-LegacyMenu";
41 | private static final String PROP_ORIENTATION = "AppSettings-Orientation";
42 |
43 | private static int FLAG_NEEDS_MENU_KEY = getStaticIntField(WindowManager.LayoutParams.class, "FLAG_NEEDS_MENU_KEY");
44 |
45 | public static void hookActivitySettings() {
46 | try {
47 | findAndHookMethod("com.android.internal.policy.impl.PhoneWindow", null, "generateLayout",
48 | "com.android.internal.policy.impl.PhoneWindow.DecorView", new XC_MethodHook() {
49 |
50 | @SuppressLint("InlinedApi")
51 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
52 | Window window = (Window) param.thisObject;
53 | View decorView = (View) param.args[0];
54 | Context context = window.getContext();
55 | String packageName = context.getPackageName();
56 |
57 | if (!XposedMod.isActive(packageName))
58 | return;
59 |
60 | int fullscreen;
61 | try {
62 | fullscreen = XposedMod.prefs.getInt(packageName + Common.PREF_FULLSCREEN,
63 | Common.FULLSCREEN_DEFAULT);
64 | } catch (ClassCastException ex) {
65 | // Legacy boolean setting
66 | fullscreen = XposedMod.prefs.getBoolean(packageName + Common.PREF_FULLSCREEN, false)
67 | ? Common.FULLSCREEN_FORCE : Common.FULLSCREEN_DEFAULT;
68 | }
69 | if (fullscreen == Common.FULLSCREEN_FORCE) {
70 | window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
71 | setAdditionalInstanceField(window, PROP_FULLSCREEN, Boolean.TRUE);
72 | } else if (fullscreen == Common.FULLSCREEN_PREVENT) {
73 | window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
74 | setAdditionalInstanceField(window, PROP_FULLSCREEN, Boolean.FALSE);
75 | } else if (fullscreen == Common.FULLSCREEN_IMMERSIVE && Build.VERSION.SDK_INT >= 19) {
76 | window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
77 | setAdditionalInstanceField(window, PROP_FULLSCREEN, Boolean.TRUE);
78 | setAdditionalInstanceField(decorView, PROP_IMMERSIVE, Boolean.TRUE);
79 | decorView.setSystemUiVisibility(
80 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
81 | | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
82 | | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
83 | }
84 |
85 | if (XposedMod.prefs.getBoolean(packageName + Common.PREF_NO_TITLE, false))
86 | window.requestFeature(Window.FEATURE_NO_TITLE);
87 |
88 | if (XposedMod.prefs.getBoolean(packageName + Common.PREF_ALLOW_ON_LOCKSCREEN, false))
89 | window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
90 | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
91 | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
92 |
93 | if (XposedMod.prefs.getBoolean(packageName + Common.PREF_SCREEN_ON, false)) {
94 | window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
95 | setAdditionalInstanceField(window, PROP_KEEP_SCREEN_ON, Boolean.TRUE);
96 | }
97 |
98 | if (XposedMod.prefs.getBoolean(packageName + Common.PREF_LEGACY_MENU, false)) {
99 | window.setFlags(FLAG_NEEDS_MENU_KEY, FLAG_NEEDS_MENU_KEY);
100 | setAdditionalInstanceField(window, PROP_LEGACY_MENU, Boolean.TRUE);
101 | }
102 |
103 | int orientation = XposedMod.prefs.getInt(packageName + Common.PREF_ORIENTATION, XposedMod.prefs.getInt(Common.PREF_DEFAULT + Common.PREF_ORIENTATION, 0));
104 | if (orientation > 0 && orientation < Common.orientationCodes.length && context instanceof Activity) {
105 | ((Activity) context).setRequestedOrientation(Common.orientationCodes[orientation]);
106 | setAdditionalInstanceField(context, PROP_ORIENTATION, orientation);
107 | }
108 | }
109 | });
110 | } catch (Throwable e) {
111 | XposedBridge.log(e);
112 | }
113 |
114 | try {
115 | findAndHookMethod(Window.class, "setFlags", int.class, int.class,
116 | new XC_MethodHook() {
117 | @Override
118 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
119 |
120 | int flags = (Integer) param.args[0];
121 | int mask = (Integer) param.args[1];
122 | if ((mask & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0) {
123 | Boolean fullscreen = (Boolean) getAdditionalInstanceField(param.thisObject, PROP_FULLSCREEN);
124 | if (fullscreen != null) {
125 | if (fullscreen.booleanValue()) {
126 | flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
127 | } else {
128 | flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN;
129 | }
130 | param.args[0] = flags;
131 | }
132 | }
133 | if ((mask & WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) != 0) {
134 | Boolean keepScreenOn = (Boolean) getAdditionalInstanceField(param.thisObject, PROP_KEEP_SCREEN_ON);
135 | if (keepScreenOn != null) {
136 | if (keepScreenOn.booleanValue()) {
137 | flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
138 | }
139 | param.args[0] = flags;
140 | }
141 | }
142 | if ((mask & FLAG_NEEDS_MENU_KEY) != 0) {
143 | Boolean menu = (Boolean) getAdditionalInstanceField(param.thisObject, PROP_LEGACY_MENU);
144 | if (menu != null) {
145 | if (menu.booleanValue()) {
146 | flags |= FLAG_NEEDS_MENU_KEY;
147 | }
148 | param.args[0] = flags;
149 | }
150 | }
151 | }
152 | });
153 | } catch (Throwable e) {
154 | XposedBridge.log(e);
155 | }
156 |
157 | if (Build.VERSION.SDK_INT >= 19) {
158 | try {
159 | findAndHookMethod("android.view.ViewRootImpl", null, "dispatchSystemUiVisibilityChanged",
160 | int.class, int.class, int.class, int.class, new XC_MethodHook() {
161 | @TargetApi(19)
162 | @Override
163 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
164 | // Has the navigation bar been shown?
165 | int localChanges = (Integer) param.args[3];
166 | if ((localChanges & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0)
167 | return;
168 |
169 | // Should it be hidden?
170 | View decorView = (View) getObjectField(param.thisObject, "mView");
171 | Boolean immersive = (decorView == null)
172 | ? null
173 | : (Boolean) getAdditionalInstanceField(decorView, PROP_IMMERSIVE);
174 | if (immersive == null || !immersive.booleanValue())
175 | return;
176 |
177 | // Enforce SYSTEM_UI_FLAG_HIDE_NAVIGATION and hide changes to this flag
178 | int globalVisibility = (Integer) param.args[1];
179 | int localValue = (Integer) param.args[2];
180 | param.args[1] = globalVisibility | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
181 | param.args[2] = localValue | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
182 | param.args[3] = localChanges & ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
183 | }
184 | });
185 | } catch (Throwable e) {
186 | XposedBridge.log(e);
187 | }
188 | }
189 |
190 | try {
191 | findAndHookMethod(Activity.class, "setRequestedOrientation", int.class, new XC_MethodHook() {
192 | @Override
193 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
194 | Integer orientation = (Integer) getAdditionalInstanceField(param.thisObject, PROP_ORIENTATION);
195 | if (orientation != null)
196 | param.args[0] = Common.orientationCodes[orientation];
197 | }
198 | });
199 | } catch (Throwable e) {
200 | XposedBridge.log(e);
201 | }
202 |
203 | try {
204 | // Hook one of the several variations of ActivityStack.realStartActivityLocked from different ROMs
205 | Method mthRealStartActivityLocked;
206 | if (Build.VERSION.SDK_INT <= 18) {
207 | try {
208 | mthRealStartActivityLocked = findMethodExact("com.android.server.am.ActivityStack", null, "realStartActivityLocked",
209 | "com.android.server.am.ActivityRecord", "com.android.server.am.ProcessRecord",
210 | boolean.class, boolean.class, boolean.class);
211 | } catch (NoSuchMethodError t) {
212 | mthRealStartActivityLocked = findMethodExact("com.android.server.am.ActivityStack", null, "realStartActivityLocked",
213 | "com.android.server.am.ActivityRecord", "com.android.server.am.ProcessRecord",
214 | boolean.class, boolean.class);
215 | }
216 | } else {
217 | mthRealStartActivityLocked = findMethodExact("com.android.server.am.ActivityStackSupervisor", null, "realStartActivityLocked",
218 | "com.android.server.am.ActivityRecord", "com.android.server.am.ProcessRecord",
219 | boolean.class, boolean.class);
220 | }
221 | hookMethod(mthRealStartActivityLocked, new XC_MethodHook() {
222 |
223 | @Override
224 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
225 | String pkgName = (String) getObjectField(param.args[0], "packageName");
226 | if (XposedMod.isActive(pkgName, Common.PREF_RESIDENT)) {
227 | int adj = -12;
228 | Object proc = getObjectField(param.args[0], "app");
229 |
230 | // Override the *Adj values if meant to be resident in memory
231 | if (proc != null) {
232 | setIntField(proc, "maxAdj", adj);
233 | if (Build.VERSION.SDK_INT <= 18)
234 | setIntField(proc, "hiddenAdj", adj);
235 | setIntField(proc, "curRawAdj", adj);
236 | setIntField(proc, "setRawAdj", adj);
237 | setIntField(proc, "curAdj", adj);
238 | setIntField(proc, "setAdj", adj);
239 | }
240 | }
241 | }
242 | });
243 | } catch (Throwable e) {
244 | XposedBridge.log(e);
245 | }
246 |
247 | try {
248 | hookAllConstructors(findClass("com.android.server.am.ActivityRecord", null), new XC_MethodHook() {
249 | @Override
250 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
251 | ActivityInfo aInfo = (ActivityInfo) getObjectField(param.thisObject, "info");
252 | if (aInfo == null)
253 | return;
254 | String pkgName = aInfo.packageName;
255 | if (XposedMod.prefs.getInt(pkgName + Common.PREF_RECENTS_MODE, Common.PREF_RECENTS_DEFAULT) > 0) {
256 | int recentsMode = XposedMod.prefs.getInt(pkgName + Common.PREF_RECENTS_MODE, Common.PREF_RECENTS_DEFAULT);
257 | if (recentsMode == Common.PREF_RECENTS_DEFAULT)
258 | return;
259 | Intent intent = (Intent) getObjectField(param.thisObject, "intent");
260 | if (recentsMode == Common.PREF_RECENTS_FORCE) {
261 | int flags = (intent.getFlags() & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
262 | intent.setFlags(flags);
263 | }
264 | else if (recentsMode == Common.PREF_RECENTS_PREVENT)
265 | intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
266 | }
267 | }
268 | });
269 | } catch (Throwable e) {
270 | XposedBridge.log(e);
271 | }
272 |
273 | try {
274 | findAndHookMethod(InputMethodService.class, "doStartInput",
275 | InputConnection.class, EditorInfo.class, boolean.class, new XC_MethodHook() {
276 | @Override
277 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
278 | EditorInfo info = (EditorInfo) param.args[1];
279 | if (info != null && info.packageName != null) {
280 | XposedMod.prefs.reload();
281 | if (XposedMod.isActive(info.packageName, Common.PREF_NO_FULLSCREEN_IME))
282 | info.imeOptions |= EditorInfo.IME_FLAG_NO_FULLSCREEN;
283 | }
284 | }
285 | });
286 | } catch (Throwable e) {
287 | XposedBridge.log(e);
288 | }
289 | }
290 | }
291 |
--------------------------------------------------------------------------------
/src/de/robv/android/xposed/mods/appsettings/hooks/PackagePermissions.java:
--------------------------------------------------------------------------------
1 | package de.robv.android.xposed.mods.appsettings.hooks;
2 |
3 | import static de.robv.android.xposed.XposedHelpers.callMethod;
4 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
5 | import static de.robv.android.xposed.XposedHelpers.findClass;
6 | import static de.robv.android.xposed.XposedHelpers.getObjectField;
7 | import static de.robv.android.xposed.XposedHelpers.setObjectField;
8 |
9 | import java.util.ArrayList;
10 | import java.util.Map;
11 | import java.util.Set;
12 |
13 | import android.content.BroadcastReceiver;
14 | import android.content.Context;
15 | import android.content.Intent;
16 | import android.content.IntentFilter;
17 | import android.content.pm.ApplicationInfo;
18 | import android.os.Build;
19 | import android.util.Log;
20 | import de.robv.android.xposed.XC_MethodHook;
21 | import de.robv.android.xposed.XposedBridge;
22 | import de.robv.android.xposed.mods.appsettings.Common;
23 | import de.robv.android.xposed.mods.appsettings.XposedMod;
24 |
25 | public class PackagePermissions extends BroadcastReceiver {
26 | private final Object pmSvc;
27 | private final Map mPackages;
28 | private final Object mSettings;
29 |
30 | @SuppressWarnings("unchecked")
31 | public PackagePermissions(Object pmSvc) {
32 | this.pmSvc = pmSvc;
33 | this.mPackages = (Map) getObjectField(pmSvc, "mPackages");
34 | this.mSettings = getObjectField(pmSvc, "mSettings");
35 | }
36 |
37 | public static void initHooks() {
38 | /* Hook to the PackageManager service in order to
39 | * - Listen for broadcasts to apply new settings and restart the app
40 | * - Intercept the permission granting function to remove disabled permissions
41 | */
42 | try {
43 | final Class> clsPMS = findClass("com.android.server.pm.PackageManagerService", XposedMod.class.getClassLoader());
44 |
45 | // Listen for broadcasts from the Settings part of the mod, so it's applied immediately
46 | findAndHookMethod(clsPMS, "systemReady", new XC_MethodHook() {
47 | @Override
48 | protected void afterHookedMethod(MethodHookParam param)
49 | throws Throwable {
50 | Context mContext = (Context) getObjectField(param.thisObject, "mContext");
51 | mContext.registerReceiver(new PackagePermissions(param.thisObject),
52 | new IntentFilter(Common.MY_PACKAGE_NAME + ".UPDATE_PERMISSIONS"),
53 | Common.MY_PACKAGE_NAME + ".BROADCAST_PERMISSION",
54 | null);
55 | }
56 | });
57 |
58 | // if the user has disabled certain permissions for an app, do as if the hadn't requested them
59 | findAndHookMethod(clsPMS, "grantPermissionsLPw", "android.content.pm.PackageParser$Package", boolean.class,
60 | new XC_MethodHook() {
61 | @SuppressWarnings("unchecked")
62 | @Override
63 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
64 | String pkgName = (String) getObjectField(param.args[0], "packageName");
65 | if (!XposedMod.isActive(pkgName) || !XposedMod.prefs.getBoolean(pkgName + Common.PREF_REVOKEPERMS, false))
66 | return;
67 |
68 | Set disabledPermissions = XposedMod.prefs.getStringSet(pkgName + Common.PREF_REVOKELIST, null);
69 | if (disabledPermissions == null || disabledPermissions.isEmpty())
70 | return;
71 |
72 | ArrayList origRequestedPermissions = (ArrayList) getObjectField(param.args[0], "requestedPermissions");
73 | param.setObjectExtra("orig_requested_permissions", origRequestedPermissions);
74 |
75 | ArrayList newRequestedPermissions = new ArrayList(origRequestedPermissions.size());
76 | for (String perm: origRequestedPermissions) {
77 | if (!disabledPermissions.contains(perm))
78 | newRequestedPermissions.add(perm);
79 | else
80 | // you requested those internet permissions? I didn't read that, sorry
81 | Log.w(Common.TAG, "Not granting permission " + perm
82 | + " to package " + pkgName
83 | + " because you think it should not have it");
84 | }
85 |
86 | setObjectField(param.args[0], "requestedPermissions", newRequestedPermissions);
87 | }
88 |
89 | @SuppressWarnings("unchecked")
90 | @Override
91 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
92 | // restore requested permissions if they were modified
93 | ArrayList origRequestedPermissions = (ArrayList) param.getObjectExtra("orig_requested_permissions");
94 | if (origRequestedPermissions != null)
95 | setObjectField(param.args[0], "requestedPermissions", origRequestedPermissions);
96 | }
97 | });
98 | } catch (Throwable e) {
99 | XposedBridge.log(e);
100 | }
101 | }
102 |
103 | @Override
104 | public void onReceive(Context context, Intent intent) {
105 | try {
106 | // The app broadcasted a request to update settings for a running app
107 |
108 | // Validate the action being requested
109 | if (!Common.ACTION_PERMISSIONS.equals(intent.getExtras().getString("action")))
110 | return;
111 |
112 | String pkgName = intent.getExtras().getString("Package");
113 | boolean killApp = intent.getExtras().getBoolean("Kill", false);
114 |
115 | XposedMod.prefs.reload();
116 |
117 | Object pkgInfo;
118 | synchronized (mPackages) {
119 | pkgInfo = mPackages.get(pkgName);
120 | callMethod(pmSvc, "grantPermissionsLPw", pkgInfo, true);
121 | callMethod(mSettings, "writeLPr");
122 | }
123 |
124 | // Apply new permissions if needed
125 | if (killApp) {
126 | try {
127 | ApplicationInfo appInfo = (ApplicationInfo) getObjectField(pkgInfo, "applicationInfo");
128 | if (Build.VERSION.SDK_INT <= 18)
129 | callMethod(pmSvc, "killApplication", pkgName, appInfo.uid);
130 | else
131 | callMethod(pmSvc, "killApplication", pkgName, appInfo.uid, "apply App Settings");
132 | } catch (Throwable t) {
133 | XposedBridge.log(t);
134 | }
135 | }
136 | } catch (Throwable t) {
137 | XposedBridge.log(t);
138 | }
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/src/de/robv/android/xposed/mods/appsettings/settings/LocaleList.java:
--------------------------------------------------------------------------------
1 | package de.robv.android.xposed.mods.appsettings.settings;
2 |
3 | import java.text.Collator;
4 | import java.util.Arrays;
5 | import java.util.List;
6 | import java.util.Locale;
7 |
8 | import android.content.res.Resources;
9 |
10 | /**
11 | * Manages a list of valid locales for the system
12 | */
13 | public class LocaleList {
14 |
15 | /*
16 | * From AOSP code - listing available languages to present to the user
17 | */
18 | private static class LocaleInfo implements Comparable {
19 | static final Collator sCollator = Collator.getInstance();
20 |
21 | String label;
22 | Locale locale;
23 |
24 | public LocaleInfo(String label, Locale locale) {
25 | this.label = label;
26 | this.locale = locale;
27 | }
28 |
29 | @Override
30 | public String toString() {
31 | return this.label;
32 | }
33 |
34 | @Override
35 | public int compareTo(LocaleInfo another) {
36 | return sCollator.compare(this.label, another.label);
37 | }
38 | }
39 |
40 | private String[] localeCodes;
41 | private String[] localeDescriptions;
42 |
43 | public LocaleList(String defaultLabel) {
44 | final String[] locales = Resources.getSystem().getAssets().getLocales();
45 | Arrays.sort(locales);
46 | final int origSize = locales.length;
47 | final LocaleInfo[] preprocess = new LocaleInfo[origSize];
48 | int finalSize = 0;
49 | for (int i = 0; i < origSize; i++) {
50 | final String s = locales[i];
51 | final int len = s.length();
52 | if (len == 5) {
53 | String language = s.substring(0, 2);
54 | String country = s.substring(3, 5);
55 | final Locale l = new Locale(language, country);
56 |
57 | if (finalSize == 0) {
58 | preprocess[finalSize++] = new LocaleInfo(toTitleCase(l.getDisplayLanguage(l)), l);
59 | } else {
60 | // check previous entry:
61 | // same lang and a country -> upgrade to full name and
62 | // insert ours with full name
63 | // diff lang -> insert ours with lang-only name
64 | if (preprocess[finalSize - 1].locale.getLanguage().equals(language)) {
65 | preprocess[finalSize - 1].label = toTitleCase(getDisplayName(preprocess[finalSize - 1].locale));
66 | preprocess[finalSize++] = new LocaleInfo(toTitleCase(getDisplayName(l)), l);
67 | } else {
68 | String displayName;
69 | if (s.equals("zz_ZZ")) {
70 | displayName = "Pseudo...";
71 | } else {
72 | displayName = toTitleCase(l.getDisplayLanguage(l));
73 | }
74 | preprocess[finalSize++] = new LocaleInfo(displayName, l);
75 | }
76 | }
77 | }
78 | }
79 |
80 | final LocaleInfo[] localeInfos = new LocaleInfo[finalSize];
81 | for (int i = 0; i < finalSize; i++) {
82 | localeInfos[i] = preprocess[i];
83 | }
84 | Arrays.sort(localeInfos);
85 |
86 | localeCodes = new String[localeInfos.length + 1];
87 | localeDescriptions = new String[localeInfos.length + 1];
88 | localeCodes[0] = "";
89 | localeDescriptions[0] = defaultLabel;
90 | for (int i = 1; i < finalSize + 1; i++) {
91 | localeCodes[i] = getLocaleCode(localeInfos[i - 1].locale);
92 | localeDescriptions[i] = localeInfos[i - 1].label;
93 | }
94 | }
95 |
96 | private static String toTitleCase(String s) {
97 | if (s.length() == 0) {
98 | return s;
99 | }
100 |
101 | return Character.toUpperCase(s.charAt(0)) + s.substring(1);
102 | }
103 |
104 | private static String getDisplayName(Locale loc) {
105 | return loc.getDisplayName(loc);
106 | }
107 |
108 | private static String getLocaleCode(Locale loc) {
109 | String result = loc.getLanguage();
110 | if (loc.getCountry().length() > 0)
111 | result += "_" + loc.getCountry();
112 | if (loc.getVariant().length() > 0)
113 | result += "_" + loc.getVariant();
114 | return result;
115 | }
116 |
117 | /**
118 | * Retrieve the locale code at a specific position in the list.
119 | */
120 | public String getLocale(int pos) {
121 | return localeCodes[pos];
122 | }
123 |
124 | /**
125 | * Retrieve the position where the specified locale code is, or 0 if it was
126 | * not found.
127 | */
128 | public int getLocalePos(String locale) {
129 | for (int i = 1; i < localeCodes.length; i++) {
130 | if (localeCodes[i].equals(locale))
131 | return i;
132 | }
133 | return 0;
134 | }
135 |
136 | /**
137 | * Retrieve an ordered list of the locale descriptions
138 | */
139 | public List getDescriptionList() {
140 | return Arrays.asList(localeDescriptions);
141 | }
142 |
143 | }
144 |
--------------------------------------------------------------------------------
/src/de/robv/android/xposed/mods/appsettings/settings/PermissionSettings.java:
--------------------------------------------------------------------------------
1 | package de.robv.android.xposed.mods.appsettings.settings;
2 |
3 | import java.util.Collections;
4 | import java.util.Comparator;
5 | import java.util.HashSet;
6 | import java.util.LinkedList;
7 | import java.util.List;
8 | import java.util.Set;
9 |
10 | import android.annotation.SuppressLint;
11 | import android.app.Activity;
12 | import android.app.Dialog;
13 | import android.content.pm.PackageInfo;
14 | import android.content.pm.PackageManager;
15 | import android.content.pm.PackageManager.NameNotFoundException;
16 | import android.content.pm.PermissionInfo;
17 | import android.graphics.Color;
18 | import android.view.View;
19 | import android.widget.Button;
20 | import android.widget.CompoundButton;
21 | import android.widget.ListView;
22 | import android.widget.Switch;
23 | import de.robv.android.xposed.mods.appsettings.R;
24 |
25 |
26 | /**
27 | * Manages a popup dialog for editing the Permission Revoking settings for a package
28 | */
29 | public class PermissionSettings {
30 | private Dialog dialog;
31 |
32 | private OnDismissListener onOkListener;
33 | private OnDismissListener onCancelListener;
34 |
35 | boolean revokeActive;
36 | private Set disabledPerms;
37 |
38 | private List permsList = new LinkedList();
39 |
40 | /**
41 | * Prepare a dialog for editing the permissions for the supplied package,
42 | * with the provided owner activity and initial settings
43 | */
44 | public PermissionSettings(Activity owner, String pkgName, boolean revoking, Set disabledPermissions) throws NameNotFoundException {
45 | dialog = new Dialog(owner);
46 | dialog.setContentView(R.layout.permissions_dialog);
47 | dialog.setTitle(R.string.perms_title);
48 | dialog.setCancelable(true);
49 | dialog.setOwnerActivity(owner);
50 |
51 | revokeActive = revoking;
52 | if (disabledPermissions != null)
53 | disabledPerms = new HashSet(disabledPermissions);
54 | else
55 | disabledPerms = new HashSet();
56 |
57 | Switch swtRevoke = (Switch) dialog.findViewById(R.id.swtRevokePerms);
58 | swtRevoke.setChecked(revokeActive);
59 |
60 | // Load the list of permissions for the package and present them
61 | loadPermissionsList(pkgName);
62 |
63 | final PermissionsListAdapter appListAdapter = new PermissionsListAdapter(owner, permsList, disabledPerms, true);
64 | appListAdapter.setCanEdit(revokeActive);
65 | ((ListView) dialog.findViewById(R.id.lstPermissions)).setAdapter(appListAdapter);
66 |
67 | // Track changes to the Revoke checkbox to lock or unlock the list of
68 | // permissions
69 | swtRevoke.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
70 | @Override
71 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
72 | revokeActive = isChecked;
73 | dialog.findViewById(R.id.lstPermissions).setBackgroundColor(revokeActive ? Color.BLACK : Color.DKGRAY);
74 | appListAdapter.setCanEdit(revokeActive);
75 | }
76 | });
77 | dialog.findViewById(R.id.lstPermissions).setBackgroundColor(revokeActive ? Color.BLACK : Color.DKGRAY);
78 |
79 | ((Button) dialog.findViewById(R.id.btnPermsCancel)).setOnClickListener(new View.OnClickListener() {
80 | @Override
81 | public void onClick(View v) {
82 | if (onCancelListener != null)
83 | onCancelListener.onDismiss(PermissionSettings.this);
84 | dialog.dismiss();
85 | }
86 | });
87 | ((Button) dialog.findViewById(R.id.btnPermsOk)).setOnClickListener(new View.OnClickListener() {
88 | @Override
89 | public void onClick(View v) {
90 | if (onOkListener != null)
91 | onOkListener.onDismiss(PermissionSettings.this);
92 | dialog.dismiss();
93 | }
94 | });
95 | }
96 |
97 | /**
98 | * Display the editor dialog
99 | */
100 | public void display() {
101 | dialog.show();
102 | }
103 |
104 | /**
105 | * Register a listener to be invoked when the editor is dismissed with the
106 | * Ok button
107 | */
108 | public void setOnOkListener(OnDismissListener listener) {
109 | onOkListener = listener;
110 | }
111 |
112 | /**
113 | * Register a listener to be invoked when the editor is dismissed with the
114 | * Cancel button
115 | */
116 | public void setOnCancelListener(OnDismissListener listener) {
117 | onCancelListener = listener;
118 | }
119 |
120 | /**
121 | * Get the state of the Active switch
122 | */
123 | public boolean getRevokeActive() {
124 | return revokeActive;
125 | }
126 |
127 | /**
128 | * Get the list of permissions in the disabled state
129 | */
130 | public Set getDisabledPermissions() {
131 | return new HashSet(disabledPerms);
132 | }
133 |
134 | /*
135 | * Populate the list of permissions requested by this package
136 | */
137 | @SuppressLint("DefaultLocale")
138 | private void loadPermissionsList(String pkgName) throws NameNotFoundException {
139 | permsList.clear();
140 |
141 | PackageManager pm = dialog.getContext().getPackageManager();
142 | PackageInfo pkgInfo = pm.getPackageInfo(pkgName, PackageManager.GET_PERMISSIONS);
143 | if (pkgInfo.sharedUserId != null) {
144 | Switch swtRevoke = (Switch) dialog.findViewById(R.id.swtRevokePerms);
145 | swtRevoke.setText(R.string.perms_shared_warning);
146 | swtRevoke.setTextColor(Color.RED);
147 | }
148 | String[] permissions = pkgInfo.requestedPermissions;
149 | if (permissions == null) {
150 | permissions = new String[0];
151 | }
152 | for (String perm : permissions) {
153 | try {
154 | permsList.add(pm.getPermissionInfo(perm, 0));
155 | } catch (NameNotFoundException e) {
156 | PermissionInfo unknownPerm = new PermissionInfo();
157 | unknownPerm.name = perm;
158 | permsList.add(unknownPerm);
159 | }
160 | }
161 |
162 | Collections.sort(permsList, new Comparator() {
163 | @Override
164 | public int compare(PermissionInfo lhs, PermissionInfo rhs) {
165 | if (lhs.name == null) {
166 | return -1;
167 | } else if (rhs.name == null) {
168 | return 1;
169 | } else {
170 | return lhs.name.toUpperCase().compareTo(rhs.name.toUpperCase());
171 | }
172 | }
173 | });
174 | }
175 |
176 | /**
177 | * Interface for the listeners of Ok/Cancel dismiss actions
178 | */
179 | public static interface OnDismissListener {
180 |
181 | public abstract void onDismiss(PermissionSettings obj);
182 | }
183 |
184 | }
185 |
--------------------------------------------------------------------------------
/src/de/robv/android/xposed/mods/appsettings/settings/PermissionsListAdapter.java:
--------------------------------------------------------------------------------
1 | package de.robv.android.xposed.mods.appsettings.settings;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import java.util.Set;
6 |
7 | import android.app.Activity;
8 | import android.content.pm.PackageManager;
9 | import android.content.pm.PermissionInfo;
10 | import android.graphics.Color;
11 | import android.graphics.Paint;
12 | import android.view.View;
13 | import android.view.ViewGroup;
14 | import android.widget.ArrayAdapter;
15 | import android.widget.Filter;
16 | import android.widget.Filterable;
17 | import android.widget.TextView;
18 | import de.robv.android.xposed.mods.appsettings.R;
19 |
20 | /*
21 | * Adapter to feed the list of permission entries
22 | */
23 | public class PermissionsListAdapter extends ArrayAdapter implements Filterable {
24 |
25 | Activity context;
26 | private List originalPermsList;
27 | private Set disabledPerms;
28 | private boolean allowEdits;
29 | private boolean canEdit;
30 | private Filter mFilter;
31 |
32 | public PermissionsListAdapter(Activity context, List items, Set disabledPerms, boolean allowEdits) {
33 | super(context, R.layout.app_permission_item, items);
34 | this.context = context;
35 | originalPermsList = new ArrayList(items);
36 | this.disabledPerms = disabledPerms;
37 | this.allowEdits = allowEdits;
38 | canEdit = false;
39 | }
40 |
41 | public void setCanEdit(boolean canEdit) {
42 | this.canEdit = canEdit;
43 | }
44 |
45 | private class ViewHolder {
46 | TextView tvName;
47 | TextView tvDescription;
48 | }
49 |
50 | public View getView(int position, View convertView, ViewGroup parent) {
51 | View row = convertView;
52 | ViewHolder vHolder;
53 | if (row == null) {
54 | row = context.getLayoutInflater().inflate(R.layout.app_permission_item, parent, false);
55 | vHolder = new ViewHolder();
56 | vHolder.tvName = (TextView) row.findViewById(R.id.perm_name);
57 | vHolder.tvDescription = (TextView) row.findViewById(R.id.perm_description);
58 | row.setTag(vHolder);
59 | } else {
60 | vHolder = (ViewHolder) row.getTag();
61 | }
62 |
63 | PermissionInfo perm = getItem(position);
64 | PackageManager pm = context.getPackageManager();
65 |
66 | CharSequence label = perm.loadLabel(pm);
67 | if (!label.equals(perm.name)) {
68 | label = perm.name + " (" + label + ")";
69 | }
70 |
71 | vHolder.tvName.setText(label);
72 | CharSequence description = perm.loadDescription(pm);
73 | description = (description == null) ? "" : description.toString().trim();
74 | if (description.length() == 0)
75 | description = context.getString(R.string.perms_nodescription);
76 | vHolder.tvDescription.setText(description);
77 | switch (perm.protectionLevel) {
78 | case PermissionInfo.PROTECTION_DANGEROUS:
79 | vHolder.tvDescription.setTextColor(Color.RED);
80 | break;
81 | case PermissionInfo.PROTECTION_SIGNATURE:
82 | vHolder.tvDescription.setTextColor(Color.GREEN);
83 | break;
84 | case PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM:
85 | vHolder.tvDescription.setTextColor(Color.YELLOW);
86 | break;
87 | default:
88 | vHolder.tvDescription.setTextColor(Color.parseColor("#0099CC"));
89 | break;
90 | }
91 |
92 | vHolder.tvName.setTag(perm.name);
93 | if (disabledPerms.contains(perm.name)) {
94 | vHolder.tvName.setPaintFlags(vHolder.tvName.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
95 | vHolder.tvName.setTextColor(Color.MAGENTA);
96 | } else {
97 | vHolder.tvName.setPaintFlags(vHolder.tvName.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG));
98 | vHolder.tvName.setTextColor(Color.WHITE);
99 | }
100 | if (allowEdits) {
101 | row.setOnClickListener(new View.OnClickListener() {
102 | @Override
103 | public void onClick(View v) {
104 | if (!canEdit) {
105 | return;
106 | }
107 |
108 | TextView tv = (TextView) v.findViewById(R.id.perm_name);
109 | if ((tv.getPaintFlags() & Paint.STRIKE_THRU_TEXT_FLAG) != 0) {
110 | disabledPerms.remove(tv.getTag());
111 | tv.setPaintFlags(tv.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG));
112 | tv.setTextColor(Color.WHITE);
113 | } else {
114 | disabledPerms.add((String) tv.getTag());
115 | tv.setPaintFlags(tv.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
116 | tv.setTextColor(Color.MAGENTA);
117 | }
118 | }
119 | });
120 | }
121 |
122 | return row;
123 | }
124 |
125 | @Override
126 | public Filter getFilter() {
127 | if (mFilter == null) {
128 | mFilter = new CustomFilter();
129 | }
130 | return mFilter;
131 | }
132 |
133 | /* Filter permissions by name, label or description based on contained text */
134 | private class CustomFilter extends Filter {
135 |
136 | private boolean matches(CharSequence value, CharSequence filter) {
137 | return (value != null && value.toString().toLowerCase().contains(filter));
138 | }
139 |
140 | @Override
141 | protected FilterResults performFiltering(CharSequence constraint) {
142 | FilterResults result = new FilterResults();
143 | ArrayList items = new ArrayList();
144 | if (constraint == null || constraint.length() == 0) {
145 | items.addAll(originalPermsList);
146 | } else {
147 | String findText = constraint.toString().toLowerCase();
148 | PackageManager pm = context.getPackageManager();
149 | for (PermissionInfo p : originalPermsList) {
150 | if (matches(p.name, findText) || matches(p.loadLabel(pm), findText) || matches(p.loadDescription(pm), findText)) {
151 | items.add(p);
152 | }
153 | }
154 | }
155 | result.values = items;
156 | result.count = items.size();
157 | return result;
158 | }
159 |
160 | @Override
161 | protected void publishResults(CharSequence constraint, FilterResults results) {
162 | clear();
163 | addAll((List) results.values);
164 | notifyDataSetChanged();
165 | }
166 |
167 | }
168 |
169 | }
170 |
--------------------------------------------------------------------------------