博客
关于我
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/

你可能感兴趣的文章
Node-RED中Switch开关和Dropdown选择组件的使用
查看>>
Node-RED中使用html节点爬取HTML网页资料之爬取Node-RED的最新版本
查看>>
Node-RED中使用JSON数据建立web网站
查看>>
Node-RED中使用json节点解析JSON数据
查看>>
Node-RED中使用node-random节点来实现随机数在折线图中显示
查看>>
Node-RED中使用node-red-browser-utils节点实现选择Windows操作系统中的文件并实现图片预览
查看>>
Node-RED中使用node-red-contrib-image-output节点实现图片预览
查看>>
Node-RED中使用node-red-node-ui-iframe节点实现内嵌iframe访问其他网站的效果
查看>>
Node-RED中使用Notification元件显示警告讯息框(温度过高提示)
查看>>
Node-RED中使用range范围节点实现从一个范围对应至另一个范围
查看>>
Node-RED中实现HTML表单提交和获取提交的内容
查看>>
Node-RED中将CSV数据写入txt文件并从文件中读取解析数据
查看>>
Node-RED中建立TCP服务端和客户端
查看>>
Node-RED中建立Websocket客户端连接
查看>>
Node-RED中建立静态网页和动态网页内容
查看>>
Node-RED中解析高德地图天气api的json数据显示天气仪表盘
查看>>
Node-RED中连接Mysql数据库并实现增删改查的操作
查看>>
Node-RED中通过node-red-ui-webcam节点实现访问摄像头并截取照片预览
查看>>
Node-RED中配置周期性执行、指定时间阶段执行、指定时间执行事件
查看>>
Node-RED安装图形化节点dashboard实现订阅mqtt主题并在仪表盘中显示温度
查看>>