├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.yaml
│ ├── feature_request.yaml
│ └── question.yaml
├── dependabot.yml
└── workflows
│ └── build.yaml
├── .gitignore
├── .idea
├── .gitignore
├── AndroidProjectSystem.xml
├── appInsightsSettings.xml
├── codeStyles
│ ├── Project.xml
│ └── codeStyleConfig.xml
├── compiler.xml
├── deploymentTargetDropDown.xml
├── deploymentTargetSelector.xml
├── gradle.xml
├── inspectionProfiles
│ └── Project_Default.xml
├── kotlinc.xml
├── misc.xml
├── qaplug_profiles.xml
├── runConfigurations.xml
└── vcs.xml
├── CONTRIBUTING.md
├── CONTRIBUTING_pt-BR.md
├── CONTRIBUTING_zh-CN.md
├── LICENSE
├── README.md
├── README_en.md
├── README_pt-BR.md
├── app
├── .gitignore
├── build.gradle.kts
├── key.jks
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── assets
│ └── xposed_init
│ ├── kotlin
│ └── top
│ │ └── ltfan
│ │ └── notdeveloper
│ │ ├── Item.kt
│ │ ├── ui
│ │ ├── activity
│ │ │ └── MainActivity.kt
│ │ ├── composable
│ │ │ ├── PreferenceItem.kt
│ │ │ ├── SharedPreference.kt
│ │ │ └── StatusCard.kt
│ │ └── theme
│ │ │ └── Theme.kt
│ │ ├── util
│ │ └── SystemUtil.kt
│ │ └── xposed
│ │ ├── Hook.kt
│ │ ├── Log.kt
│ │ └── ModuleStatus.kt
│ └── res
│ ├── drawable-v24
│ └── ic_launcher_foreground.xml
│ ├── drawable
│ └── ic_launcher_background.xml
│ ├── mipmap-anydpi-v26
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-mdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── values-night
│ └── themes.xml
│ ├── values-pt-rBR
│ └── strings.xml
│ ├── values-zh-rCN
│ └── strings.xml
│ ├── values
│ ├── strings.xml
│ └── themes.xml
│ └── xml
│ ├── backup_rules.xml
│ └── data_extraction_rules.xml
├── build.gradle.kts
├── gradle.properties
├── gradle
├── libs.versions.toml
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle.kts
/.github/ISSUE_TEMPLATE/bug_report.yaml:
--------------------------------------------------------------------------------
1 | name: Bug report
2 | description: Create a report to help us improve
3 | title: '[Bug] '
4 | labels: ['bug']
5 | assignees:
6 | - xfqwdsj
7 | body:
8 | - type: markdown
9 | attributes:
10 | value: |
11 | *(For Chinese users)* **Issue标题请使用英文,内容可用中文**
12 | - type: checkboxes
13 | id: searched_existing_issues
14 | attributes:
15 | label: Existing Issues Search Confirmation
16 | description: Please confirm you have searched for existing issues before submitting a new one.
17 | options:
18 | - label: I have searched for existing issues and did not find a similar one.
19 | required: true
20 | - type: textarea
21 | id: bug_description
22 | attributes:
23 | label: Bug Description
24 | description: Clearly describe the bug.
25 | placeholder: e.g., App crashes on launch
26 | validations:
27 | required: true
28 | - type: textarea
29 | id: steps_to_reproduce
30 | attributes:
31 | label: Steps to Reproduce
32 | description: Provide step-by-step instructions to reproduce the issue.
33 | placeholder: e.g., 1. Open the app 2. Tap on 'Hide USB debugging' 3. Observe crash
34 | validations:
35 | required: true
36 | - type: textarea
37 | id: expected_behavior
38 | attributes:
39 | label: Expected Behavior
40 | description: Describe what you expected to happen.
41 | placeholder: e.g., The switch state changed without crashing
42 | validations:
43 | required: true
44 | - type: markdown
45 | attributes:
46 | value: |
47 | **How to provide screenshots correctly?**
48 |
49 | Since a screenshot may be too long to read, please use the following format to provide screenshots:
50 |
51 | ```markdown
52 | Screenshots
53 |
54 |
55 | ```
56 | - type: textarea
57 | id: screenshots
58 | attributes:
59 | label: Screenshots
60 | description: Attach screenshots to help illustrate the issue.
61 | placeholder: Follow the format above to provide screenshots
62 | - type: textarea
63 | id: device_info
64 | attributes:
65 | label: Device Details
66 | description: Provide device and OS details.
67 | placeholder: |
68 | e.g., Device: Xiaomi 14, OS: Xiaomi Hyper OS 1.0.23.12.4.DEV; Android 14
69 | validations:
70 | required: true
71 | - type: markdown
72 | attributes:
73 | value: |
74 | **How to provide logs correctly?**
75 |
76 | Since logs can be lengthy, please refer to the following guidance to provide logs:
77 |
78 | - **Option 1**: Paste the log file directly in the text area below.
79 | - **Option 2**: Use the following format to provide log text:
80 |
81 | ````markdown
82 | Logs
83 |
84 | ```
85 |
86 | ```
87 |
88 | ````
89 |
90 | This helps us diagnose the issue more effectively.
91 | - type: textarea
92 | id: logs
93 | attributes:
94 | label: Logs
95 | description: Provide logs to help diagnose the issue.
96 | placeholder: Refer to the guidance above to provide logs
97 | validations:
98 | required: true
99 | - type: textarea
100 | id: additional_context
101 | attributes:
102 | label: Additional Context
103 | description: Add any other relevant information.
104 | placeholder: e.g., Related issues
105 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.yaml:
--------------------------------------------------------------------------------
1 | name: Feature request
2 | description: Suggest an idea for this project
3 | title: '[Feature] '
4 | labels: ['enhancement']
5 | assignees:
6 | - xfqwdsj
7 | body:
8 | - type: markdown
9 | attributes:
10 | value: |
11 | *(For Chinese users)* **Issue标题请使用英文,内容可用中文**
12 | - type: checkboxes
13 | id: searched_existing_issues
14 | attributes:
15 | label: Existing Issues Search Confirmation
16 | description: Please confirm you have searched for existing issues before submitting a new one.
17 | options:
18 | - label: I have searched for existing issues and did not find a similar one.
19 | required: true
20 | - type: textarea
21 | id: problem_description
22 | attributes:
23 | label: Problem Description
24 | description: Clearly describe the problem you want to solve.
25 | placeholder: e.g., Difficulty navigating settings
26 | validations:
27 | required: true
28 | - type: textarea
29 | id: solution_description
30 | attributes:
31 | label: Proposed Solution
32 | description: Describe your proposed solution in detail.
33 | placeholder: e.g., Add a search bar in settings
34 | validations:
35 | required: true
36 | - type: textarea
37 | id: expected_behavior
38 | attributes:
39 | label: Expected Behavior
40 | description: Describe what you expect to happen after the feature is implemented.
41 | placeholder: e.g., Users can quickly find settings using the search bar
42 | validations:
43 | required: true
44 | - type: textarea
45 | id: alternatives
46 | attributes:
47 | label: Alternatives Considered
48 | description: Describe any alternative solutions or features you've considered.
49 | placeholder: e.g., Group settings into categories
50 | - type: markdown
51 | attributes:
52 | value: |
53 | **How to provide images correctly?**
54 |
55 | Since an image may be too long to read, please use the following format to provide images:
56 |
57 | ```markdown
58 | Images
59 |
60 |
61 | ```
62 | - type: textarea
63 | id: images
64 | attributes:
65 | label: Images
66 | description: Attach images or screenshots to support your feature request.
67 | placeholder: Follow the format above to provide images
68 | - type: textarea
69 | id: additional_context
70 | attributes:
71 | label: Additional Context
72 | description: Add any other relevant information (e.g., logs, related issues, references).
73 | placeholder: e.g., Related issues, logs, references
74 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/question.yaml:
--------------------------------------------------------------------------------
1 | name: Question?
2 | description: Please ask a question using Discussions
3 | title: Question
4 | labels: ['question']
5 | assignees:
6 | - xfqwdsj
7 | body:
8 | - type: markdown
9 | attributes:
10 | value: |
11 | *For questions, please use [Discussions](https://github.com/xfqwdsj/IAmNotADeveloper/discussions) and don't submit an issue.*
12 | - type: checkboxes
13 | id: read
14 | attributes:
15 | label: Read the text above
16 | description: Please confirm you have read the text above.
17 | options:
18 | - label: I have read the text above and will not submit an issue for a question.
19 | required: true
20 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5 |
6 | version: 2
7 | updates:
8 | - package-ecosystem: "gradle" # See documentation for possible values
9 | directory: "/" # Location of package manifests
10 | schedule:
11 | interval: "daily"
12 |
--------------------------------------------------------------------------------
/.github/workflows/build.yaml:
--------------------------------------------------------------------------------
1 | name: Building Release
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request:
8 | branches:
9 | - main
10 |
11 | jobs:
12 | build:
13 | runs-on: ubuntu-latest
14 |
15 | steps:
16 | - name: Checkout
17 | uses: actions/checkout@v4
18 | - name: Set up JDK
19 | uses: actions/setup-java@v4
20 | with:
21 | distribution: temurin
22 | java-version: '19'
23 | - name: Set up cache
24 | uses: actions/cache@v4
25 | with:
26 | path: |
27 | ~/.gradle/caches
28 | ~/.gradle/wrapper
29 | key: ${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }}-${{ hashFiles('**/buildSrc/**/*.kt') }}
30 | - name: Build
31 | run: |
32 | chmod +x ./gradlew
33 | ./gradlew assembleRelease
34 | - name: Upload artifact
35 | uses: actions/upload-artifact@v4
36 | with:
37 | name: NotDeveloper-${{ github.sha }}
38 | path: app/build/outputs/apk/release/app-release.apk
39 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 | local.properties
16 | /.kotlin/
17 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/AndroidProjectSystem.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/appInsightsSettings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
25 |
26 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | xmlns:android
53 |
54 | ^$
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | xmlns:.*
64 |
65 | ^$
66 |
67 |
68 | BY_NAME
69 |
70 |
71 |
72 |
73 |
74 |
75 | .*:id
76 |
77 | http://schemas.android.com/apk/res/android
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 | .*:name
87 |
88 | http://schemas.android.com/apk/res/android
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 | name
98 |
99 | ^$
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | style
109 |
110 | ^$
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 | .*
120 |
121 | ^$
122 |
123 |
124 | BY_NAME
125 |
126 |
127 |
128 |
129 |
130 |
131 | .*
132 |
133 | http://schemas.android.com/apk/res/android
134 |
135 |
136 | ANDROID_ATTRIBUTE_ORDER
137 |
138 |
139 |
140 |
141 |
142 |
143 | .*
144 |
145 | .*
146 |
147 |
148 | BY_NAME
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/deploymentTargetDropDown.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/deploymentTargetSelector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/.idea/kotlinc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/.idea/qaplug_profiles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
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 |
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 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 |
722 |
723 |
724 |
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 |
733 |
734 |
735 |
736 |
737 |
738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 |
746 |
747 |
748 |
749 |
750 |
751 |
752 |
753 |
754 |
755 |
756 |
757 |
758 |
759 |
760 |
761 |
762 |
763 |
764 |
765 |
766 |
767 |
768 |
769 |
770 |
771 |
772 |
773 |
774 |
775 |
776 |
777 |
778 |
779 |
780 |
781 |
782 |
783 |
784 |
785 |
786 |
787 |
788 |
789 |
790 |
791 |
792 |
793 |
794 |
795 |
796 |
797 |
798 |
799 |
800 |
801 |
802 |
803 |
804 |
805 |
806 |
807 |
808 |
809 |
810 |
811 |
812 |
813 |
814 |
815 |
816 |
817 |
818 |
819 |
820 |
821 |
822 |
823 |
824 |
825 |
826 |
827 |
828 |
829 |
830 |
831 |
832 |
833 |
834 |
835 |
836 |
837 |
838 |
839 |
840 |
841 |
842 |
843 |
844 |
845 |
846 |
847 |
848 |
849 |
850 |
851 |
852 |
853 |
854 |
855 |
856 |
857 |
858 |
859 |
860 |
861 |
862 |
863 |
864 |
865 |
866 |
867 |
868 |
869 |
870 |
871 |
872 |
873 |
874 |
875 |
876 |
877 |
878 |
879 |
880 |
881 |
882 |
883 |
884 |
885 |
886 |
887 |
888 |
889 |
890 |
891 |
892 |
893 |
894 |
895 |
896 |
897 |
898 |
899 |
900 |
901 |
902 |
903 |
904 |
905 |
906 |
907 |
908 |
909 |
910 |
911 |
912 |
913 |
914 |
915 |
916 |
917 |
918 |
919 |
920 |
921 |
922 |
923 |
924 |
925 |
926 |
927 |
928 |
929 |
930 |
931 |
932 |
933 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | **English** | [简体中文](CONTRIBUTING_zh-CN.md) | [Português (Brasil)](CONTRIBUTING_pt-BR.md)
2 |
3 | # Contributing Guide
4 |
5 | Thank you for your interest in contributing to this project! Please follow the steps below to get started:
6 |
7 | ## How to Contribute
8 |
9 | 1. **Fork this repository**
10 |
11 | Click the Fork button at the top right corner to fork this project to your GitHub account.
12 |
13 | 2. **Create a branch**
14 |
15 | Clone your fork locally and create a new branch based on `main` for your development. Suggested branch names: `feature/xxx`, `fix/xxx`, etc.
16 |
17 | 3. **Make changes**
18 |
19 | Keep your commit history clear and concise. Please write meaningful commit messages for each change.
20 |
21 | 4. **Push your branch and open a Pull request**
22 |
23 | Push your branch to GitHub and open a [Pull request (PR)](https://github.com/xfqwdsj/IAmNotADeveloper/pulls) in this repository. Please describe your changes and the motivation in detail in the PR description.
24 |
25 | 5. **Code review**
26 |
27 | Maintainers will review your PR and may suggest changes. Please respond promptly and make adjustments as needed.
28 |
29 | 6. **Merge and release**
30 |
31 | After approval, maintainers will merge your changes. Your contribution will appear in the next release.
32 |
33 | ## Contribution Tips
34 |
35 | - Follow the project's code style and conventions.
36 | - Ensure local build and tests pass before submitting.
37 | - Update relevant documentation if your changes affect docs.
38 | - For large or breaking changes, discuss first in [Issues](https://github.com/xfqwdsj/IAmNotADeveloper/issues).
39 |
40 | ## Reporting Issues
41 |
42 | To report bugs or suggest new features, please submit them in [Issues](https://github.com/xfqwdsj/IAmNotADeveloper/issues) with as much detail as possible (logs, screenshots, etc.).
43 |
44 | ## Contact
45 |
46 | If you have questions, contact us via [Issues](https://github.com/xfqwdsj/IAmNotADeveloper/issues) or [Discussions](https://github.com/xfqwdsj/IAmNotADeveloper/discussions).
47 |
--------------------------------------------------------------------------------
/CONTRIBUTING_pt-BR.md:
--------------------------------------------------------------------------------
1 | [English](CONTRIBUTING.md) | [简体中文](CONTRIBUTING_zh-CN.md) | **Português (Brasil)**
2 |
3 | # Guia de contribuição
4 |
5 | Agradecemos seu interesse em contribuir com este projeto! Siga os passos abaixo para começar:
6 |
7 | ## Como contribuir
8 |
9 | 1. **Faça um fork deste repositório**
10 |
11 | Clique no botão Fork no canto superior direito para bifurcar este projeto para sua conta do GitHub.
12 |
13 | 2. **Crie uma branch**
14 |
15 | Clone seu fork localmente e crie uma nova branch baseada em `main` para o seu desenvolvimento. Nomes de branch sugeridos: `feature/xxx`, `fix/xxx`, etc.
16 |
17 | 3. **Faça as alterações**
18 |
19 | Mantenha seu histórico de commits claro e conciso. Escreva mensagens de commit significativas para cada alteração.
20 |
21 | 4. **Envie sua branch e abra um Pull request**
22 |
23 | Envie sua branch para o GitHub e abra um [Pull request (PR)](https://github.com/xfqwdsj/IAmNotADeveloper/pulls) neste repositório. Descreva suas alterações e a motivação em detalhes na descrição do PR.
24 |
25 | 5. **Revisão de código**
26 |
27 | Os mantenedores analisarão seu PR e poderão sugerir alterações. Responda prontamente e faça os ajustes necessários.
28 |
29 | 6. **Mesclar e lançar**
30 |
31 | Após a aprovação, os mantenedores mesclarão suas alterações. Sua contribuição aparecerá na próxima versão.
32 |
33 | ## Dicas de contribuição
34 |
35 | - Siga o estilo e as convenções do código do projeto.
36 | - Garanta que a compilação e os testes locais sejam aprovados antes do envio.
37 | - Atualize a documentação relevante se suas alterações afetarem os documentos.
38 | - Para mudanças grandes ou significativas, discuta primeiro em [Issues](https://github.com/xfqwdsj/IAmNotADeveloper/issues).
39 |
40 | ## Relatando problemas
41 |
42 | Para relatar bugs ou sugerir novos recursos, envie-os em [Issues](https://github.com/xfqwdsj/IAmNotADeveloper/issues) com o máximo de detalhes possível (logs, capturas de tela, etc.).
43 |
44 | ## Contato
45 |
46 | Se você tiver dúvidas, entre em contato via [Issues](https://github.com/xfqwdsj/IAmNotADeveloper/issues) ou [Discussions](https://github.com/xfqwdsj/IAmNotADeveloper/discussions).
47 |
--------------------------------------------------------------------------------
/CONTRIBUTING_zh-CN.md:
--------------------------------------------------------------------------------
1 | [English](CONTRIBUTING.md) | **简体中文** | [Português (Brasil)](CONTRIBUTING_pt-BR.md)
2 |
3 | # 贡献指南
4 |
5 | 感谢你有意为本项目做出贡献!请按照以下步骤参与贡献:
6 |
7 | ## 如何贡献
8 |
9 | 1. **Fork本仓库**
10 |
11 | 点击右上角的Fork按钮,将本项目Fork到你的GitHub账户下。
12 |
13 | 2. **创建分支**
14 |
15 | 在本地克隆你的Fork,并基于`main`分支创建新分支进行开发。分支命名建议:`feature/xxx`、`fix/xxx`等。
16 |
17 | 3. **提交更改**
18 |
19 | 保持提交记录清晰、简洁。每次提交请编写有意义的提交信息。
20 |
21 | 4. **推送分支并发起Pull request**
22 |
23 | 将你的分支推送到GitHub,并在本仓库发起[Pull request(简称PR)](https://github.com/xfqwdsj/IAmNotADeveloper/pulls)。请在PR描述中详细说明你的更改内容和动机。
24 |
25 | 5. **代码评审**
26 |
27 | 维护者会对你的PR进行评审,可能会提出修改建议。请及时响应并根据建议进行调整。
28 |
29 | 6. **合并与发布**
30 |
31 | 通过评审后,维护者会合并你的更改。你的贡献将出现在下一个版本中。
32 |
33 | ## 贡献建议
34 |
35 | - 遵循项目的代码风格和规范。
36 | - 提交前请确保本地构建和测试通过。
37 | - 如涉及文档变更,请同步更新相关文档。
38 | - 对于较大或破坏性更改,建议先在[Issues](https://github.com/xfqwdsj/IAmNotADeveloper/issues)区讨论。
39 |
40 | ## 问题反馈
41 |
42 | 如需报告Bug或建议新功能,请在[Issues](https://github.com/xfqwdsj/IAmNotADeveloper/issues)区提交,并尽量提供详细信息(如日志、截图等)。
43 |
44 | ## 联系方式
45 |
46 | 如有疑问,可通过[Issues](https://github.com/xfqwdsj/IAmNotADeveloper/issues)或[Discussions](https://github.com/xfqwdsj/IAmNotADeveloper/discussions)与我们联系。
47 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 LTFan
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://deepwiki.com/xfqwdsj/IAmNotADeveloper)
2 |
3 | **简体中文** | [English](README_en.md) | [Português (Brasil)](README_pt-BR.md)
4 |
5 | # 我不是开发者
6 |
7 | 一个用于隐藏Android系统开发者相关选项状态的模块。
8 |
9 | ## FAQ
10 |
11 | ### Q: 我激活了模块,但模块报告“未激活”,这是怎么回事?
12 |
13 | 排查步骤:
14 |
15 | 1. 确认您已经激活了模块。
16 | 2. 确认您在成功激活模块后,强行停止了模块应用。
17 | 3. 在[Issues](https://github.com/xfqwdsj/IAmNotADeveloper/issues)中搜索相关问题。
18 | 4. 如果没有找到相关问题,请先抓取日志并对模块应用截图,确保包含完整的模块状态卡片(如果无法在一张截图中包含,请分多张截图)。
19 | 5. 在[Issues](https://github.com/xfqwdsj/IAmNotADeveloper/issues)中提交新问题,并上传日志。
20 |
21 | ### Q: 如何确认LSPosed中,模块已经激活?
22 |
23 | 您可以通过以下步骤确认:
24 |
25 | 1. 通过任意方式启动LSPosed管理器。
26 | 2. 在“模块”页面中,找到“我不是开发者”模块。
27 | 3. 确认“启用模块”开关处于开启状态。
28 |
29 | ### Q: 如何抓取日志?
30 |
31 | 您可以通过以下步骤抓取日志:
32 |
33 | 1. 通过任意方式启动LSPosed管理器。
34 | 2. 在“日志”页面中,点击右上角的“保存”图标按钮。
35 | 3. 选择一个合适的保存位置,如“下载内容”,不要修改文件名。
36 | 4. 点击“保存”按钮。
37 |
38 | ### Q: 我对某应用程序激活了模块,但是应用程序崩溃了/没有任何效果/被检测器应用检测到了,怎么办?
39 |
40 | 本模块的实现方式为直接注入目标应用程序,对于内置注入防护的应用程序,模块可能会不起作用,甚至会使应用拒绝工作。
41 |
42 | 解决方案:无。[#104](https://github.com/xfqwdsj/IAmNotADeveloper/issues/104)已经立项,您可以耐心等待,没有预计完成时间。**请不要提交关于此问题的任何Issue,它将会被直接关闭。**
43 |
44 | ## 如何贡献
45 |
46 | 如果您想为本项目贡献代码,请参考[CONTRIBUTING.md](CONTRIBUTING_zh-CN.md)。
47 |
48 | ## 隐私协议
49 |
50 | 本应用的“测试”功能会获取您对应系统开关的状态,包括:
51 |
52 | - 开发者模式
53 | - USB 调试
54 | - 无线调试
55 |
56 | 但是本应用不会收集您的任何信息。
57 |
--------------------------------------------------------------------------------
/README_en.md:
--------------------------------------------------------------------------------
1 | [](https://deepwiki.com/xfqwdsj/IAmNotADeveloper)
2 |
3 | [简体中文](README.md) | **English** | [Português (Brasil)](README_pt-BR.md)
4 |
5 | # IAmNotADeveloper
6 |
7 | A module for hiding the status of Android system developer options.
8 |
9 | ## FAQ
10 |
11 | ### Q: I have activated the module, but it reports "Module not activated". What should I do?
12 |
13 | Troubleshooting steps:
14 |
15 | 1. Make sure you have activated the module.
16 | 2. Make sure you have force stopped the module app after successful activation.
17 | 3. Search for related issues in the [Issues](https://github.com/xfqwdsj/IAmNotADeveloper/issues) section.
18 | 4. If you cannot find a related issue, please capture logs and take screenshots of the module app, ensuring the full module status card is visible (if it cannot fit in one screenshot, use multiple).
19 | 5. Submit a new issue in [Issues](https://github.com/xfqwdsj/IAmNotADeveloper/issues) and upload the logs.
20 |
21 | ### Q: How do I confirm that the module is activated in LSPosed?
22 |
23 | You can confirm by following these steps:
24 |
25 | 1. Launch the LSPosed Manager by any means.
26 | 2. On the "Modules" page, find the "IAmNotADeveloper" module.
27 | 3. Make sure the "Enable module" switch is turned on.
28 |
29 | ### Q: How do I capture logs?
30 |
31 | You can capture logs by following these steps:
32 |
33 | 1. Launch the LSPosed Manager by any means.
34 | 2. On the "Logs" page, tap the "Save" icon button in the upper right corner.
35 | 3. Choose a suitable save location, such as "Downloads", and do not change the file name.
36 | 4. Tap the "Save" button.
37 |
38 | ### Q: I activated the module for a certain app, but the app crashes/has no effect/is detected by a detector app. What should I do?
39 |
40 | This module works by directly injecting into the target app. For apps with built-in injection protection, the module may not work or may cause the app to refuse to run.
41 |
42 | Solution: None at the moment. See [Issue #104](https://github.com/xfqwdsj/IAmNotADeveloper/issues/104) for details. Please wait patiently; there is currently no ETA (Estimated Time of Arrival). **Do not submit any issues regarding this problem; they will be closed without further explanation.**
43 |
44 | ## How to Contribute
45 |
46 | If you want to contribute code to this project, please refer to [CONTRIBUTING.md](CONTRIBUTING.md).
47 |
48 | ## Privacy Agreement
49 |
50 | The "Test" function of this application will obtain the status of your corresponding system switch, including:
51 |
52 | - Developer mode
53 | - USB debugging
54 | - Wireless debugging
55 |
56 | However, this application will not collect any information about you.
57 |
--------------------------------------------------------------------------------
/README_pt-BR.md:
--------------------------------------------------------------------------------
1 | [](https://deepwiki.com/xfqwdsj/IAmNotADeveloper)
2 |
3 | [简体中文](README.md) | [English](README_en.md) | **Português (Brasil)**
4 |
5 | # IAmNotADeveloper
6 |
7 | Um módulo para ocultar o status das opções do desenvolvedor do sistema Android.
8 |
9 | ## Perguntas frequentes
10 |
11 | ### P: Ativei o módulo, mas ele informa "Módulo não ativado". O que devo fazer?
12 |
13 | Etapas de solução de problemas:
14 |
15 | 1. Certifique-se de ter ativado o módulo.
16 | 2. Certifique-se de que você tenha forçado a parada do app do módulo após a ativação bem-sucedida.
17 | 3. Pesquise por problemas relacionados na seção [Issues](https://github.com/xfqwdsj/IAmNotADeveloper/issues).
18 | 4. Se você não conseguir encontrar um problema relacionado, capture logs e faça capturas de tela do app do módulo, garantindo que o cartão de status completo do módulo esteja visível (se não couber em uma captura de tela, use várias).
19 | 5. Envie um novo problema em [Issues](https://github.com/xfqwdsj/IAmNotADeveloper/issues) e carregue os logs.
20 |
21 | ### P: Como posso confirmar se o módulo está ativado no LSPosed?
22 |
23 | Você pode confirmar seguindo estes passos:
24 |
25 | 1. Abra o LSPosed por qualquer meio.
26 | 2. Na página "Módulos", localize o módulo "IAmNotADeveloper".
27 | 3. Certifique-se de que a chave "Ativar módulo" esteja ativada.
28 |
29 | ### P: Como faço para capturar logs?
30 |
31 | Você pode capturar logs seguindo estes passos:
32 |
33 | 1. Abra o LSPosed por qualquer meio.
34 | 2. Na página "Registros", toque no ícone "Salvar" no canto superior direito.
35 | 3. Escolha um local adequado para salvar, como "Downloads", e não altere o nome do arquivo.
36 | 4. Toque no botão "Salvar".
37 |
38 | ### P: Ativei o módulo para um determinado app, mas o app trava/não tem efeito/é detectado por um app detector. O que devo fazer?
39 |
40 | Este módulo funciona injetando diretamente no app de destino. Para apps com proteção contra injeção integrada, o módulo pode não funcionar ou fazer com que o app se recuse a executar.
41 |
42 | Solução: Nenhuma no momento. Consulte o [Issue #104](https://github.com/xfqwdsj/IAmNotADeveloper/issues/104) para obter detalhes. Aguarde pacientemente; no momento, não há ETA (Hora Estimada de Chegada). **Não envie nenhum issue relacionado a este problema; eles serão encerrados sem maiores explicações.**
43 |
44 | ## Como contribuir
45 |
46 | Se você quiser contribuir com código para este projeto, consulte [CONTRIBUTING.md](CONTRIBUTING_pt-BR.md).
47 |
48 | ## Acordo de privacidade
49 |
50 | A função "Testar" deste app obterá o status das chaves do sistema correspondentes, incluindo:
51 |
52 | - Opções do desenvolvedor
53 | - Depuração USB
54 | - Depuração por Wi-Fi
55 |
56 | No entanto, este app não coletará nenhuma informação sobre você.
57 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
2 |
3 | plugins {
4 | alias(libs.plugins.kotlin)
5 | alias(libs.plugins.androidApplication)
6 | alias(libs.plugins.composeCompiler)
7 | }
8 |
9 | kotlin {
10 | compilerOptions {
11 | jvmTarget.set(JvmTarget.JVM_11)
12 | }
13 | }
14 |
15 | android {
16 | val appId = "top.ltfan.notdeveloper"
17 |
18 | namespace = appId
19 | compileSdk = libs.versions.compileSdk.get().toInt()
20 |
21 | signingConfigs {
22 | create("config") {
23 | storeFile = file("key.jks")
24 | storePassword = "keykey"
25 | keyAlias = "keykey"
26 | keyPassword = "keykey"
27 | }
28 | }
29 |
30 | defaultConfig {
31 | applicationId = appId
32 | minSdk = libs.versions.minSdk.get().toInt()
33 | targetSdk = libs.versions.targetSdk.get().toInt()
34 | versionName = libs.versions.app.versionName.get()
35 | versionCode = libs.versions.app.versionCode.get().toInt()
36 | }
37 |
38 | buildTypes {
39 | release {
40 | isMinifyEnabled = true
41 | isShrinkResources = true
42 | proguardFiles(
43 | getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
44 | )
45 | signingConfig = signingConfigs.getByName("config")
46 | }
47 |
48 | debug {
49 | signingConfig = signingConfigs.getByName("config")
50 | }
51 | }
52 |
53 | buildFeatures {
54 | buildConfig = true
55 | }
56 |
57 | compileOptions {
58 | sourceCompatibility = JavaVersion.VERSION_11
59 | targetCompatibility = JavaVersion.VERSION_11
60 | }
61 |
62 | buildFeatures {
63 | compose = true
64 | }
65 |
66 | packaging {
67 | resources {
68 | excludes += "/META-INF/{AL2.0,LGPL2.1}"
69 | }
70 | }
71 | }
72 |
73 | dependencies {
74 | implementation(libs.kotlin.reflect)
75 | implementation(libs.lifecycle.runtime)
76 | implementation(libs.lifecycle.viewmodel)
77 | implementation(libs.activity.compose)
78 |
79 | val compose = platform(libs.compose)
80 | implementation(compose)
81 |
82 | implementation(libs.compose.runtime)
83 | implementation(libs.compose.foundation)
84 | implementation(libs.compose.ui)
85 | implementation(libs.compose.ui.tooling.preview)
86 | implementation(libs.compose.animation)
87 | implementation(libs.compose.material3)
88 | implementation(libs.preference)
89 | compileOnly(libs.xposed.api)
90 | }
91 |
--------------------------------------------------------------------------------
/app/key.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xfqwdsj/IAmNotADeveloper/af28e73a6f048d9ec61795c21798b8093125c272/app/key.jks
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.kts.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
14 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
30 |
33 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/app/src/main/assets/xposed_init:
--------------------------------------------------------------------------------
1 | top.ltfan.notdeveloper.xposed.Hook
--------------------------------------------------------------------------------
/app/src/main/kotlin/top/ltfan/notdeveloper/Item.kt:
--------------------------------------------------------------------------------
1 | package top.ltfan.notdeveloper
2 |
3 | import androidx.annotation.StringRes
4 |
5 | enum class Item(val key: String, @StringRes val nameId: Int) {
6 | DevelopmentSettingsEnabled("development_settings_enabled", R.string.toggle_hide_development_mode),
7 | AdbEnabled("adb_enabled", R.string.toggle_hide_usb_debugging),
8 | AdbWifiEnabled("adb_wifi_enabled", R.string.toggle_hide_wireless_debugging);
9 |
10 | companion object {
11 | val oldApiItems = listOf(DevelopmentSettingsEnabled, AdbEnabled)
12 | val newApiItems = listOf(AdbWifiEnabled)
13 | val settingGlobalItems = listOf(DevelopmentSettingsEnabled, AdbEnabled, AdbWifiEnabled)
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/top/ltfan/notdeveloper/ui/activity/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package top.ltfan.notdeveloper.ui.activity
2 |
3 | import android.annotation.SuppressLint
4 | import android.os.Bundle
5 | import android.provider.Settings
6 | import android.view.WindowManager
7 | import androidx.activity.ComponentActivity
8 | import androidx.activity.compose.setContent
9 | import androidx.activity.enableEdgeToEdge
10 | import androidx.compose.foundation.layout.Column
11 | import androidx.compose.foundation.layout.Spacer
12 | import androidx.compose.foundation.layout.WindowInsets
13 | import androidx.compose.foundation.layout.WindowInsetsSides
14 | import androidx.compose.foundation.layout.consumeWindowInsets
15 | import androidx.compose.foundation.layout.displayCutout
16 | import androidx.compose.foundation.layout.fillMaxSize
17 | import androidx.compose.foundation.layout.height
18 | import androidx.compose.foundation.layout.only
19 | import androidx.compose.foundation.layout.padding
20 | import androidx.compose.foundation.layout.safeDrawing
21 | import androidx.compose.foundation.layout.windowInsetsPadding
22 | import androidx.compose.foundation.rememberScrollState
23 | import androidx.compose.foundation.verticalScroll
24 | import androidx.compose.material3.ExperimentalMaterial3Api
25 | import androidx.compose.material3.LargeTopAppBar
26 | import androidx.compose.material3.Scaffold
27 | import androidx.compose.material3.Text
28 | import androidx.compose.material3.TopAppBarDefaults
29 | import androidx.compose.material3.rememberTopAppBarState
30 | import androidx.compose.runtime.getValue
31 | import androidx.compose.runtime.mutableStateMapOf
32 | import androidx.compose.runtime.mutableStateOf
33 | import androidx.compose.runtime.setValue
34 | import androidx.compose.ui.Alignment
35 | import androidx.compose.ui.Modifier
36 | import androidx.compose.ui.input.nestedscroll.nestedScroll
37 | import androidx.compose.ui.res.stringResource
38 | import androidx.compose.ui.unit.dp
39 | import top.ltfan.notdeveloper.Item
40 | import top.ltfan.notdeveloper.R
41 | import top.ltfan.notdeveloper.ui.composable.PreferenceItem
42 | import top.ltfan.notdeveloper.ui.composable.StatusCard
43 | import top.ltfan.notdeveloper.ui.composable.rememberBooleanSharedPreference
44 | import top.ltfan.notdeveloper.ui.theme.IAmNotADeveloperTheme
45 | import top.ltfan.notdeveloper.util.isMiui
46 | import top.ltfan.notdeveloper.xposed.statusIsPreferencesReady
47 |
48 | class MainActivity : ComponentActivity() {
49 | private var isPreferencesReady by mutableStateOf(false)
50 | private val testResults = mutableStateMapOf- ()
51 |
52 | @SuppressLint("WorldReadableFiles")
53 | @OptIn(ExperimentalMaterial3Api::class)
54 | override fun onCreate(savedInstanceState: Bundle?) {
55 | enableEdgeToEdge()
56 | @Suppress("DEPRECATION") if (isMiui) {
57 | window.setFlags(
58 | WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
59 | WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
60 | )
61 | window.setFlags(
62 | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,
63 | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION
64 | )
65 | }
66 | super.onCreate(savedInstanceState)
67 |
68 | setContent {
69 | IAmNotADeveloperTheme {
70 | val scrollBehavior =
71 | TopAppBarDefaults.enterAlwaysScrollBehavior(rememberTopAppBarState())
72 |
73 | Scaffold(
74 | modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
75 | topBar = {
76 | LargeTopAppBar(
77 | title = {
78 | Text(stringResource(R.string.app_name))
79 | },
80 | windowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Horizontal + WindowInsetsSides.Top),
81 | scrollBehavior = scrollBehavior
82 | )
83 | }
84 | ) { padding ->
85 | Column(
86 | modifier = Modifier
87 | .consumeWindowInsets(padding)
88 | .fillMaxSize()
89 | .verticalScroll(rememberScrollState())
90 | .padding(padding)
91 | .windowInsetsPadding(WindowInsets.displayCutout.only(WindowInsetsSides.Horizontal + WindowInsetsSides.Bottom)),
92 | horizontalAlignment = Alignment.CenterHorizontally
93 | ) {
94 | Spacer(Modifier.height(16.dp))
95 |
96 | StatusCard(
97 | modifier = Modifier.padding(horizontal = 16.dp),
98 | isPreferencesReady = isPreferencesReady
99 | )
100 |
101 | Spacer(Modifier.height(16.dp))
102 |
103 | for (item in Item.entries) {
104 | @Suppress("DEPRECATION") var pref by rememberBooleanSharedPreference(
105 | mode = MODE_WORLD_READABLE,
106 | key = item.key,
107 | defaultValue = true,
108 | afterSet = { check() }
109 | )
110 | val testResult = testResults[item] ?: false
111 |
112 | PreferenceItem(
113 | nameId = item.nameId,
114 | testResult = testResult,
115 | checked = pref,
116 | onClick = { pref = !pref },
117 | enabled = isPreferencesReady
118 | )
119 | }
120 |
121 | Spacer(Modifier.height(16.dp))
122 | }
123 | }
124 | }
125 | }
126 | }
127 |
128 | override fun onResume() {
129 | super.onResume()
130 | isPreferencesReady = statusIsPreferencesReady
131 | check()
132 | }
133 |
134 | private fun check() {
135 | Item.settingGlobalItems.forEach {
136 | testResults[it] = Settings.Global.getInt(
137 | contentResolver,
138 | it.key,
139 | 0
140 | ) == 1
141 | }
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/top/ltfan/notdeveloper/ui/composable/PreferenceItem.kt:
--------------------------------------------------------------------------------
1 | package top.ltfan.notdeveloper.ui.composable
2 |
3 | import androidx.annotation.StringRes
4 | import androidx.compose.foundation.clickable
5 | import androidx.compose.material.icons.Icons
6 | import androidx.compose.material.icons.filled.Check
7 | import androidx.compose.material.icons.filled.Clear
8 | import androidx.compose.material3.Icon
9 | import androidx.compose.material3.ListItem
10 | import androidx.compose.material3.Switch
11 | import androidx.compose.material3.Text
12 | import androidx.compose.runtime.Composable
13 | import androidx.compose.ui.Modifier
14 | import androidx.compose.ui.res.stringResource
15 | import top.ltfan.notdeveloper.R
16 |
17 | @Composable
18 | fun PreferenceItem(
19 | @StringRes nameId: Int,
20 | testResult: Boolean,
21 | checked: Boolean,
22 | onClick: () -> Unit,
23 | enabled: Boolean,
24 | ) {
25 | ListItem(
26 | headlineContent = {
27 | Text(stringResource(nameId))
28 | },
29 | modifier = Modifier.clickable(enabled = enabled, onClick = onClick),
30 | leadingContent = {
31 | if (testResult) {
32 | Icon(
33 | Icons.Default.Clear,
34 | contentDescription = stringResource(R.string.test_result_on)
35 | )
36 | } else {
37 | Icon(
38 | Icons.Default.Check,
39 | contentDescription = stringResource(R.string.test_result_off)
40 | )
41 | }
42 | },
43 | trailingContent = {
44 | Switch(checked = checked, onCheckedChange = null, enabled = enabled)
45 | }
46 | )
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/top/ltfan/notdeveloper/ui/composable/SharedPreference.kt:
--------------------------------------------------------------------------------
1 | package top.ltfan.notdeveloper.ui.composable
2 |
3 | import android.content.Context
4 | import android.content.SharedPreferences.OnSharedPreferenceChangeListener
5 | import androidx.compose.runtime.Composable
6 | import androidx.compose.runtime.DisposableEffect
7 | import androidx.compose.runtime.getValue
8 | import androidx.compose.runtime.mutableStateOf
9 | import androidx.compose.runtime.remember
10 | import androidx.compose.runtime.setValue
11 | import androidx.compose.ui.platform.LocalContext
12 | import androidx.core.content.edit
13 | import kotlinx.coroutines.CoroutineScope
14 | import kotlinx.coroutines.Dispatchers
15 | import kotlinx.coroutines.launch
16 | import kotlin.reflect.KProperty
17 |
18 | @Composable
19 | fun rememberBooleanSharedPreference(
20 | preferenceFileKey: String? = null,
21 | mode: Int = Context.MODE_PRIVATE,
22 | key: String,
23 | defaultValue: Boolean,
24 | beforeSet: ((Boolean) -> Boolean)? = null,
25 | afterSet: ((Boolean) -> Unit)? = null,
26 | ): BooleanSharedPreference {
27 | val context = LocalContext.current
28 | val preference = remember(key) {
29 | BooleanSharedPreference(
30 | context, preferenceFileKey, mode, key, defaultValue, beforeSet, afterSet
31 | )
32 | }
33 |
34 | DisposableEffect(preference) {
35 | onDispose {
36 | preference.clean()
37 | }
38 | }
39 |
40 | return preference
41 | }
42 |
43 | class BooleanSharedPreference(
44 | context: Context,
45 | preferenceFileKey: String? = null,
46 | mode: Int = Context.MODE_PRIVATE,
47 | private val key: String,
48 | private val defaultValue: Boolean,
49 | private val beforeSet: ((Boolean) -> Boolean)? = null,
50 | private val afterSet: ((Boolean) -> Unit)? = null,
51 | ) {
52 | private val sharedPreferences = runCatching {
53 | context.getSharedPreferences(
54 | preferenceFileKey ?: (context.packageName + "_preferences"), mode
55 | )
56 | }.getOrNull()
57 |
58 | private val listener = OnSharedPreferenceChangeListener { sharedPreferences, changedKey ->
59 | if (changedKey != key) {
60 | return@OnSharedPreferenceChangeListener
61 | }
62 |
63 | value = sharedPreferences.getBoolean(key, defaultValue)
64 | }
65 |
66 | init {
67 | sharedPreferences?.registerOnSharedPreferenceChangeListener(listener)
68 | }
69 |
70 | private val prefsValue get() = sharedPreferences?.getBoolean(key, defaultValue) ?: defaultValue
71 |
72 | private var value by mutableStateOf(prefsValue)
73 |
74 | operator fun getValue(thisObj: Any?, property: KProperty<*>) = value
75 |
76 | operator fun setValue(thisObj: Any?, property: KProperty<*>, value: Boolean) {
77 | CoroutineScope(Dispatchers.IO).launch {
78 | val prefsValue = beforeSet?.invoke(value) ?: value
79 | sharedPreferences?.edit(commit = true) { putBoolean(key, prefsValue) }
80 | this@BooleanSharedPreference.value = prefsValue
81 | afterSet?.invoke(prefsValue)
82 | }
83 | }
84 |
85 | fun clean() {
86 | sharedPreferences?.unregisterOnSharedPreferenceChangeListener(listener)
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/top/ltfan/notdeveloper/ui/composable/StatusCard.kt:
--------------------------------------------------------------------------------
1 | package top.ltfan.notdeveloper.ui.composable
2 |
3 | import androidx.compose.animation.AnimatedVisibility
4 | import androidx.compose.animation.expandVertically
5 | import androidx.compose.animation.shrinkVertically
6 | import androidx.compose.foundation.layout.Column
7 | import androidx.compose.foundation.layout.Row
8 | import androidx.compose.foundation.layout.Spacer
9 | import androidx.compose.foundation.layout.fillMaxWidth
10 | import androidx.compose.foundation.layout.height
11 | import androidx.compose.foundation.layout.padding
12 | import androidx.compose.foundation.layout.size
13 | import androidx.compose.foundation.layout.width
14 | import androidx.compose.material.icons.Icons
15 | import androidx.compose.material.icons.filled.CheckCircle
16 | import androidx.compose.material.icons.filled.Warning
17 | import androidx.compose.material3.CardDefaults
18 | import androidx.compose.material3.ElevatedCard
19 | import androidx.compose.material3.Icon
20 | import androidx.compose.material3.MaterialTheme
21 | import androidx.compose.material3.Text
22 | import androidx.compose.runtime.Composable
23 | import androidx.compose.runtime.getValue
24 | import androidx.compose.runtime.mutableStateOf
25 | import androidx.compose.runtime.remember
26 | import androidx.compose.runtime.setValue
27 | import androidx.compose.ui.Alignment
28 | import androidx.compose.ui.Modifier
29 | import androidx.compose.ui.graphics.Color
30 | import androidx.compose.ui.graphics.vector.ImageVector
31 | import androidx.compose.ui.res.stringResource
32 | import androidx.compose.ui.tooling.preview.Preview
33 | import androidx.compose.ui.unit.dp
34 | import top.ltfan.notdeveloper.R
35 | import top.ltfan.notdeveloper.xposed.statusIsModuleActivated
36 |
37 | @Composable
38 | fun StatusCard(
39 | modifier: Modifier = Modifier,
40 | isModuleActivated: Boolean = statusIsModuleActivated,
41 | isPreferencesReady: Boolean
42 | ) {
43 | val status = Status.from(isModuleActivated, isPreferencesReady)
44 |
45 | var expanded by remember { mutableStateOf(false) }
46 |
47 | ElevatedCard(
48 | onClick = { expanded = !expanded },
49 | modifier = modifier.fillMaxWidth(),
50 | colors = CardDefaults.cardColors(containerColor = status.containerColor),
51 | ) {
52 | Row(
53 | Modifier
54 | .padding(24.dp)
55 | .fillMaxWidth(),
56 | verticalAlignment = Alignment.CenterVertically
57 | ) {
58 | Icon(status.icon, contentDescription = null, modifier = Modifier.size(32.dp))
59 | Spacer(Modifier.width(16.dp))
60 | Column(Modifier.weight(1f)) {
61 | Text(status.summary, style = MaterialTheme.typography.headlineSmall)
62 | AnimatedVisibility(visible = isPreferencesReady) {
63 | Text(stringResource(R.string.description_changes_application))
64 | }
65 | AnimatedVisibility(visible = status != Status.Normal) {
66 | Text(stringResource(R.string.description_more_info))
67 | }
68 |
69 | AnimatedVisibility(
70 | visible = status != Status.Normal || expanded,
71 | enter = expandVertically(expandFrom = Alignment.CenterVertically),
72 | exit = shrinkVertically(shrinkTowards = Alignment.CenterVertically)
73 | ) {
74 | Spacer(Modifier.height(8.dp))
75 | }
76 | AnimatedVisibility(visible = expanded && isModuleActivated) {
77 | Text(stringResource(R.string.status_entry_activation_y))
78 | }
79 | AnimatedVisibility(visible = !isModuleActivated) {
80 | Text(
81 | stringResource(R.string.status_entry_activation_n),
82 | color = MaterialTheme.colorScheme.error
83 | )
84 | }
85 | AnimatedVisibility(visible = expanded) {
86 | Text(
87 | stringResource(R.string.status_entry_activation_description),
88 | style = MaterialTheme.typography.labelSmall
89 | )
90 | }
91 |
92 | AnimatedVisibility(
93 | visible = expanded,
94 | enter = expandVertically(expandFrom = Alignment.CenterVertically),
95 | exit = shrinkVertically(shrinkTowards = Alignment.CenterVertically)
96 | ) {
97 | Spacer(Modifier.height(8.dp))
98 | }
99 |
100 | AnimatedVisibility(visible = expanded && isPreferencesReady) {
101 | Text(stringResource(R.string.status_entry_prefs_y))
102 | }
103 | AnimatedVisibility(visible = !isPreferencesReady) {
104 | Text(
105 | stringResource(R.string.status_entry_prefs_n),
106 | color = MaterialTheme.colorScheme.error
107 | )
108 | }
109 | AnimatedVisibility(visible = expanded) {
110 | Text(
111 | stringResource(R.string.status_entry_prefs_description),
112 | style = MaterialTheme.typography.labelSmall
113 | )
114 | }
115 | }
116 | }
117 | }
118 | }
119 |
120 | @Preview(device = "id:pixel_5", locale = "zh-rCN", showSystemUi = false, showBackground = false)
121 | @Composable
122 | fun StatusCardPreview() {
123 | Column {
124 | StatusCard(isModuleActivated = true, isPreferencesReady = true)
125 | StatusCard(isModuleActivated = true, isPreferencesReady = false)
126 | StatusCard(isModuleActivated = false, isPreferencesReady = true)
127 | StatusCard(isModuleActivated = false, isPreferencesReady = false)
128 | }
129 | }
130 |
131 | enum class Status {
132 | Normal, Partial, Error;
133 |
134 | companion object {
135 | fun from(isModuleActivated: Boolean, isPreferencesReady: Boolean): Status {
136 | if (!isModuleActivated) return Error
137 | return if (isPreferencesReady) {
138 | Normal
139 | } else Partial
140 | }
141 | }
142 |
143 | val containerColor: Color
144 | @Composable get() = when (this) {
145 | Normal -> MaterialTheme.colorScheme.primaryContainer
146 | Partial -> MaterialTheme.colorScheme.tertiaryContainer
147 | Error -> MaterialTheme.colorScheme.errorContainer
148 | }
149 |
150 | val icon: ImageVector
151 | @Composable get() = when (this) {
152 | Normal -> Icons.Default.CheckCircle
153 | else -> Icons.Default.Warning
154 | }
155 |
156 | val summary: String
157 | @Composable get() = stringResource(
158 | when (this) {
159 | Normal -> R.string.status_normal
160 | Partial -> R.string.status_partial
161 | Error -> R.string.status_error
162 | }
163 | )
164 | }
165 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/top/ltfan/notdeveloper/ui/theme/Theme.kt:
--------------------------------------------------------------------------------
1 | package top.ltfan.notdeveloper.ui.theme
2 |
3 | import android.os.Build
4 | import androidx.compose.foundation.isSystemInDarkTheme
5 | import androidx.compose.material3.MaterialTheme
6 | import androidx.compose.material3.darkColorScheme
7 | import androidx.compose.material3.dynamicDarkColorScheme
8 | import androidx.compose.material3.dynamicLightColorScheme
9 | import androidx.compose.material3.lightColorScheme
10 | import androidx.compose.runtime.Composable
11 | import androidx.compose.ui.platform.LocalContext
12 |
13 | @Composable
14 | fun IAmNotADeveloperTheme(
15 | darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit
16 | ) {
17 | val colorScheme = when {
18 | Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
19 | val context = LocalContext.current
20 | if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
21 | }
22 |
23 | darkTheme -> darkColorScheme()
24 | else -> lightColorScheme()
25 | }
26 |
27 | MaterialTheme(
28 | colorScheme = colorScheme, content = content
29 | )
30 | }
--------------------------------------------------------------------------------
/app/src/main/kotlin/top/ltfan/notdeveloper/util/SystemUtil.kt:
--------------------------------------------------------------------------------
1 | package top.ltfan.notdeveloper.util
2 |
3 | import android.annotation.SuppressLint
4 | import kotlin.reflect.full.declaredFunctions
5 |
6 | val isMiui: Boolean
7 | @SuppressLint("PrivateApi") get() {
8 | val clazz = Class.forName("android.os.SystemProperties").kotlin
9 | val method =
10 | clazz.declaredFunctions.firstOrNull { it.name == "get" && it.parameters.size == 1 }
11 | return method?.call("ro.miui.ui.version.name") != ""
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/top/ltfan/notdeveloper/xposed/Hook.kt:
--------------------------------------------------------------------------------
1 | package top.ltfan.notdeveloper.xposed
2 |
3 | import android.content.ContentResolver
4 | import android.provider.Settings
5 | import androidx.annotation.Keep
6 | import de.robv.android.xposed.IXposedHookLoadPackage
7 | import de.robv.android.xposed.XC_MethodHook
8 | import de.robv.android.xposed.XC_MethodHook.MethodHookParam
9 | import de.robv.android.xposed.XSharedPreferences
10 | import de.robv.android.xposed.XposedBridge
11 | import de.robv.android.xposed.XposedHelpers
12 | import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam
13 | import top.ltfan.notdeveloper.BuildConfig
14 | import top.ltfan.notdeveloper.Item
15 |
16 | @Keep
17 | class Hook : IXposedHookLoadPackage {
18 | override fun handleLoadPackage(lpparam: LoadPackageParam) {
19 | if (lpparam.packageName.startsWith("android") || lpparam.packageName.startsWith("com.android")) {
20 | return
21 | }
22 |
23 | Log.d("processing package ${lpparam.packageName}")
24 |
25 | if (lpparam.packageName == BuildConfig.APPLICATION_ID) {
26 | XposedHelpers.findAndHookMethod(
27 | "${BuildConfig.APPLICATION_ID}.xposed.ModuleStatusKt",
28 | lpparam.classLoader,
29 | "getStatusIsModuleActivated",
30 | object : XC_MethodHook() {
31 | override fun beforeHookedMethod(param: MethodHookParam) {
32 | param.result = true
33 | }
34 | },
35 | )
36 | }
37 |
38 | val prefs = XSharedPreferences(BuildConfig.APPLICATION_ID)
39 |
40 | val newApiCallback = object : XC_MethodHook() {
41 | override fun beforeHookedMethod(param: MethodHookParam) {
42 | prefs.reload()
43 | changeResultToZero(
44 | lpparam,
45 | prefs,
46 | param,
47 | *(Item.oldApiItems.toTypedArray() + Item.newApiItems.toTypedArray())
48 | )
49 | }
50 | }
51 |
52 | val oldApiCallback = object : XC_MethodHook() {
53 | override fun beforeHookedMethod(param: MethodHookParam) {
54 | prefs.reload()
55 | changeResultToZero(lpparam, prefs, param, *Item.oldApiItems.toTypedArray())
56 | }
57 | }
58 |
59 | XposedHelpers.findAndHookMethod(
60 | Settings.Global::class.java,
61 | "getInt",
62 | ContentResolver::class.java,
63 | String::class.java,
64 | Int::class.java,
65 | newApiCallback,
66 | )
67 |
68 | XposedHelpers.findAndHookMethod(
69 | Settings.Global::class.java,
70 | "getInt",
71 | ContentResolver::class.java,
72 | String::class.java,
73 | newApiCallback,
74 | )
75 |
76 | XposedHelpers.findAndHookMethod(
77 | Settings.Secure::class.java,
78 | "getInt",
79 | ContentResolver::class.java,
80 | String::class.java,
81 | Int::class.java,
82 | oldApiCallback,
83 | )
84 |
85 | XposedHelpers.findAndHookMethod(
86 | Settings.Secure::class.java,
87 | "getInt",
88 | ContentResolver::class.java,
89 | String::class.java,
90 | oldApiCallback,
91 | )
92 |
93 | processSystemProps(prefs, lpparam)
94 | }
95 |
96 | private fun processSystemProps(prefs: XSharedPreferences, lpparam: LoadPackageParam) {
97 | val clazz = XposedHelpers.findClassIfExists(
98 | "android.os.SystemProperties", lpparam.classLoader
99 | )
100 |
101 | if (clazz == null) {
102 | Log.w("cannot find SystemProperties class")
103 | return
104 | }
105 |
106 | val ffsReady = "sys.usb.ffs.ready"
107 | val usbState = "sys.usb.state"
108 | val usbConfig = "sys.usb.config"
109 | val rebootFunc = "persist.sys.usb.reboot.func"
110 | val svcAdbd = "init.svc.adbd"
111 |
112 | val methodGet = "get"
113 | val methodGetprop = "getprop"
114 | val methodGetBoolean = "getBoolean"
115 | val methodGetInt = "getInt"
116 | val methodGetLong = "getLong"
117 |
118 | val overrideAdb = "mtp"
119 | val overrideSvcAdbd = "stopped"
120 |
121 | listOf(methodGet, methodGetprop, methodGetBoolean, methodGetInt, methodGetLong).forEach {
122 | XposedBridge.hookAllMethods(
123 | clazz, it,
124 | object : XC_MethodHook() {
125 | override fun beforeHookedMethod(param: MethodHookParam) {
126 | prefs.reload()
127 | if (!prefs.getBoolean(Item.AdbEnabled.key, true)) return
128 |
129 | val arg = param.args[0] as String
130 | Log.d("processing ${param.method.name} from ${lpparam.packageName} with arg $arg")
131 |
132 | if (param.method.name != methodGet && arg != ffsReady) {
133 | Log.i("props processed ${param.method.name} from ${lpparam.packageName} receiving invalid arg $arg")
134 | return
135 | }
136 |
137 | when (arg) {
138 | ffsReady -> {
139 | when (param.method.name) {
140 | methodGet -> param.result = "0"
141 | methodGetprop -> param.result = "0"
142 | methodGetBoolean -> param.result = false
143 | methodGetInt -> param.result = 0
144 | methodGetLong -> param.result = 0L
145 | }
146 | }
147 |
148 | usbState -> param.result = overrideAdb
149 | usbConfig -> param.result = overrideAdb
150 | rebootFunc -> param.result = overrideAdb
151 | svcAdbd -> param.result = overrideSvcAdbd
152 | }
153 |
154 | Log.d("processed ${param.method.name}($arg): ${param.result}")
155 | }
156 | }
157 | )
158 | }
159 | }
160 |
161 | private fun changeResultToZero(
162 | lpparam: LoadPackageParam,
163 | prefs: XSharedPreferences,
164 | param: MethodHookParam,
165 | vararg items: Item
166 | ) {
167 | val arg = param.args[1] as String
168 | Log.d("processing ${param.method.name} from ${lpparam.packageName} with arg $arg")
169 |
170 | items.forEach { item ->
171 | val key = item.key
172 | if (prefs.getBoolean(key, true) && arg == key) {
173 | param.result = 0
174 | Log.d("processed ${param.method.name}($arg): ${param.result}")
175 | return
176 | }
177 | }
178 |
179 | Log.d("processed ${param.method.name}($arg) without changing result")
180 | }
181 | }
182 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/top/ltfan/notdeveloper/xposed/Log.kt:
--------------------------------------------------------------------------------
1 | package top.ltfan.notdeveloper.xposed
2 |
3 | import de.robv.android.xposed.XposedBridge
4 |
5 | object Log {
6 | const val TAG = "NotDeveloper"
7 |
8 | fun d(message: String, throwable: Throwable? = null) {
9 | log("DEBUG", message, throwable)
10 | }
11 |
12 | fun i(message: String, throwable: Throwable? = null) {
13 | log("INFO", message, throwable)
14 | }
15 |
16 | fun w(message: String, throwable: Throwable? = null) {
17 | log("WARN", message, throwable)
18 | }
19 |
20 | private fun log(level: String, message: String, throwable: Throwable? = null) {
21 | XposedBridge.log("[$level] $TAG: $message")
22 | if (throwable != null) {
23 | XposedBridge.log(throwable)
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/top/ltfan/notdeveloper/xposed/ModuleStatus.kt:
--------------------------------------------------------------------------------
1 | package top.ltfan.notdeveloper.xposed
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Context
5 | import androidx.annotation.Keep
6 |
7 | val statusIsModuleActivated
8 | @Keep get() = false
9 |
10 |
11 | val Context.statusIsPreferencesReady: Boolean
12 | @SuppressLint("WorldReadableFiles")get() {
13 | return try {
14 | @Suppress("DEPRECATION") getSharedPreferences(
15 | "testPreferences",
16 | Context.MODE_WORLD_READABLE
17 | )
18 | true
19 | } catch (t: Throwable) {
20 | android.util.Log.e(Log.TAG, "failed to confirm SharedPreferences' state.", t)
21 | false
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xfqwdsj/IAmNotADeveloper/af28e73a6f048d9ec61795c21798b8093125c272/app/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xfqwdsj/IAmNotADeveloper/af28e73a6f048d9ec61795c21798b8093125c272/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xfqwdsj/IAmNotADeveloper/af28e73a6f048d9ec61795c21798b8093125c272/app/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xfqwdsj/IAmNotADeveloper/af28e73a6f048d9ec61795c21798b8093125c272/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xfqwdsj/IAmNotADeveloper/af28e73a6f048d9ec61795c21798b8093125c272/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xfqwdsj/IAmNotADeveloper/af28e73a6f048d9ec61795c21798b8093125c272/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xfqwdsj/IAmNotADeveloper/af28e73a6f048d9ec61795c21798b8093125c272/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xfqwdsj/IAmNotADeveloper/af28e73a6f048d9ec61795c21798b8093125c272/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xfqwdsj/IAmNotADeveloper/af28e73a6f048d9ec61795c21798b8093125c272/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xfqwdsj/IAmNotADeveloper/af28e73a6f048d9ec61795c21798b8093125c272/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/values-night/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | IAmNotADeveloper
4 | Ocultar opções do desenvolvedor
5 | Ocultar depuração USB
6 | Ocultar depuração por Wi-Fi
7 | Funcionando normalmente
8 | Funcionando parcialmente
9 | Pode não funcionar
10 | Módulo ativado
11 | Módulo não ativado
12 | O status de ativação do módulo afeta diretamente sua funcionalidade. Se o módulo não estiver ativado, ele não funcionará. O módulo relata seu status de ativação conectando seus próprios componentes. Se você suspeitar de um relatório falso, force a parada do app e abra-o novamente.
13 | Preferências prontas
14 | Preferências não funcionam
15 | O estado de Preferences determina se as configurações do módulo podem ser salvas. Normalmente, o uso adequado do LSPosed não torna esse estado anormal. Se o estado for anormal, todos os recursos do módulo serão ativados por padrão.
16 | Todas as alterações entrarão em vigor imediatamente
17 | Clique para ver mais informações
18 | Resultado do teste deste item: Ligado
19 | Resultado do teste deste item: Desligado
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/values-zh-rCN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 我不是开发者
4 | 隐藏开发者模式
5 | 隐藏USB调试
6 | 隐藏无线调试
7 | 正常工作中
8 | 部分功能可用
9 | 可能无法工作
10 | 模块已激活
11 | 模块未激活
12 | 模块的激活状态直接影响其功能。如果模块未被激活,它将完全无法运行。模块通过Hook自身的成员实现报告模块激活状态,如果你认为存在误报,请强行停止应用再重新打开。
13 | 偏好设置正常
14 | 偏好设置不可用
15 | 偏好设置的状态决定了模块设置是否可以被保存。通常,正确使用LSPosed不会导致此状态异常。如果此状态异常,所有模块功能将默认启用。
16 | 所有更改将即时生效
17 | 点击查看更多信息
18 | 该项测试结果:开启
19 | 该项测试结果:关闭
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | IAmNotADeveloper
4 | Hide development mode
5 | Hide USB debugging
6 | Hide wireless debugging
7 | Working normally
8 | Partially working
9 | May not work
10 | Module activated
11 | Module not activated
12 | The module\'s activation status directly affects its functionality. If the module isn\'t activated, it won\'t work. The module reports its activation status by hooking its own members. If you suspect a false report, force stop the app and reopen it.
13 | Preferences ready
14 | Preferences not working
15 | The state of Preferences determines whether the module\'s settings can be saved. Normally, proper usage of LSPosed won\'t cause this state to be abnormal. If the state is abnormal, all module features will be enabled by default.
16 | All changes will take effect immediately
17 | Click to view more information
18 | Test result of this item: On
19 | Test result of this item: Off
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/backup_rules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/data_extraction_rules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | plugins {
3 | alias(libs.plugins.kotlin) apply false
4 | alias(libs.plugins.androidApplication) apply false
5 | alias(libs.plugins.androidLibrary) apply false
6 | alias(libs.plugins.composeCompiler) apply false
7 | }
8 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Kotlin code style for this project: "official" or "obsolete":
19 | kotlin.code.style=official
20 | # Enables namespacing of each library's R class so that its R class includes only the
21 | # resources declared in the library itself and none from the library's dependencies,
22 | # thereby reducing the size of the R class for that library
23 | android.nonTransitiveRClass=true
--------------------------------------------------------------------------------
/gradle/libs.versions.toml:
--------------------------------------------------------------------------------
1 | [versions]
2 | app-versionName = "1.5.0"
3 | app-versionCode = "9"
4 | kotlin = "2.1.20"
5 | agp = "8.10.0"
6 | compileSdk = "36"
7 | targetSdk = "36"
8 | minSdk = "27"
9 | compose = "2025.05.00"
10 | lifecycle = "2.9.0"
11 | activity = "1.10.1"
12 | preference = "1.2.1"
13 | xposed-api = "82"
14 |
15 | [libraries]
16 | kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" }
17 | lifecycle-runtime = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycle" }
18 | lifecycle-viewmodel = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycle" }
19 | activity-compose = { module = "androidx.activity:activity-compose", version.ref = "activity" }
20 | compose = { module = "androidx.compose:compose-bom", version.ref = "compose" }
21 | compose-runtime = { module = "androidx.compose.runtime:runtime" }
22 | compose-foundation = { module = "androidx.compose.foundation:foundation" }
23 | compose-ui = { module = "androidx.compose.ui:ui" }
24 | compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview" }
25 | compose-animation = { module = "androidx.compose.animation:animation" }
26 | compose-material3 = { module = "androidx.compose.material3:material3" }
27 | preference = { module = "androidx.preference:preference-ktx", version.ref = "preference" }
28 | xposed-api = { module = "de.robv.android.xposed:api", version.ref = "xposed-api" }
29 |
30 | [plugins]
31 | kotlin = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
32 | androidApplication = { id = "com.android.application", version.ref = "agp" }
33 | androidLibrary = { id = "com.android.library", version.ref = "agp" }
34 | composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
35 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xfqwdsj/IAmNotADeveloper/af28e73a6f048d9ec61795c21798b8093125c272/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sun Sep 24 13:04:41 CST 2023
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 |
86 | # Determine the Java command to use to start the JVM.
87 | if [ -n "$JAVA_HOME" ] ; then
88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89 | # IBM's JDK on AIX uses strange locations for the executables
90 | JAVACMD="$JAVA_HOME/jre/sh/java"
91 | else
92 | JAVACMD="$JAVA_HOME/bin/java"
93 | fi
94 | if [ ! -x "$JAVACMD" ] ; then
95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 | else
101 | JAVACMD="java"
102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103 |
104 | Please set the JAVA_HOME variable in your environment to match the
105 | location of your Java installation."
106 | fi
107 |
108 | # Increase the maximum file descriptors if we can.
109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110 | MAX_FD_LIMIT=`ulimit -H -n`
111 | if [ $? -eq 0 ] ; then
112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113 | MAX_FD="$MAX_FD_LIMIT"
114 | fi
115 | ulimit -n $MAX_FD
116 | if [ $? -ne 0 ] ; then
117 | warn "Could not set maximum file descriptor limit: $MAX_FD"
118 | fi
119 | else
120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121 | fi
122 | fi
123 |
124 | # For Darwin, add options to specify how the application appears in the dock
125 | if $darwin; then
126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127 | fi
128 |
129 | # For Cygwin or MSYS, switch paths to Windows format before running java
130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133 |
134 | JAVACMD=`cygpath --unix "$JAVACMD"`
135 |
136 | # We build the pattern for arguments to be converted via cygpath
137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138 | SEP=""
139 | for dir in $ROOTDIRSRAW ; do
140 | ROOTDIRS="$ROOTDIRS$SEP$dir"
141 | SEP="|"
142 | done
143 | OURCYGPATTERN="(^($ROOTDIRS))"
144 | # Add a user-defined pattern to the cygpath arguments
145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147 | fi
148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
149 | i=0
150 | for arg in "$@" ; do
151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153 |
154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156 | else
157 | eval `echo args$i`="\"$arg\""
158 | fi
159 | i=`expr $i + 1`
160 | done
161 | case $i in
162 | 0) set -- ;;
163 | 1) set -- "$args0" ;;
164 | 2) set -- "$args0" "$args1" ;;
165 | 3) set -- "$args0" "$args1" "$args2" ;;
166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172 | esac
173 | fi
174 |
175 | # Escape application args
176 | save () {
177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178 | echo " "
179 | }
180 | APP_ARGS=`save "$@"`
181 |
182 | # Collect all arguments for the java command, following the shell quoting and substitution rules
183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184 |
185 | exec "$JAVACMD" "$@"
186 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | rootProject.name = "IAmNotADeveloper"
2 |
3 | pluginManagement {
4 | repositories {
5 | google()
6 | mavenCentral()
7 | gradlePluginPortal()
8 | }
9 | }
10 | dependencyResolutionManagement {
11 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
12 | repositories {
13 | google()
14 | mavenCentral()
15 | maven("https://api.xposed.info/")
16 | }
17 | }
18 |
19 | include(":app")
20 |
--------------------------------------------------------------------------------