zoukankan      html  css  js  c++  java
  • 应用程序实现关闭屏幕

    感谢:http://www.cnblogs.com/chenyg32/p/3719714.html

    本文是从网上找来的,我自己进行了修改和优化。主要用到了系统的设备管理器,是个可以抛砖引玉的程序。需要说明的是,一旦应用激活了设备管理器,那么在卸载钱必须要取消激活。这点可以用来防止被恶意卸载。

    下面开始上代码:

    1.在Manifest中写上receiver需要设备管理器的方式

     <!-- 设备管理 -->  
            <!-- 其中,permission表示此功能所需的权限;
            android:name="android.app.device_admin"表示这个动作的跳转界面 -->
             <receiver
                android:name=".AdminReceiver"
                android:label="@string/app_name"
                android:description="@string/app_name"
                android:permission="android.permission.BIND_DEVICE_ADMIN">
                <meta-data
                    android:name="android.app.device_admin"
                    android:resource="@xml/lock"/>
                <intent-filter>
                    <action
                        android:name="android.app.action.DEVICE_ADMIN_ENABLED"/>
                </intent-filter>
            </receiver>

    其中,resource是说明设备管理器中需要的权限。于是我在xml文件夹中写上了下面的文件。这里可以有多种权限,设置可以直接进入系统的锁屏界面。具体自己Google吧

    <?xml version="1.0" encoding="UTF-8"?>
    <device-admin
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <uses-policies>
            <!--强制锁屏-->
            <force-lock/>
        </uses-policies>
    </device-admin>

    这里面定义的receive其实就是继承了设备管理的广播类,没写代码

    package com.kale.kalelock;
    
    import android.app.admin.DeviceAdminReceiver;
    
    /**
     * @author:Jack Tony
     * @tips  :这个类的父类是BroadcastReceiver,通过其OnReceive方法可以根据不同的Action执行不同的动作。
     * @date  :2014-8-10
     */
    public class AdminReceiver extends DeviceAdminReceiver{
    
    }

    全部的Manifest

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.kale.kalelock"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="18" />
    
        <application
            android:allowBackup="true"
            android:icon="@drawable/lock"
            android:label="@string/app_name"
            android:theme="@android:style/Theme.Translucent" >
            <activity
                android:name=".MainActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <!-- 设备管理 -->  
            <!-- 其中,permission表示此功能所需的权限;
            android:name="android.app.device_admin"表示这个动作的跳转界面 -->
             <receiver
                android:name=".AdminReceiver"
                android:label="@string/app_name"
                android:description="@string/app_name"
                android:permission="android.permission.BIND_DEVICE_ADMIN">
                <meta-data
                    android:name="android.app.device_admin"
                    android:resource="@xml/lock"/>
                <intent-filter>
                    <action
                        android:name="android.app.action.DEVICE_ADMIN_ENABLED"/>
                </intent-filter>
            </receiver>
        </application>
    
    </manifest>

    MainActivity

    package com.kale.kalelock;
    
    import android.app.Activity;
    import android.app.admin.DevicePolicyManager;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Bundle;
    
    public class MainActivity extends Activity {
    
        /**
         * DevicePolicyManager 顾名思义,这个类的作用是管理设备。通过这个类,我们可以实现屏幕锁定、亮度调节甚至是恢复出厂设置等功能。
         */
        private DevicePolicyManager policyManager;
        private ComponentName componentName;
        private static final int MY_REQUEST_CODE = 9999;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            // 获取设备管理服务
            policyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
            // ComponentName这个我们在用intent跳转的时候用到过。
            // 自己的AdminReceiver 继承自 DeviceAdminReceiver
            componentName = new ComponentName(this, AdminReceiver.class);
            /*
             * 假如先判断是否有权限,如果没有则调用activeManage(),然后立即锁屏,最后再finish()。
             * 这样做是有问题的,因为activeManage()可能还在等待另一个Activity的结果,那么此时依然没有权限却
             * 执行了lockNow(),这样就出错了。 处理方法有2个:
             * 1、是重写OnActivityResult()函数,在里面判断是否获取权限成功,是则锁屏并finish()
             * 否则继续调用activeManage()获取权限(这样激活后立即锁屏,效果很好)
             * 2、不重写OnActivityResult()函数,第一次获取权限后不锁屏而立即finish(),这样从理论上说也可能
             * 失败,可能权限还没获取好就finish了(这样激活后就回到桌面,还得再按一次锁屏才能锁) 综上推荐第一种方法。
             */
    
            // 判断是否有锁屏权限,若有则立即锁屏并结束自己,若没有则获取权限
            if (policyManager.isAdminActive(componentName)) {
                policyManager.lockNow();// 锁屏
                finish();
            } else {
                activeManage(); //获取权限
            }
            //setContentView(R.layout.activity_main); // 把这句放在最后,这样锁屏的时候就不会跳出来(闪一下)
        }
        /**
         * 获取权限 
         */
        private void activeManage() {
            // 启动设备管理(隐式Intent) - 在AndroidManifest.xml中设定相应过滤器
            Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
    
            // 权限列表
            intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, componentName);
    
            // 描述(additional explanation) 在申请权限时出现的提示语句
            intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
                    "激活后就能一键锁屏了");
    
            startActivityForResult(intent, MY_REQUEST_CODE);
        }
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            // 获取权限成功,立即锁屏并finish自己,否则继续获取权限
            if (requestCode == MY_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
                policyManager.lockNow();
                finish();
            } else {
                //activeManage();
                finish();
            }
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

    原文中有闪屏的解决办法,我这里直接设置Acitvity没有布局文件,并且在Manifest中的Application标签下写了如下主题:

    android:theme="@android:style/Theme.Translucent" >

    原文的解决办法如下:

    而最难的部分在于,当打开软件的时候,该软件会出现闪屏(闪现标题栏),然后才锁屏。

    一个比较好的解决方法是把该Activity设置为透明的,这样即使出现标题栏也看不到。

    网上大部分代码是这样解决的,在配置文件中,为Activity标签添加一个属性android:theme=@android:style/Theme.Translucent

    但是由于我新建项目的时候为该项目选择了系统自带的主题(Theme.AppCompat.Light.DarkActionBar),所以配置文件中,Application标签已经声明了主题(见下图),如果继续在Activity中添加主题的话会运行出错!

    OK,那我把Application的主题删了,只为Activity配置透明主题行了吧………………可是还是运行出错!没深入研究过Android,所以不知怎么会这样……

    最后磕磕碰碰,摸索出一个方法,修改Application的主题,添加下面2句(只添加1句透明的应该也行,没试过)

    至此,终于不再闪屏了……

    源码下载:http://download.csdn.net/detail/shark0017/7778991

  • 相关阅读:
    输入流输出流
    WIN32_FIND_DATA
    typeid
    为什么要内存对齐 Data alignment: Straighten up and fly right
    fatal error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "stdafx.h
    memcmp
    DPI
    英寸、 Picas、 点、 跨度和 Twips 之间的关系
    如何解决 “fatal error C1083: ”无法打开包括文件
    hdoj 1269迷宫城堡解题报告
  • 原文地址:https://www.cnblogs.com/tianzhijiexian/p/3920257.html
Copyright © 2011-2022 走看看