- 投稿日:2021-01-12T10:06:55+09:00
【Unity】Android アプリでスクショや画面録画などを禁止する
背景
アプリによっては、セキュリティやコンテンツ的にスクショや画面録画を禁止したいときがあると思います。
そのとき Android の機能であるWindowManager.LayoutParams.FLAG_SECURE
を Activity のOnCreate()
で呼ぶ必要があります。しかし、Unity だとどうするのか分からなかったので調べてまとめた記事になります。
FLAG_SECURE を設定するとどうなるか
- スクショを無効化
- 画面録画(スクリーンレコーディング)をすると、録画した画面が真っ黒になる
- タスク画面・タスク一覧で、アプリ画面を真っ白にできる
動作確認環境
- Unity 2018.4.22f1
※ Unity2018.2以前のバージョンを使っている場合は、以下の手順とは異なるかと思いますので、ご注意ください。
手順
Unity + Android で実現するためには、
UnityPlayerActivity
を拡張して新しい Activity を定義する- 新しい Activity が使用されるように
AndroidManifest.xml
を修正する- 新しい Activity の
OnCreate()
にFLAG_SECURE
を設定するという手順が必要です。
1.
UnityPlayerActivity
を拡張する自分が作業中の Unityプロジェクトの
Assets/Plugins/Android
配下に新しい Activity を作成します。
例として、OverrideExample
クラスを作成します。ちなみに、 package name 以外のファイル内容は、Unity公式からそのままコピペしています。
UnityPlayerActivity Java コードの拡張 - Unity マニュアル
package name は、自分が設定した名前に置き換えてください。OverrideExample.javapackage com.DefaultCompany.ExtendUnityPlayerActivity; import com.unity3d.player.UnityPlayerActivity; import android.os.Bundle; import android.util.Log; public class OverrideExample extends UnityPlayerActivity { protected void onCreate(Bundle savedInstanceState) { // UnityPlayerActivity.onCreate() を呼び出す super.onCreate(savedInstanceState); // logcat にデバッグメッセージをプリントする Log.d("OverrideActivity", "onCreate called!"); } public void onBackPressed() { // UnityPlayerActivity.onBackPressed() を呼び出す代わりに、Back ボタンイベントを無視する // super.onBackPressed(); } }2.
AndroidManifest.xml
を修正するActivity と同様に
Assets/Plugins/Android
にAndroidManifest.xml
を配置します。
android:name
の部分は、1.
で作成したクラス名に合わせてください。AndroidManifest.xml<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.product"> <application android:icon="@drawable/app_icon" android:label="@string/app_name"> <activity android:name=".OverrideExample" android:label="@string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>この状態で、Androidビルドして問題なくアプリが使用できるか確認してください。
特に、 package name を間違えるとアプリがクラッシュしたりするので、注意してください。3. FLAG_SECURE を設定する
onCreate()
でFLAG_SECURE
を設定します。OverrideExample.javapackage com.DefaultCompany.ExtendUnityPlayerActivity; import com.unity3d.player.UnityPlayerActivity; import android.os.Bundle; import android.util.Log; import android.view.WindowManager; public class OverrideExample extends UnityPlayerActivity { protected void onCreate(Bundle savedInstanceState) { // UnityPlayerActivity.onCreate() を呼び出す super.onCreate(savedInstanceState); // logcat にデバッグメッセージをプリントする Log.d("OverrideActivity", "onCreate called!"); //FLAG_SECUREの設定 getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE); } public void onBackPressed() { // UnityPlayerActivity.onBackPressed() を呼び出す代わりに、Back ボタンイベントを無視する // super.onBackPressed(); } }これで作業は完了です。
Androidビルドして、問題なければスクショや画面録画ができなくなっていると思います。参考文献
UnityPlayerActivity Java コードの拡張 - Unity マニュアル
Androidアプリでキャプチャーをされたくないときにする方法
- 投稿日:2021-01-12T06:46:22+09:00
Unityで対話型音声認識アプリを作れるフレームワークをつくった
macOS, Windows両方で動く、Unityで対話型の音声認識アプリがすぐに作れるフレームワークを作りました。
リポジトリへのリンク:https://github.com/HassoPlattnerInstituteHCI/SpeechIOForUnity
Unity Package: https://github.com/HassoPlattnerInstituteHCI/SpeechIOForUnity/releases/tag/v1.0つかいかた
SpeechOut/SpeechIn
を宣言し、以下のように書くだけ。SpeechOut speechOut = new SpeechOut(); SpeechIn speechIn = new SpeechIn(OnRecognized); void Start(){ Dialog(); } async void Dialog(){ await speechOut.Speak("Hello!"); await speechIn.Listen(new string[] { "Hello", "Hi", "Hey" }); await speechOut.Speak("How are you doing?"); await speechIn.Listen(new string[] { "I'm fine", "Nah", "I'm Sick" }); //... }なぜつくったか
macOS, Windowsを使う学生のために、Unityを扱う授業で音声認識を使った対話型アプリを作るためのフレームワークがあればいいなと思ったので作りました。
主に非同期処理のasync/await
ベースで、逐次処理をわかりやすく書けるように、また速度や”間”などのチューニングも簡単にできるようにしました。授業ではmac, Windowsそれぞれを使う学生を同様に対応しないといけないのですが、Unityそのものは双方で動作する一方、ネイティブOSの機能を使おうとすると相互にコードを共有できない=他のチームやグループが作ったアプリを動作させられないことになるので、このようなコードを作りました。
授業のためとはいえ、一般的に使いやすいツールだと思います。
OSネイティブの音声認識・音声合成
macOS側
macOSネイティブのオフライン音声認識ツールとしては、
NSSpeechRecognizer
が、音声合成ツールとしては、コマンドラインツールとしてsay
があります。このうち、say
に関してはUnity上のSystem.Diagnostics.Process
から呼び出すことで実行できます(この点、Argsをいじるだけで声質とか速度を変えられるのでサイコー)一方の
NSSpeechRecognizer
はOSネイティブAPIとして提供されている機能なので、実行するためにはObjective-C
もしくはSwift
で記述されたコードから実行する必要があります。今回のフレームワークでは別途NSSpeechForUnityとして、
NSSpeechRecognizer
を呼び出すObjective-C
コードを書き、外部ライブラリとして.bundle
ファイルを書き出し、それをUnityのPluginとすることで実行しています。Windows側
逆にWindows側では
UnityEngine.Windows.Speech
なるモジュールがあり、音声認識に関してはUnityから直接実行できる一方、音声合成に関しては別途WindowsのネイティブAPI=SAPIを叩く必要がありました。コード内で別途WindowsVoiceProjectとして、Visual Studioから.dllをビルドできるプロジェクトを作り、その.dllをUnityのPluginにします。
以上2つのOSに関して独自にライブラリを書き出すことによって実現しましたが、Unity上で非同期の動作を実現させるため、それぞれの処理がきちんと終わったかどうかを常に監視するためのコードを書く必要があります。たとえばこのように、内部のStateを逐一変えて、Unity側から監視することで、UnityのAsync/Awaitが進行するように若干HardCodedな感じではありますが、リアルタイムアプリケーションのための非同期処理を実現しています。
応用
対話型アプリケーションのためとは言いましたが、VRアプリケーションなどのための目と手が離せない際のデバッグ(イベントが起こったときにどのフラグが立ったか喋って教えてくれる)や、視覚障害者向けアプリなど、様々な用途が考えられます。「デバッグのときになにか喋ってくれたら便利だな」とか、「アクセシビリティ機能の充実したアプリを作りたいな」などというときにはぜひ使ってみてください。