博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android 7.1 FileObserver 使用过程的大坑
阅读量:279 次
发布时间:2019-03-01

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

最近开发一种功能,在屏幕熄灭之后,监控按键,然后发广播,启动某些应用。  

 FileObserver 使用过程的大坑 就是权限!两种权限,一种是SD卡的读写权限,一种是android 系统使用这个API的权限

 

另外,如果想在系统休眠的时候,创建文件和文件夹,需要修改 SE权限,这部分在system/sepolicy ,然后编译boot.img

system/sepolicy$ svn diff .Index: system_server.te===================================================================--- system_server.te    (revision 147)+++ system_server.te    (working copy)@@ -547,9 +547,14 @@  # Do not allow opening files from external storage as unsafe ejection # could cause the kernel to kill the system_server.-neverallow system_server sdcard_type:dir { open read write };-neverallow system_server sdcard_type:file rw_file_perms;+allow system_server sdcard_type:dir { open read write add_name  create_dir_perms};+allow system_server sdcard_type:file {rw_file_perms create_file_perms rename}; ++# avc: denied { add_name } for name="rscjakey2.txt" scontext=u:r:system_server:s0 tcontext=u:object_r:fuse:s0 tclass=dir permissive=0+#avc: denied { write } for name="0" dev="fuse" ino=1 scontext=u:r:system_server:s0 tcontext=u:object_r:fuse:s0 tclass=dir permissive=0+#allow system_server fuse:dir { open read write add_name  };+ # system server should never be opening zygote spawned app data # files directly. Rather, they should always be passed via a # file descriptor.

 

创建的过程是在phonewindowmanger里面的,监控按键,然后创建。

if (keyCode == 139  ) {            			Log.d(TAG, "5910KeyEvent.KEYCODE_POWER=" + keyCode);			if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {				Environment.setUserRequired(false);								File rscjafile = new File ("/sdcard/rscja");				File txtFile = new File ("/sdcard/rscja/key.txt");				Log.i("keyCode ssss1111 5921 ", " sssssssstxtFile.exists() ="+txtFile.exists());								if(down) {						try {							Log.i("keyCode ssss1111 5925 ", " sssssssstxtFile.exists() ="+rscjafile.exists());							if (!rscjafile.exists()) {								rscjafile.mkdirs();								Log.i("keyCode ssss1111 5928", " sssssssstxtFile.exists() ="+rscjafile.exists());							}							Log.i("keyCode ssss 5919 ", " sssssssstxtFile.exists(22222) ="+txtFile.exists());							FileOutputStream outputStream = new FileOutputStream(txtFile);							outputStream.write("1".getBytes());							outputStream.close();						} catch (IOException e) {							e.printStackTrace();						}				 }else {					 try {							Log.i("keyCode ssss 5931 ", " sssssssstxtFile.exists(22222) ="+txtFile.exists());							FileOutputStream outputStreamup = new FileOutputStream(txtFile);							outputStreamup.write("0".getBytes());							outputStreamup.close();						} catch (IOException e) {							e.printStackTrace();						} 				 }			}			     if (repeatCountvv == 0) {                    Intent myKeyIntent = new Intent();                    if(down) {                        myKeyIntent.setAction("com.KEY_DOWN");                    }                    else {                        myKeyIntent.setAction("com.EY_UP");                    }                    myKeyIntent.putExtra("keycode", keyCode);                    mContext.sendBroadcastAsUser(myKeyIntent, UserHandle.ALL);                }													                    return 0;        }

 

先贴代码

