博客
关于我
android 7.1 FileObserver 使用过程的大坑
阅读量:285 次
发布时间:2019-03-01

本文共 2965 字,大约阅读时间需要 9 分钟。

在Android开发中,最近我遇到了一个有趣的问题:如何在屏幕熄灭后,通过监控按键来启动特定的应用。这个功能涉及到文件监听、权限管理以及系统级的修改,过程中遇到了不少挑战。

1. 权限问题:FileObserver的痛点

FileObserver是一个强大的工具,能够监听文件系统的变化。但在实际使用中,最大的问题莫过于权限管理。Android系统提供了两种权限:一种是对SD卡的读写权限,另一种是对系统API的权限。如果不正确处理这两种权限,应用可能会出现无法运行或被系统禁止运行的情况。

2. 系统修改:SE政策的调整

为了实现需要在系统休眠状态下创建文件和文件夹,我需要修改SE(安全引蒙)政策。具体来说,我需要在system/sepolicy目录下修改相关的权限规则。这涉及到编译boot.img,并将修改后的规则应用到系统中。例如,在system_server.te文件中,我需要添加允许系统服务器创建和修改文件的权限。

```xmlallow system_server fuse:dir { open read write add_name };```

这条规则允许系统服务器对FUSE文件系统下的目录进行读写和添加名称操作。

3. 按键监控与广播发送

为了实现按键监控,我选择在phonewindowmanger中添加键事件监听逻辑。当检测到特定的按键(如电源键)被按下时,系统会启动相应的监听逻辑。具体来说,我在键事件处理中,检查SD卡是否已经mounted。如果SD卡存在,并且按键被按下,我会在指定的路径下创建文件,并通过广播通知其他应用。

```javaif (keyCode == 139) { if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { // 检查SD卡是否存在并创建文件 File rscjafile = new File("/sdcard/rscja"); File txtFile = new File("/sdcard/rscja/key.txt"); if (!rscjafile.exists()) { rscjafile.mkdirs(); } // 写入文件 try { FileOutputStream outputStream = new FileOutputStream(txtFile); outputStream.write("1".getBytes()); outputStream.close(); } catch (IOException e) { e.printStackTrace(); } // 发送广播 Intent myKeyIntent = new Intent(); myKeyIntent.setAction("com.KEY_DOWN"); myKeyIntent.putExtra("keycode", keyCode); mContext.sendBroadcastAsUser(myKeyIntent, UserHandle.ALL); }}

4. 权限申请与处理

在应用运行时,权限申请是必不可少的。为了确保应用能正常运行,我需要动态申请WRITE_EXTERNAL_STORAGE和READ_EXTERNAL_STORAGE权限。如果用户拒绝权限申请,我需要提示用户并引导其前往设置页面进行权限管理。

```java@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (requestCode == 1) { for (int i = 0; i < permissions.length; i++) { if (grantResults[i] == PERMISSION_GRANTED) { Toast.makeText(this, "权限申请成功", Toast.LENGTH_SHORT).show(); } else { if (!ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])) { // 强制显示提示 AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("权限提示") .setMessage("请允许应用访问外部存储空间") .setPositiveButton("设置", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { startActivityForResult(new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS), NOT_NOTICE); } }); mDialog = builder.create(); mDialog.show(); } else { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("权限提示") .setMessage("请允许应用访问外部存储空间") .setPositiveButton("允许", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); } }); alertDialog = builder.create(); alertDialog.show(); } } } }}

5. 系统签名与APK发布

在Android 7.1及以上版本中,系统应用需要签名才能正常运行。如果我的应用需要修改系统级的权限或文件,我需要生成签名后的APK文件。签名APK的方法如下:

```bashjava -Djava.library.path=. -jar signapk.jar platform.x509.pem platform.pk8 app-debug.apk app_sign.apk```

6. 总结

通过以上方法,我成功实现了在屏幕熄灭后,通过监控按键并发送广播启动应用的功能。这个过程涉及到FileObserver的使用、权限管理、系统级权限调整以及按键事件处理等多个方面。虽然过程复杂,但通过一步步的尝试和修改,最终达到了预期效果。

转载地址:http://yazo.baihongyu.com/

你可能感兴趣的文章
python基础---->常用模块
查看>>
Python基础(2):控制结构
查看>>
Python基础 | 关于“循环”那些事
查看>>
python系列【仅供参考】:python之subprocess模块rsync拉取文件
查看>>
python系列【仅供参考】:python 远程rdp
查看>>
python基础
查看>>
Python基本语法与变量类型
查看>>
python基本数据类型(容器)- tuple list dict set
查看>>
python基本工资的调整方案_Python薪资又涨了!这可咋办!
查看>>
Python基准测试和性能分析内存管理和垃圾回收
查看>>
Python基于RESTful风格的接口自动化测试实战
查看>>
python基于flask搭建http服务(四)—— Docker容器化部署
查看>>
python基于flask搭建http服务(二)—— 实现Excel上传、数据清洗、入库
查看>>
python基于flask搭建http服务(三)—— 使用gunicorn部署项目
查看>>
python基于flask搭建http服务(一)—— 实现数据查询和Excel导出
查看>>
Python块键盘/鼠标输入
查看>>
python在心理学研究中的应用有哪些_心理学在线研究可用平台简介和应用进展
查看>>
python在使用HTMLTestRunner时,报告为空,错误提示<_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf_8'>...
查看>>
python在gpu上运行_【python】python开启GPU加速
查看>>
Python在def函数中使用for循环
查看>>