├── .gitignore
├── .idea
├── .gitignore
├── compiler.xml
├── gradle.xml
├── misc.xml
└── vcs.xml
├── GlobalProxy_help.mp4
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── aidl
│ └── com
│ │ └── itos
│ │ └── dpm
│ │ └── IUserService.aidl
│ ├── java
│ └── com
│ │ └── itos
│ │ └── dpm
│ │ ├── MainActivity.java
│ │ ├── UserService.java
│ │ └── dhizuku.java
│ └── res
│ ├── drawable
│ ├── icon.png
│ └── owner.png
│ ├── layout
│ └── activity_main.xml
│ ├── values-v21
│ └── styles.xml
│ ├── values
│ ├── colors.xml
│ ├── strings.xml
│ └── styles.xml
│ └── xml
│ └── device_admin.xml
├── build.gradle
├── device_owner.zip
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.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 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # 默认忽略的文件
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/GlobalProxy_help.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/DPM_Operate/78a2647b9c7bb9413f49dabd3629fc20215b3821/GlobalProxy_help.mp4
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DPM_Operate
2 | 利用Dhizuku获取DeviceOwner权限,然后进行一些操作
3 |
4 | ## 本软件功能:
5 | 1. 限制指定/全部APP的卸载
6 | 2. 限制安装APP
7 | 3. 设置DeviceOwner锁屏提示文字
8 | 4. 设置组织名
9 | 5. 禁用截屏
10 | 6. 禁用相机
11 | 7. 禁用ADB调试
12 | 8. 设置全局代理
13 | `*使用教程: 项目里面那个 GlobalProxy_help.mp4 ,自己下载来看*`
14 |
15 | 本软件是我第一次用UserService,写的不好见谅
16 | 我UI设计比较垃圾,大家可以提PR
17 | 有问题就提is,基本都会搞的(只要合理)
18 |
19 | [我的主页](https://itos.codegang.top/)
20 |
21 | [我的酷安](http://www.coolapk.com/u/3287595)
22 |
23 | 求一波关注(doge)
24 |
25 | 软件下载: [点我](https://codegang.lanzouq.com/i775411t1ucf)密码:aii7
26 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | }
4 | android {
5 | compileSdk 33
6 |
7 | defaultConfig {
8 | applicationId "com.itos.dpm"
9 | minSdk 28
10 | targetSdk 33
11 | versionCode 14
12 | versionName "Release-5"
13 |
14 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
15 | }
16 |
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
21 | signingConfig signingConfigs.debug
22 | }
23 | }
24 | compileOptions {
25 | sourceCompatibility JavaVersion.VERSION_15
26 | targetCompatibility JavaVersion.VERSION_15
27 | }
28 | }
29 |
30 | dependencies {
31 | implementation 'org.jetbrains:annotations:15.0'
32 | def dhizuku_version = "2.4"
33 | implementation "io.github.iamr0s:Dhizuku-API:$dhizuku_version"
34 |
35 |
36 | }
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
18 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/aidl/com/itos/dpm/IUserService.aidl:
--------------------------------------------------------------------------------
1 | package com.itos.dpm;
2 |
3 | interface IUserService {
4 | void onCreate() = 1;
5 | void onDestroy() = 2;
6 | void change_screen_text(String text) = 21;
7 | void set_screen_capture(boolean x) = 22;
8 | void set_camera_capture(boolean x) = 23;
9 | void set_org_name(String text) = 24;
10 | void add_user_restriction(String key) = 25;
11 | void clear_user_restriction(String key) = 26;
12 | void set_global_proxy(String url) = 27;
13 | // 20以内的transact code是保留给未来的Dhizuku APi使用的。
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/dpm/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.itos.dpm;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.app.Activity;
5 | import android.app.AlertDialog;
6 | import android.app.admin.DevicePolicyManager;
7 | import android.content.ComponentName;
8 | import android.content.Context;
9 | import android.content.DialogInterface;
10 | import android.content.Intent;
11 | import android.content.ServiceConnection;
12 | import android.content.pm.ApplicationInfo;
13 | import android.content.pm.PackageManager;
14 | import android.net.ProxyInfo;
15 | import android.net.Uri;
16 | import android.os.Bundle;
17 | import android.os.IBinder;
18 | import android.os.RemoteException;
19 | import android.os.UserManager;
20 | import android.util.Log;
21 | import android.view.View;
22 | import android.view.Window;
23 | import android.view.WindowManager;
24 | import android.widget.AdapterView;
25 | import android.widget.ArrayAdapter;
26 | import android.widget.EditText;
27 | import android.widget.Spinner;
28 | import android.widget.Toast;
29 |
30 | import com.rosan.dhizuku.api.Dhizuku;
31 | import com.rosan.dhizuku.api.DhizukuRequestPermissionListener;
32 | import com.rosan.dhizuku.api.DhizukuUserServiceArgs;
33 |
34 | import org.jetbrains.annotations.Nullable;
35 |
36 | import java.util.ArrayList;
37 | import java.util.Arrays;
38 | import java.util.Objects;
39 |
40 | import com.itos.dpm.dhizuku;
41 |
42 | public class MainActivity extends Activity implements View.OnClickListener {
43 | DevicePolicyManager mDevicePolicyManager;
44 | private IUserService service;
45 |
46 | ComponentName componentName;
47 | private static final String[] REQUIRED_DELEGATED_SCOPES = new String[]{
48 | DevicePolicyManager.DELEGATION_BLOCK_UNINSTALL,
49 | DevicePolicyManager.DELEGATION_PACKAGE_ACCESS,
50 | };
51 |
52 | EditText pkg_editText, screen_editText, proxyinfo_edit;
53 | ProxyInfo proxyInfo;
54 |
55 | String[] options = {"安装APP", "卸载APP", "ADB调试"};
56 | Spinner spinner;
57 | String UserRestriction;
58 | String selectedItem;
59 |
60 | private boolean isDeviceOwner(){
61 | boolean isDeviceOwnerApp = mDevicePolicyManager.isDeviceOwnerApp(componentName.getPackageName());
62 | Log.d("TAG", "isDeviceOwnerApp: " + isDeviceOwnerApp);
63 | return isDeviceOwnerApp;
64 | }
65 | @SuppressLint("MissingInflatedId")
66 | @Override
67 | protected void onCreate(@Nullable Bundle savedInstanceState) {
68 | super.onCreate(savedInstanceState);
69 | mDevicePolicyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
70 | requestWindowFeature(Window.FEATURE_NO_TITLE);
71 | // 设置当前页状态栏为白色
72 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
73 | getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
74 | getWindow().setStatusBarColor(getResources().getColor(R.color.white));
75 |
76 | setContentView(R.layout.activity_main);
77 | View decorView = getWindow().getDecorView();
78 | decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
79 |
80 |
81 | if (!Dhizuku.init(this)) {
82 | ShowToastL(this, "Dhizuku 初始化失败,请安装或启动 Dhizuku 应用程序,然后重启本APP。");
83 | ShowToastS(this, "密码9g7p");
84 | Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://iamr0s.lanzoul.com/b02ki3edg"));
85 | startActivity(intent);
86 | finish();
87 | return;
88 | }
89 | if (Dhizuku.getVersionCode() < 5) {
90 | ShowToastL(this, "请更新您的 Dhizuku 版本(需要2.8及以上)");
91 | ShowToastS(this, "密码9g7p");
92 | Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://iamr0s.lanzoul.com/b02ki3edg"));
93 | startActivity(intent);
94 | finish();
95 | return;
96 | }
97 | if (!Dhizuku.isPermissionGranted()) {
98 | Dhizuku.requestPermission(new DhizukuRequestPermissionListener() {
99 | @Override
100 | public void onRequestPermission(int grantResult) {
101 | if (grantResult == PackageManager.PERMISSION_GRANTED){
102 | setDelegatedScopes();
103 | bindUserService();
104 | } else{
105 | ShowToastL(MainActivity.this, String.valueOf(R.string.dhizuku_permission_denied));
106 | finish();
107 | }
108 | }
109 | });
110 | } else {
111 | bindUserService();
112 | setDelegatedScopes();
113 | }
114 |
115 | pkg_editText = findViewById(R.id.pkg_edit_text);
116 | screen_editText = findViewById(R.id.screen_edit_text);
117 | proxyinfo_edit = findViewById(R.id.global_proxy_address_edit);
118 | findViewById(R.id.unblock_uninstall).setOnClickListener(this);
119 | findViewById(R.id.block_uninstall).setOnClickListener(this);
120 | findViewById(R.id.check_unblock_uninstall).setOnClickListener(this);
121 | findViewById(R.id.change_screen_text).setOnClickListener(this);
122 | findViewById(R.id.screen_capture_disabled).setOnClickListener(this);
123 | findViewById(R.id.screen_capture_enabled).setOnClickListener(this);
124 | findViewById(R.id.camera_disabled).setOnClickListener(this);
125 | findViewById(R.id.camera_enabled).setOnClickListener(this);
126 | findViewById(R.id.user_restriction_disabled).setOnClickListener(this);
127 | findViewById(R.id.user_restriction_enabled).setOnClickListener(this);
128 | findViewById(R.id.set_org_name).setOnClickListener(this);
129 | findViewById(R.id.set_global_proxy_address).setOnClickListener(this);
130 | findViewById(R.id.join).setOnClickListener(this);
131 |
132 | spinner = findViewById(R.id.spinner);
133 | // 创建适配器
134 | ArrayAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, options);
135 | adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
136 | // 设置适配器
137 | spinner.setAdapter(adapter);
138 | // 设置选择项监听
139 | spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
140 | @Override
141 | public void onItemSelected(AdapterView> parent, View view, int position, long id) {
142 | selectedItem = parent.getItemAtPosition(position).toString();
143 | if (selectedItem.equals(options[0])){
144 | UserRestriction=UserManager.DISALLOW_INSTALL_APPS;
145 | } else if (selectedItem.equals(options[1])) {
146 | UserRestriction=UserManager.DISALLOW_UNINSTALL_APPS;
147 | } else {
148 | UserRestriction=UserManager.DISALLOW_DEBUGGING_FEATURES;
149 | }
150 | // Toast.makeText(MainActivity.this, "选择了:" + selectedItem, Toast.LENGTH_SHORT).show();
151 | }
152 | @Override
153 | public void onNothingSelected(AdapterView> parent) {}
154 |
155 | });
156 | }
157 |
158 | void bindUserService() {
159 | DhizukuUserServiceArgs args = new DhizukuUserServiceArgs(new ComponentName(this, UserService.class));
160 | boolean bind = Dhizuku.bindUserService(args, new ServiceConnection() {
161 | @Override
162 | public void onServiceConnected(ComponentName name, IBinder iBinder) {
163 | ShowToastS(MainActivity.this,"已连接到 UserService");
164 | service = IUserService.Stub.asInterface(iBinder);
165 | }
166 |
167 | @Override
168 | public void onServiceDisconnected(ComponentName name) {
169 | ShowToastS(MainActivity.this,"UserService 已断开链接");
170 | }
171 | });
172 | if (bind) return;
173 | ShowToastS(MainActivity.this,"start user service failed");
174 | }
175 | private boolean checkDelegatedScopes() {
176 | return new ArrayList<>(Arrays.asList(Dhizuku.getDelegatedScopes())).containsAll(Arrays.asList(REQUIRED_DELEGATED_SCOPES));
177 | }
178 |
179 | private void setDelegatedScopes() {
180 | if (checkDelegatedScopes()) return;
181 | Dhizuku.setDelegatedScopes(REQUIRED_DELEGATED_SCOPES);
182 | }
183 |
184 | public void ShowToastS(final Context context, final String text) {
185 | Toast.makeText(context, text, Toast.LENGTH_SHORT).show();
186 | }
187 | public void ShowToastL(final Context context, final String text) {
188 | Toast.makeText(context, text, Toast.LENGTH_LONG).show();
189 | }
190 |
191 | private String pkg2name(String pakeage){
192 | try {
193 | PackageManager packageManager = getPackageManager();
194 | ApplicationInfo applicationInfo = packageManager.getApplicationInfo(pakeage, 0);
195 | return packageManager.getApplicationLabel(applicationInfo).toString();
196 | // 在这里使用appName变量,即应用程序的名称
197 | } catch (PackageManager.NameNotFoundException e) {
198 | e.printStackTrace();
199 | return "";
200 | }
201 | }
202 |
203 | /****************
204 | *
205 | * 发起添加群流程。群号:IQOO⭐️交流群(262040855) 的 key 为: SqLJvDGqjKNDvc_O5dx6A164eLSo4QBG
206 | * 调用 joinQQGroup(SqLJvDGqjKNDvc_O5dx6A164eLSo4QBG) 即可发起手Q客户端申请加群 IQOO⭐️交流群(262040855)
207 | *
208 | * @param key 由官网生成的key
209 | * @return 返回true表示呼起手Q成功,返回false表示呼起失败
210 | ******************/
211 | private boolean joinQQGroup(String key) {
212 | Intent intent = new Intent();
213 | intent.setData(Uri.parse("mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26jump_from%3Dwebapi%26k%3D" + key));
214 | // 此Flag可根据具体产品需要自定义,如设置,则在加群界面按返回,返回手Q主界面,不设置,按返回会返回到呼起产品界面
215 | // intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
216 | try {
217 | startActivity(intent);
218 | return true;
219 | } catch (Exception e) {
220 | // 未安装手Q或安装的版本不支持
221 | return false;
222 | }
223 | }
224 |
225 |
226 | @Override
227 | public void onClick(View view) {
228 | int id = view.getId();
229 | String packageName = pkg_editText.getText().toString();
230 | String screen_text = screen_editText.getText().toString();
231 | String proxyinfo_text = proxyinfo_edit.getText().toString();
232 | if (id == R.id.block_uninstall) {
233 | if (!pkg2name(packageName).equals("")) {
234 | mDevicePolicyManager.setUninstallBlocked(componentName, packageName, true);
235 | ShowToastS(this, "已尝试限制 " + pkg2name(packageName) + " 卸载");
236 | } else {
237 | ShowToastS(this, "未安装此软件");
238 | }
239 | } else if (id == R.id.unblock_uninstall) {
240 | if (!pkg2name(packageName).equals("")) {
241 | mDevicePolicyManager.setUninstallBlocked(componentName, packageName, false);
242 | ShowToastS(this, "已尝试解除限制 " + pkg2name(packageName) + " 卸载");
243 | } else {
244 | ShowToastS(this, "未安装此软件");
245 | }
246 | } else if (id == R.id.check_unblock_uninstall) {
247 | if (!pkg2name(packageName).equals("")) {
248 | boolean pkg_block_status = mDevicePolicyManager.isUninstallBlocked(componentName, packageName);
249 | if (pkg_block_status){
250 | ShowToastS(this, pkg2name(packageName)+" 无法被卸载");
251 | } else {
252 | ShowToastS(this, pkg2name(packageName)+" 可以被卸载");
253 | }
254 | } else {
255 | ShowToastS(this, "未安装此软件");
256 | }
257 | } else if (id == R.id.change_screen_text){
258 | try {
259 | service.change_screen_text(screen_text);
260 | ShowToastS(this,"已设置锁屏提示文字为: "+screen_text);
261 | } catch (RemoteException e) {
262 | ShowToastS(this,"设置失败");
263 | }
264 | } else if (id == R.id.screen_capture_disabled){
265 | try {
266 | service.set_screen_capture(true);
267 | ShowToastS(this, "已尝试禁用截屏");
268 | } catch (RemoteException e) {
269 | ShowToastS(this, "禁用截屏失败");
270 | }
271 | } else if (id == R.id.screen_capture_enabled){
272 | try {
273 | service.set_screen_capture(false);
274 | ShowToastS(this, "已尝试启用截屏");
275 | } catch (RemoteException e) {
276 | ShowToastS(this, "启用截屏失败");
277 | }
278 | } else if (id == R.id.camera_disabled){
279 | try {
280 | service.set_camera_capture(true);
281 | ShowToastS(this, "已尝试禁用相机");
282 | } catch (RemoteException e) {
283 | ShowToastS(this, "禁用相机失败");
284 | }
285 | } else if (id == R.id.camera_enabled){
286 | try {
287 | service.set_camera_capture(false);
288 | ShowToastS(this, "已尝试启用相机");
289 | } catch (RemoteException e) {
290 | ShowToastS(this, "启用相机失败");
291 | }
292 | } else if (id == R.id.user_restriction_enabled){
293 | try {
294 | service.add_user_restriction(UserRestriction);
295 | ShowToastS(this, "已尝试禁用"+selectedItem);
296 | if (Objects.equals(selectedItem, "安装APP")) {
297 | ShowToastL(this,"开启此限制后千万不要取消激活Dhizuku并卸载, 不然你就只能双清了");
298 | }
299 | } catch (RemoteException e) {
300 | ShowToastS(this, "禁用"+selectedItem+"失败");
301 | }
302 | } else if (id == R.id.user_restriction_disabled){
303 | try {
304 | service.clear_user_restriction(UserRestriction);
305 | ShowToastS(this, "已尝试启用"+selectedItem);
306 | } catch (RemoteException e) {
307 | ShowToastS(this, "启用"+selectedItem+"失败");
308 | }
309 | } else if (id == R.id.set_global_proxy_address){
310 | try {
311 | // // 使用冒号分隔字符串
312 | // String[] parts = proxyinfo_text.split(":");
313 | // // 获取主机和端口
314 | // String host = parts[0];
315 | // String portString = parts[1];
316 | // // 将端口字符串转换为 int 类型
317 | // int port = Integer.parseInt(portString);
318 | //
319 | // proxyInfo = ProxyInfo.buildDirectProxy(host, port);
320 | service.set_global_proxy(proxyinfo_text);
321 | ShowToastS(this, "已尝试将全局代理设置为" + proxyinfo_text);
322 | } catch (RemoteException e) {
323 | ShowToastS(this, "设置失败");
324 | }
325 |
326 | } else if (id == R.id.set_org_name){
327 | try {
328 | service.set_org_name(screen_text);
329 | ShowToastS(this,"已设置组织名为: "+screen_text);
330 | } catch (RemoteException e) {
331 | ShowToastS(this,"设置失败");
332 | }
333 | } else if (id == R.id.join){
334 | boolean is_join_succeed = joinQQGroup("SqLJvDGqjKNDvc_O5dx6A164eLSo4QBG");
335 | if (!is_join_succeed){
336 | Toast.makeText(this,"未安装手Q或安装的版本不支持",Toast.LENGTH_SHORT).show();
337 | }
338 | }
339 | }
340 | }
341 |
342 |
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/dpm/UserService.java:
--------------------------------------------------------------------------------
1 | package com.itos.dpm;
2 | import android.app.admin.DevicePolicyManager;
3 | import android.content.Context;
4 | import android.net.ProxyInfo;
5 | import android.net.Uri;
6 | import android.os.RemoteException;
7 |
8 | //import androidx.annotation.Keep;
9 |
10 | import com.rosan.dhizuku.shared.DhizukuVariables;
11 |
12 | public class UserService extends IUserService.Stub{
13 | private Context context;
14 | private DevicePolicyManager devicePolicyManager;
15 |
16 | //@Keep
17 | public UserService(Context context) {
18 | this.context = context;
19 | devicePolicyManager = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
20 | }
21 | @Override
22 | public void onCreate() {
23 | }
24 | @Override
25 | public void onDestroy() {
26 |
27 | }
28 | @Override
29 | public void change_screen_text(String text) {
30 | devicePolicyManager.setDeviceOwnerLockScreenInfo(DhizukuVariables.COMPONENT_NAME, text);
31 | }
32 | @Override
33 | public void set_screen_capture(boolean x) {
34 | devicePolicyManager.setScreenCaptureDisabled(DhizukuVariables.COMPONENT_NAME, x);
35 | }
36 |
37 | @Override
38 | public void set_camera_capture(boolean x) {
39 | devicePolicyManager.setCameraDisabled(DhizukuVariables.COMPONENT_NAME, x);
40 | }
41 |
42 | @Override
43 | public void set_org_name(String text) {
44 | devicePolicyManager.setOrganizationName(DhizukuVariables.COMPONENT_NAME, text);
45 | }
46 |
47 | @Override
48 | public void add_user_restriction(String key) {
49 | devicePolicyManager.addUserRestriction(DhizukuVariables.COMPONENT_NAME, key);
50 | }
51 |
52 | @Override
53 | public void clear_user_restriction(String key) {
54 | devicePolicyManager.clearUserRestriction(DhizukuVariables.COMPONENT_NAME, key);
55 | }
56 |
57 | // @Override
58 | // public void set_global_proxy(ProxyInfo proxyinfo) throws RemoteException {
59 | // devicePolicyManager.setRecommendedGlobalProxy(DhizukuVariables.COMPONENT_NAME, proxyinfo);
60 | // }
61 | @Override
62 | public void set_global_proxy(String url) {
63 | ProxyInfo proxy = null;
64 | if (!url.isEmpty()) { // 如果 url 不为空
65 | if (url.startsWith("http") || url.startsWith("https")) { // 如果 url 以 "http" 或 "https" 开头
66 | Uri uri = Uri.parse(url); // 解析 url
67 | proxy = ProxyInfo.buildPacProxy(uri); // 构建 PAC 代理
68 | } else { // 如果 url 不以 "http" 或 "https" 开头
69 | String[] urlElements = url.split(":"); // 使用冒号分隔 url
70 | if (urlElements.length != 2) return; // 如果分隔结果不为 2 个元素,则返回
71 | proxy = ProxyInfo.buildDirectProxy(urlElements[0], Integer.parseInt(urlElements[1])); // 构建直连代理
72 | }
73 | devicePolicyManager.setRecommendedGlobalProxy(DhizukuVariables.COMPONENT_NAME, proxy);
74 | } else {
75 | devicePolicyManager.setRecommendedGlobalProxy(DhizukuVariables.COMPONENT_NAME, null);
76 | }
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/app/src/main/java/com/itos/dpm/dhizuku.java:
--------------------------------------------------------------------------------
1 | package com.itos.dpm;
2 |
3 | import android.app.Activity;
4 | import android.app.AlertDialog;
5 | import android.content.Context;
6 | import android.graphics.Color;
7 | import android.graphics.drawable.GradientDrawable;
8 | import android.os.Handler;
9 | import android.os.Looper;
10 | import android.view.View;
11 | import android.widget.Toast;
12 | import android.content.Intent;
13 | import android.net.Uri;
14 | import android.content.ActivityNotFoundException;
15 |
16 | import com.rosan.dhizuku.api.Dhizuku;
17 |
18 | public class dhizuku {
19 |
20 |
21 | private static Activity activity;
22 | private static AlertDialog dialog;
23 |
24 |
25 | // public static void initialize(Context c) {
26 | // if (Dhizuku.init()) {
27 | // Toast.makeText(c, "Dhizuku已授权", Toast.LENGTH_SHORT).show();
28 | // } else {
29 | //
30 | // }
31 | // }
32 |
33 | public static void setActivity(Activity activity) {
34 | dhizuku.activity = activity;
35 | }
36 |
37 | public static void showDialog(String message) {
38 | AlertDialog.Builder builder = new AlertDialog.Builder(activity);
39 | builder.setTitle("Dhizuku异常");
40 | builder.setMessage(message);
41 | builder.setPositiveButton("下载Dhizuku最新版 (密码9g7p)", (dialog, which) -> {
42 | Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://iamr0s.lanzoul.com/b02ki3edg"));
43 | activity.startActivity(intent);
44 | activity.finish();
45 | });
46 | builder.setNegativeButton("加入QQ群", (dialog, which) -> {
47 | Uri uri = Uri.parse("mqqapi://card/show_pslcard?src_type=internal&version=1&uin=262040855&card_type=group&source=qrcode");
48 | try {
49 | activity.startActivity(new Intent(Intent.ACTION_VIEW, uri));
50 | activity.finish();
51 | } catch (ActivityNotFoundException e) {
52 | Toast.makeText(activity, "未安装QQ或版本不支持", Toast.LENGTH_SHORT).show();
53 | }
54 | });
55 | builder.setCancelable(false);
56 | dialog = builder.create();
57 | View dialogView = dialog.getWindow().getDecorView();
58 | GradientDrawable drawable = new GradientDrawable();
59 | drawable.setCornerRadius(45);
60 | drawable.setColor(Color.WHITE);
61 | dialogView.setBackground(drawable);
62 | dialog.show();
63 | final Handler handler = new Handler(Looper.getMainLooper());
64 | handler.postDelayed(() -> {
65 | if (dialog != null && dialog.isShowing()) {
66 | dialog.dismiss();
67 | activity.finish();
68 | }
69 | }, 5000);
70 | }
71 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/DPM_Operate/78a2647b9c7bb9413f49dabd3629fc20215b3821/app/src/main/res/drawable/icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/owner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/DPM_Operate/78a2647b9c7bb9413f49dabd3629fc20215b3821/app/src/main/res/drawable/owner.png
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
21 |
22 |
23 |
24 |
27 |
28 |
32 |
37 |
44 |
45 |
52 |
53 |
60 |
69 |
70 |
74 |
75 |
78 |
79 |
84 |
91 |
98 |
99 |
108 |
111 |
119 |
128 |
131 |
137 |
138 |
145 |
146 |
153 |
154 |
155 |
160 |
161 |
168 |
169 |
176 |
177 |
180 |
186 |
187 |
192 |
200 |
208 |
209 |
212 |
213 |
214 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #009688
4 | #00796B
5 | #FF9800
6 | #F4A7B9
7 | #deb179
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 请安装或启动 Dhizuku 应用程序,然后重新启动本APP。
4 | 请同意 Dhizuku 的权限请求。
5 | Block Uninstall App
6 | Unblock Uninstall App
7 | Disable App
8 | Enable App
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/device_admin.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | plugins {
3 | id 'com.android.application' version '7.4.2' apply false
4 | id 'com.android.library' version '7.4.2' apply false
5 | }
6 | dependencies {
7 |
8 | }
--------------------------------------------------------------------------------
/device_owner.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/DPM_Operate/78a2647b9c7bb9413f49dabd3629fc20215b3821/device_owner.zip
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | ## For more details on how to configure your build environment visit
2 | # http://www.gradle.org/docs/current/userguide/build_environment.html
3 | #
4 | # Specifies the JVM arguments used for the daemon process.
5 | # The setting is particularly useful for tweaking memory settings.
6 | # Default value: -Xmx1024m -XX:MaxPermSize=256m
7 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
8 | #
9 | # When configured, Gradle will run in incubating parallel mode.
10 | # This option should only be used with decoupled projects. More details, visit
11 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
12 | # org.gradle.parallel=true
13 | #Mon Mar 13 17:56:20 CST 2023
14 | android.nonTransitiveRClass=true
15 | android.overridePathCheck=true
16 | org.gradle.jvmargs=-Xmx1536M -Dkotlin.daemon.jvm.options\="-Xmx2048M" -Dfile.encoding\=UTF-8
17 | android.useAndroidX=true
18 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ItosEO/DPM_Operate/78a2647b9c7bb9413f49dabd3629fc20215b3821/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Mar 09 20:08:22 CST 2023
2 | distributionBase=GRADLE_USER_HOME
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
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:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | gradlePluginPortal()
6 | }
7 | }
8 | dependencyResolutionManagement {
9 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
10 | repositories {
11 | google()
12 | mavenCentral()
13 | }
14 | }
15 | rootProject.name = "device_owner"
16 | include ':app'
17 |
--------------------------------------------------------------------------------