package com.chww.androidfilelistener;import android.Manifest;import android.app.Activity;import android.app.AlertDialog;import android.content.Context;import android.content.DialogInterface;import android.content.Intent;import android.net.Uri;import android.os.Bundle;import android.os.Environment;import android.os.FileObserver;import android.provider.Settings;import android.support.v4.app.ActivityCompat;import android.support.v4.content.ContextCompat;import android.widget.Toast;import static android.content.pm.PackageManager.PERMISSION_GRANTED;public class AndroidFileListenerActivity extends Activity {    private FileObserver mFileObserver;    private FileObserver multiFileObserver;    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        myRequetPermission();        if(null == mFileObserver) {            mFileObserver = new SDCardFileObserver(getApplicationContext(),Environment.getExternalStorageDirectory().getPath()+"/recja/");           mFileObserver.startWatching(); //开始监听        }    }    static class SDCardFileObserver extends FileObserver {        //mask:指定要监听的事件类型,默认为FileObserver.ALL_EVENTS        public SDCardFileObserver(String path, int mask) {            super(path, mask);        }        public SDCardFileObserver(Context ct, String path) {            super(path);        }        @Override        public void onEvent(int event, String path) {            final int action = event & FileObserver.ALL_EVENTS;            switch (action) {                case FileObserver.ACCESS:                    System.out.println("event: 文件或目录被访问, path: " + path);                    break;                case FileObserver.DELETE:                    System.out.println("event: 文件或目录被删除, path: " + path);                    break;                case FileObserver.OPEN:                    System.out.println("event: 文件或目录被打开, path: " + path);                    break;                case FileObserver.MODIFY:                    System.out.println("event: 文件或目录被修改, path: " + path);                    break;                case FileObserver.CREATE:                    System.out.println("event: 文件或目录被创建, path: " + path);                    break;            }        }    }    private void myRequetPermission() {        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PERMISSION_GRANTED) {            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE}, 1);        }else {            Toast.makeText(this,"您已经申请了权限!",Toast.LENGTH_SHORT).show();        }    }    private static final int NOT_NOTICE = 2;//如果勾选了不再询问    private AlertDialog alertDialog;    private AlertDialog mDialog;    @Override    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {        super.onRequestPermissionsResult(requestCode, permissions, grantResults);        if (requestCode == 1) {            for (int i = 0; i < permissions.length; i++) {                if (grantResults[i] == PERMISSION_GRANTED) {//选择了“始终允许”                    Toast.makeText(this, "" + "权限" + permissions[i] + "申请成功", Toast.LENGTH_SHORT).show();                } else {                    if (!ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])){//用户选择了禁止不再询问                        AlertDialog.Builder builder = new AlertDialog.Builder(this);                        builder.setTitle("permission")                                .setMessage("点击允许才可以使用我们的app哦")                                .setPositiveButton("去允许", new DialogInterface.OnClickListener() {                                    public void onClick(DialogInterface dialog, int id) {                                        if (mDialog != null && mDialog.isShowing()) {                                            mDialog.dismiss();                                        }                                        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);                                        Uri uri = Uri.fromParts("package", getPackageName(), null);//注意就是"package",不用改成自己的包名                                        intent.setData(uri);                                        startActivityForResult(intent, NOT_NOTICE);                                    }                                });                        mDialog = builder.create();                        mDialog.setCanceledOnTouchOutside(false);                        mDialog.show();                    }else {//选择禁止                        AlertDialog.Builder builder = new AlertDialog.Builder(this);                        builder.setTitle("permission")                                .setMessage("点击允许才可以使用我们的app哦")                                .setPositiveButton("去允许", new DialogInterface.OnClickListener() {                                    public void onClick(DialogInterface dialog, int id) {                                        if (alertDialog != null && alertDialog.isShowing()) {                                            alertDialog.dismiss();                                        }                                        ActivityCompat.requestPermissions(AndroidFileListenerActivity.this,                                                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);                                    }                                });                        alertDialog = builder.create();                        alertDialog.setCanceledOnTouchOutside(false);                        alertDialog.show();                    }                }            }        }    }    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        if(requestCode==NOT_NOTICE){            myRequetPermission();//由于不知道是否选择了允许所以需要再次判断        }    }}

 

 

配置文件

 

 

 

总结,有很多APK 是需要  android:sharedUserId="android.uid.system" 这个权限才能去做一些事情的~搞了几天才发现的。

没有任何提示啊~~!方向都找不到,只能猜

android 7.1的签名APK 方法

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

 

demo已经上传

怎么不能设置免积分了。

 

 

 

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

你可能感兴趣的文章