[Android实例] 仿Easy Touch,实现Home键,锁屏,清理内存功能

该篇文章从eoeAndroid搬迁过来的,原文地址:[Android实例] 仿Easy Touch,实现Home键,锁屏,清理内存功能

有的时候我们会面临物理键失灵的情况,这个时候就需要用软件进行代替物理键,苹果有一款软件叫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);

至此,我的大部分代码已经复制粘贴完毕,本人比较懒,很多代码没注释,请见谅
这里写图片描述 这里写图片描述
下载地址:项目代码

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值