キオスクアプリを作る

# キオスクアプリとは

専用アプリです。例えばタクシーの後部座席や、居酒屋のメニューを作る時に利用をしたい時使います。アプリが固定されていて、基本的にホームなどには戻れないようにします。

## ピンとはどう違うの？

ピンを使うとアプリが固定化でき、パスワードなどでのロックができますが、その画面が出ちゃうのが嫌だ。また、アプリを再起動したりしたら普通にホームから始まってしまって設定をする時に「ピンをしますか？」っていうのが出て設定をしなくてはいけない。

## Androidではどのような風に実装をするのか？

1: ピンをする時に確認のダイアログが出ないようにできるので、起動の時にアプリを立ち上げて、そのままピンをします。

2: ピンをプログラムからしか解除できないようにできます。

の2つをします。が、ここで問題があって、

**基本的に、パーミッションの問題で動作できません。でもルートは取らないで実装ができます。逆にユーザーへの配布アプリで実装方法は今のところ不明です。**

## 最初にセキュリティ解除用のプロフラムを用意します。

レシーバーを作成

```java:AdminReceiver.java
public class AdminReceiver extends DeviceAdminReceiver {
    @Override
    public void onEnabled(Context context, Intent intent) {
        super.onEnabled(context, intent);
    }
}
```
マニフェストに下記を設定

```xml:manifest
<receiver
	android:name=".AdminReceiver"
	android:label="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>
```

```xml:admin
<?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>
```

を用意します。

アプリをインストールします。

## adb shell を実行します。
```adb:adb
adb shell dpm set-device-owner yaya.tokyo.*****/.AdminReceiver
```

で成功：

```adb:adb
Success: Device owner set to package ComponentInfo{yaya.tokyo.***/yaya.tokyo.***.AdminReceiver}
Active admin set to component {yaya.tokyo.***/yaya.tokyo.***.AdminReceiver}
```

のはずが、失敗しました。

```adb:adb
java.lang.IllegalStateException: Not allowed to set the device owner because there are already some accounts on the device
```

## 失敗の原因

このプログラムを実行する時に工場からの出荷状態に戻す事と書いてあるリファレンスがあるのですが、戻したのに、失敗し続けました。

出荷状態に戻すのは、どういう意味かと言うと、「この端末のオーナーに君意外が既にアカウントを持っているよ」という意味で、そのオーナー情報を消してほしいという意味なようです。

で、なぜ失敗し続けたのか。というと、「docomo softbank au」のアカウントが工場出荷状態で登録されています

キオスクアプリという性質上キャリアのアカウントを削除してしまいましょう。手元にあったのがドコモの端末だったのでドコモのアプリを設定-アプリから消す&無効をするのですが、できないアプリがいくつもありました。adbから消せるらしいというので

一覧表示　[参照](https://www.orefolder.net/blog/2017/01/adb-app-hide/)

```adb:adb
adb shell pm list packages -s
```

で

```adb:adb
adb shell pm hide com.nttdocomo.android.remotelock
Error: java.lang.SecurityException: Neither user 2000 nor current process has android.permission.MANAGE_USERS.
```

消えない。　ROOTを取ると消えるそうです、もしくはandroidのバージョンによっては消えるみたいです

## ROOTをとらないで削除
[参照](http://smartgadget.pw/archives/21462117.html)

```adb:adb
adb shell pm uninstall -k --user 0 "com.nttdocomo.android.accountauthenticator"
```

でアカウントを削除すれば、adb shellでdpm set-device-ownerがSuccessできました。


## OWNER権限をもったので　実装

```java:Mainactivity.java
DevicePolicyManager myDevicePolicyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName mDPM = new ComponentName(MainActivity.this, AdminReceiver.class);
if (myDevicePolicyManager.isDeviceOwnerApp(MainActivity.this.getPackageName())) {
	String[] packages = {MainActivity.this.getPackageName()};
	myDevicePolicyManager.setLockTaskPackages(mDPM, packages);
	startLockTask();
} else {
	Toast.makeText(getApplicationContext(),"権限がない", Toast.LENGTH_LONG).show();
}
```
でこの状態を消すには

```java:Mainactivity.java
stopLockTask();
```

を実行すれば、ピンが終了します。
もしくは、この状態だと、端末を再起動すればピンが終了しています。

なので、端末起動のタイミングでこのアプリを呼び出して、上記のコードを実装すれば専用機の完成です。