[Android实例] 仿Easy Touch,实现Home键,锁屏,清理内存功能
2016-01-04 16:45
531 查看
该篇文章从eoeAndroid搬迁过来的,原文地址:[Android实例] 仿Easy Touch,实现Home键,锁屏,清理内存功能
有的时候我们会面临物理键失灵的情况,这个时候就需要用软件进行代替物理键,苹果有一款软件叫Easy Touch,就是用来代替物理键功能的,而安卓同样也有一款相同名字的软件,在这里,我模仿android的Easy Touch做了部分功能,如实现Home键功能,锁屏和清理内存功能,可能有些不完善的地方,敬请见谅。
1.创建WindowManager窗口,需要设置为WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,即为系统级别的,这样的话,当打开其他应用程序的时候,我们的WindowManager窗口就会存在最上方
增加权限
由于Easy Touch有两种界面,一种是展示个小图标,另一种是点击小图标后呈现的功能操作界面,所以这里面我用的是同一个WindowManager窗口,不同的页面进行替换 小图标界面:
功能操作界面:
2.实现操作方法 点击小图标或移动小图标的监听事件:
home键:
锁屏键:
其中PowerAdminreceiver是集成DeviceAdminReceiver,不需要实现什么方法
AndroidManifest.xml里增加
在res/xml文件夹下增加lock_screen_admin.xml
清理内存:
增加权限
3.调用WindowManager窗口,由于我将该窗口封装成单例,所以使用方法如下
至此,我的大部分代码已经复制粘贴完毕,本人比较懒,很多代码没注释,请见谅
下载地址:项目代码
有的时候我们会面临物理键失灵的情况,这个时候就需要用软件进行代替物理键,苹果有一款软件叫Easy Touch,就是用来代替物理键功能的,而安卓同样也有一款相同名字的软件,在这里,我模仿android的Easy Touch做了部分功能,如实现Home键功能,锁屏和清理内存功能,可能有些不完善的地方,敬请见谅。
1.创建WindowManager窗口,需要设置为WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,即为系统级别的,这样的话,当打开其他应用程序的时候,我们的WindowManager窗口就会存在最上方
private void createWM() { windowManager = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE); layoutParams = new WindowManager.LayoutParams(); layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; layoutParams.format = PixelFormat.TRANSLUCENT; layoutParams.flags = WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; }
增加权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
由于Easy Touch有两种界面,一种是展示个小图标,另一种是点击小图标后呈现的功能操作界面,所以这里面我用的是同一个WindowManager窗口,不同的页面进行替换 小图标界面:
iconView = new Button(context); iconView.setBackgroundResource(R.drawable.selector_btn_launcher); layoutParams.alpha = 0.6f; layoutParams.x = iconViewX; layoutParams.y = iconViewY; layoutParams.width = 98; layoutParams.height = 98; layoutParams.gravity = Gravity.LEFT | Gravity.TOP; windowManager.addView(iconView, layoutParams);
功能操作界面:
mainView = LayoutInflater.from(context).inflate( R.layout.wm_main_layout, null); layoutParams.alpha = 1f; layoutParams.x = 0; layoutParams.y = 0; layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT; layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT; layoutParams.gravity = layoutParams.gravity = Gravity.LEFT | Gravity.TOP; windowManager.addView(mainView, layoutParams);
2.实现操作方法 点击小图标或移动小图标的监听事件:
iconView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub // 获取相对屏幕的坐标,即以屏幕左上角为原点 float rawX = event.getRawX(); // 为状态栏高度 Math.ceil(25 // * context.getResources().getDisplayMetrics().density)) float rawY = (float) (event.getRawY() - stateHeight); int sumX = (int) (rawX - startRawX); int sumY = (int) (event.getRawY() - startRawY); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // 获取相对View的坐标,即以此View左上角为原点 startX = event.getX(); startY = event.getY(); startRawX = event.getRawX(); startRawY = event.getRawY(); layoutParams.alpha = 1f; windowManager.updateViewLayout(iconView, layoutParams); break; case MotionEvent.ACTION_UP: Log.i("Log", "sumX=" + sumX + ";sumY=" + sumY); layoutParams.alpha = 0.6f; windowManager.updateViewLayout(iconView, layoutParams); if (sumX > -10 && sumX < 10 && sumY > -10 && sumY < 10) { addMainView(); } else { float endRawX = rawX - startX; float endRawY = rawY - startY; if (endRawX < width / 2) { if (endRawX > endRawY) { updateIconViewPosition(endRawX, 0); } else if (endRawX > height - event.getRawY() - 98) { updateIconViewPosition(endRawX, (float) (height - stateHeight - 98)); } else { updateIconViewPosition(0, endRawY); } } else { if (width - endRawX - 98 > endRawY) { updateIconViewPosition(endRawX, 0); } else if (width - endRawX - 98 > height - event.getRawY() - 98) { updateIconViewPosition(endRawX, (float) (height - stateHeight - 98)); } else { updateIconViewPosition(width - 98, endRawY); } } } startX = 0; startY = 0; startRawX = 0; startRawY = 0; break; case MotionEvent.ACTION_MOVE: if (sumX < -10 || sumX > 10 || sumY < -10 || sumY > 10) { updateIconViewPosition(rawX - startX, rawY - startY); } break; default: break; } return true; } }); }
home键:
Intent intent = new Intent(Intent.ACTION_MAIN); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addCategory(Intent.CATEGORY_HOME); activity.startActivity(intent);
锁屏键:
devicePolicyManager = (DevicePolicyManager)activity.getSystemService(Activity.DEVICE_POLICY_SERVICE); componentName = new ComponentName(activity,PowerAdminreceiver.class); if (devicePolicyManager.isAdminActive(componentName)) { devicePolicyManager.lockNow(); } else {// 第一次运行程序 Intent intent = new Intent( DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, componentName); intent.putExtra( DevicePolicyManager.EXTRA_ADD_EXPLANATION, "One key lock screen need to active"); activity.startActivity(intent); }
其中PowerAdminreceiver是集成DeviceAdminReceiver,不需要实现什么方法
AndroidManifest.xml里增加
<receiver android:name="com.example.windowmanagertest.PowerAdminreceiver" android:description="@string/app_name" android:label="@string/app_name" android:permission="android.permission.BIND_DEVICE_ADMIN" > <meta-data android:name="android.app.device_admin" android:resource="@xml/lock_screen_admin" /> <intent-filter> <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" /> </intent-filter> </receiver>
在res/xml文件夹下增加lock_screen_admin.xml
<?xml version="1.0" encoding="utf-8"?> <device-admin xmlns:android="http://schemas.android.com/apk/res/android" > <uses-policies> <limit-password /> <watch-login /> <reset-password /> <force-lock /> <wipe-data /> </uses-policies> </device-admin>
清理内存:
activityManager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE); currentProcessId = android.os.Process.myPid(); long buforeMemory = getAvailMemory(); int count = 0; RunningAppProcessInfo runningAppProcessInfo = null; List<RunningAppProcessInfo> runningAppProcessInfos = activityManager .getRunningAppProcesses(); if (runningAppProcessInfos != null) { for (int i = 0; i < runningAppProcessInfos.size(); ++i) { runningAppProcessInfo = runningAppProcessInfos .get(i); // 一般数值大于RunningAppProcessInfo.IMPORTANCE_SERVICE // 的进程即为长时间未使用进程或者空进程 // 一般数值大于RunningAppProcessInfo.IMPORTANCE_VISIBLE // 的进程都是非可见进程,即在后台运行 if (runningAppProcessInfo.importance > RunningAppProcessInfo.IMPORTANCE_VISIBLE && runningAppProcessInfo.pid != currentProcessId) { String[] pkgList = runningAppProcessInfo.pkgList; for (int j = 0; j < pkgList.length; ++j) { activityManager .killBackgroundProcesses(pkgList[j]); count++; } } } String str = "共结束" + count + "个进程;" + "清理" + (getAvailMemory() - buforeMemory) + "MB内存"; Toast.makeText(context, str, Toast.LENGTH_SHORT).show(); }
private long getAvailMemory() { MemoryInfo memoryInfo = new MemoryInfo(); activityManager.getMemoryInfo(memoryInfo); return memoryInfo.availMem / (1024 * 1024); }
增加权限
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
3.调用WindowManager窗口,由于我将该窗口封装成单例,所以使用方法如下
WMInstance.getInstance(this);
至此,我的大部分代码已经复制粘贴完毕,本人比较懒,很多代码没注释,请见谅
下载地址:项目代码
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories