概要
UnityでAndroidのウィジェット機能を使うには、
①まず、アプリ部分をUnityで実装
②次に、ウィジェット部分をAndroid Studioで実装 という手順を踏む必要があります。
本記事には、Unityで「PlayerPrefsに保存した変数」をウィジェットに表示する方法を記載します。
最後に、今後の課題として、バックグラウンドでの更新処理に関しても触れます。
実装(Unity側)
まず、新規プロジェクトを作ります。(図1)

完了すると、図2の画面が待ち受けています。

Projectビューを右クリックでC#スクリプトを作成。
名前は”SampleProgram”とします。
using UnityEngine;
public class SampleProgram : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
PlayerPrefs.SetInt("Data1", 1);
PlayerPrefs.SetString("Data2", "Hi! I am John.");
}
}
とりあえず、図3のようにSampleProgram.csをMain Cameraにアタッチして、

図4のように、Export Projectにチェックを入れます。(ここで、Add Open Scenesも忘れずに押します)

新しいフォルダを作って保存します(図5)。このファイルは重要なので、見失わないようにしてください。

出力が完了すると、同ファイルの直下に何やらいくつかのフォルダが出来ていることが確認できます(図6)。

実装(Android Studio側)
準備
Android Studioを起動します。図6に示すように、上から3つ目にある、”Open an existing Android Studio project”を選択。

そして、先ほど出力したファイルを開きます(図7)。

そして、起動すると、Android Studioが必要なパッケージをインポートするので、終わるまで少し待ちます。その間、プロジェクトウィンドウの”Android”となっている部分を、”Project”に変更します(図8・図9)。


変更したら、WidgetDisplay直下の”unityLibrary”を選択し、右クリック。
“New>Widget>App Widget”を選択します(図10)。
出ない場合は、お茶でも飲んで少し待ってください。

すると、図11の画面が出てきます。
・Class Nameはテキトーに(ここではNewAppWidget)
・ConfigurationScreenのチェックを外し
・Source LanguageをJava
にします。

しばらくすると、”NewAppWidget.java”というタブが勝手に開きます(図12)。
同ファイルは次の参考位置にあります。
※参考位置:WidgetDisplay>unityLibrary>src>
main>java>com.unity3d.player>NewAppWidget.java

このタブは一旦無視して、左のProjectビューから
・WidgetDisplay>unityLibrary>src>
main>res>layout>new_app_widget.xml
・WidgetDisplay>unityLibrary>src>
main>res>xml>new_app_widget_info.xml
を開いておきます。
ここまで出来たら、改めて、new_app_widget.xmlを開きなおし、適当な位置にTextViewをドラッグ&ドロップします(図13)。

ここで、
・デフォルトで真ん中あたりに”EXAMPLE”と書かれているtext
・左上に何やら小さく書かれているtext
以上、2つのtextViewが生成されているはずです。
※ここで、可能であれば、2つのオブジェクトのIDがそれぞれ
“appwidget_text” および “textView”になっていることを確認してください。
実装
いよいよコーディングに入ります。先ほど勝手に開かれた、”NewAppWidget.java”を開きます。
これを観察すると、何やら、”NewAppWidget”クラスの中に、”updateAppWidget”という関数があります(図14)。

この部分を次のように書き換えます。
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
SharedPreferences pref = context.getSharedPreferences(context.getPackageName() + ".v2.playerprefs", Context.MODE_PRIVATE);
// Construct the RemoteViews object
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);
views.setTextViewText(R.id.appwidget_text, "" + pref.getInt("Data1", -1));
views.setTextViewText(R.id.textView, pref.getString("Data2", "-1"));
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
最後に、Ctrl+Alt+Lでコードを整形します。
確認
ここまで出来たら、一先ず、ビルドしてインストールします。(※ビルド方法はここでは解説しません)
すると、図15のように、いつものロゴが出て、

青い空の画面になります(図16)。

ややもすればStart関数が走り、PlayerPrefsの中身が更新されるはずですから、アプリを終了します。その後、ホーム画面にウィジェットを配置します(図17)。

デフォルトの1×1では少し小さいので、もう少し大きくしてみます(図18)。

こうすると、「半角スペース」が文字化けしていますが
・左上 → Data1として保存した”Hi! I am John.”
・中央 → Data2として保存した”1″
が表示されていることが分かります。
おつかれさまでした。
補足
動的にウィジェットを更新するには、先ほど開いておいた”new_app_widget_info.xml”の”updatePeriodMillis”の値を”86400000″(1日)→”1800000″(30分)に変更します。

30分より短い間隔で更新したい場合、AlarmやThreadという機能を、
Unityの関数をバックグラウンドで走らせたい場合、Serviceという機能をそれぞれ使う必要がありそうです。
UnityでAndroidのネイティブプラグインを利用する方法はいくつかのネット記事で確認できます。関連記事を含め、こちらのQiita記事によくまとめられています。
執筆時点(2021/04/06時点)で、アプリが起動していない間にUnityのプログラムをバックグラウンド動作させる方法が見つかっていません。この点は今後の課題になりそうです。