應用程序實現關閉屏幕


感謝: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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM