博客
关于我
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_STORAGEREAD_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 初学者需要知道的四条建议
查看>>
Python 判断字符串是否包含子字符串
查看>>
python 判断当前时间是否为零点
查看>>
python 利用pandas读取本地中CSV文件的指定列 列名重命名 并保存回本地
查看>>
python 利用pyspark读取HDFS中CSV文件的指定列 列名重命名 并保存回HDFS
查看>>
python 利用pyttsx3文字转语音
查看>>
python 利用已有Ner模型进行数据清洗合并
查看>>
python 到大数据开发工程师_如何成为一个大数据开发工程师?
查看>>
python 加密解密(base64, AES)
查看>>
Python 包管理器和 Node.js
查看>>
python 启动提示IDLE's subprocess didn't make conne...
查看>>
Python 和 OpenCV.如何检测图像中的所有(填充)圆形/圆形对象?
查看>>
Python 和 RabbitMQ - 聆听来自多个渠道的消费事件的最佳方式?
查看>>
python编辑器打不开_关于命令ride.py打不开RF,而是打开pycharm编辑器问题解决思路...
查看>>
python编译exe同时支持32位_第三周:同时管理64位和32位版本的Python,并用Pyinstaller打包成exe...
查看>>
Python 和Java 哪个更适合做自动化测试?
查看>>
Python编程:掌握高级语言程序设计。从零基础到精通,收藏这篇就够了!
查看>>
python 图片转ico
查看>>
python 图片转文字、语音转文字、文字转语音保存音频并朗读
查看>>