参考サイト
以下のページの内容を参考にしました。
Android Working with Lock Screen and Device Administration API
仕様書とかきちんと調べていないので、誤りがあるかもしれませんが、とりあえず動きます。
とりあえずやってみる
基本的には、DevicePolicyManagerのインスタンスを作って、lockNow()というメソドを呼べば良いです。ただ、色々設定があります。
とりあえず、EmptyActivityで雛形のプロジェクトを作って実験します。
ボタンを作って、押されたら LockScreen を呼ぶようにしておきます。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.ogilab.lockscreen.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:id="@+id/textView" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Lock Screen"
android:id="@+id/button"
android:layout_below="@+id/textView"
android:layout_alignParentStart="true"
android:layout_marginTop="23dp"
android:onClick="LockScreen" />
</RelativeLayout>
LockScreen()の中で、lockNow()を呼んでみます。
public class MainActivity extends AppCompatActivity {
private DevicePolicyManager mDevicePolicyManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDevicePolicyManager = (DevicePolicyManager)getSystemService(
Context.DEVICE_POLICY_SERVICE);
}
public void LockScreen(View view) {
Log.d("LockScreen", "LockScreen");
mDevicePolicyManager.lockNow();
}
}
これは駄目でした、、、。(アプリが異常終了します。)
真面目にやってみる
デバイスをロックするには、そのアプリが端末管理アプリであることを宣言して、かつ、ユーザがそのアプリが端末を管理して良いと許可しないといけません。(だいたい、そういうことらしい、、、)
端末管理アプリになるためには、DeviceAdminReceiverを継承したクラスが必要なので、とりあえず、Adminというクラスを作ります。
package com.ogilab.lockscreen;
import android.app.admin.DeviceAdminReceiver;
public class Admin extends DeviceAdminReceiver {
}
中身はなくても動きます。メソドをoverrideすれば、色々できそうですが、、。
このアプリができる端末操作を定義します。
resの下に、xmlというフォルダーを作り、その中に、admin.xmlというファイルを作ります。
<device-admin xmlns:android="http://schemas.android.com/apk/res/android" >
<uses-policies>
<watch-login />
<force-lock />
</uses-policies>
</dev>
watch-loginはいらないかも、、、。
このアプリが、端末管理アプリであることをAndroidManifest.xmlの中に記述します。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ogilab.lockscreen">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".Admin"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/admin"/>
<intent-filter>
<action
android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
</application>
</manifest>
追記しているのは、receiverのところです。
MainActivity.javaは、管理者権限がなかったら、追加する画面に移行するようなロジックを追記します。
package com.ogilab.lockscreen;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private static final int ADMIN_INTENT = 1;
private DevicePolicyManager mDevicePolicyManager;
private ComponentName mComponentName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDevicePolicyManager = (DevicePolicyManager)getSystemService(
Context.DEVICE_POLICY_SERVICE);
mComponentName = new ComponentName(this, Admin.class);
}
public void LockScreen(View view) {
Log.d("LockScreen", "LockScreen");
if (mDevicePolicyManager.isAdminActive(mComponentName)) {
mDevicePolicyManager.lockNow();
} else {
Log.d("LockScreen", "admin not active");
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mComponentName);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "Administrator description");
startActivityForResult(intent, ADMIN_INTENT);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == ADMIN_INTENT) {
if (resultCode == RESULT_OK) {
Toast.makeText(getApplicationContext(), "Registered As Admin", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getApplicationContext(), "Failed to register as Admin", Toast.LENGTH_SHORT).show();
}
}
}
@Override
protected void onResume() {
super.onResume();
Log.d("LockScreen", "onResume");
}
}
ロック画面から復帰すると、onResume()が呼ばれます。(それ以外の時も呼ばれる可能性があるので、何らかの判定が必要)
ちなみに、管理者権限がないと、ボタンを2回押さないといけません。そこは必要に応じて修正してください。
管理者権限は、設定のセキュリティの端末管理アプリの中でも変更できます。