はじめに
この記事ではAndroidアプリをアシスタントアプリとして登録したい時に設定するコードについて紹介します。
例としてコードを掲載していますが、まだ開発途中であるため、一部機能が使用できず、また強制停止が頻発します。あくまで参考程度でお使いください。
Androidスマホのショートカット機能
Androidスマホには、画面の右下から中央下に指をスライドしたり、ホームボタンを長押しするとアシスタントアプリが起動するショートカットが実装されています。また、端末によっては、アシスタントキー(SHARP AQUOS)や、Googleアシスタントボタン(SONY Xperia)などの、アシスタントアプリを起動するためのボタンが存在します。
しかし、あまり使わないんですよね。この機能。
じゃあ別のアプリを割り当てたい。
でも残念なことに、これらのショートカットは、アシスタントアプリとして登録されているアプリでないと、起動させられないんです。
アシスタントアプリを作れば良いじゃない
ショートカット機能で起動できるアプリはアシスタントアプリだけ。つまりアシスタントアプリなら起動できるということ。
Androidには、アプリがどういう役割を果たすのかをOS側に伝えるコードがあります。例えば
<action android:name="android.intent.action.BROWSER"/>
というコードがアプリのAndroidManifest.xmlに存在した場合、Androidはブラウザアプリとして扱います。
ではアシスタントアプリの場合は何を入力すれば良いのか…?調べてみると、ありました。
<action android:name="android.intent.action.ASSIST"/>
ブラウザの場合はBROWSRだった部分がアシスタントの場合はASSISTになるんですね。
つまり、android.intent.action.ASSISTを指定したアプリから、ショートカットしたい別のアプリを開けば、実質的に、ショートカットボタンから好きなアプリを開くことができます。
動作を考える
ショートカットからある特定のアプリを開く機能だけが欲しい、というのであれば、実装は楽です。
例えばChromeであれば、コード自体にChromeを開くコードを埋め込んでしまい、作ったアプリを起動した瞬間にChromeを起動する仕様にしてやれば、簡単です。
しかし、時間が経てば、起動させたいアプリは変わるかもしれません。その度にアプリをビルドし直すのは面倒です。
できればアプリ内から、起動するアプリを選べたら便利ですよね。アプリ一覧を表示して、ユーザーに選択してもらい、そのアプリのパッケージを取得し、保存、使用することで、様々なアプリに対応できるようになります。
ただし、今の私にはそんな動作を実現できる実力が無いため、LINEを起動するコードを書きたいと思います。
開きたいアプリを開く画面と、開きたいアプリを選択する画面をどうやって分けるか
ランチャーでアプリのアイコンを長押しした時に表示することができる、ウィジェット機能を使っています。
コード
まだ作成途中ですが一応公開します
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.preference.PreferenceManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onStart() {
super.onStart();
PackageManager pm = getPackageManager();
Intent intent = pm.getLaunchIntentForPackage("jp.naver.line.android");
try {
startActivity(intent);
} catch (Exception e) {
Toast.makeText(this, "対象のアプリがありません", Toast.LENGTH_SHORT).show();
}
}
}
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class SettingActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button saveButton = (Button)findViewById(R.id.SaveButton);
saveButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
saveButtonClick();
}
});
}
public void saveButtonClick() {
EditText editText = (EditText)findViewById(R.id.editText);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
sp.edit().putString("SaveString", editText.getText().toString()).commit();
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
tools:targetApi="31" >
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.ASSIST" />
<action android:name="android.intent.action.SEARCH_LONG_PRESS" />
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:value=""
android:name="android.app.shortcuts"
android:resource="@xml/shortcuts"/>
</activity>
<activity
android:name=".SettingActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
<meta-data
android:name="android.app.shortcuts"
android:resource="@xml/shortcuts"/>
</activity>
</application>
</manifest>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.223" />
<EditText
android:id="@+id/editText"
android:layout_width="243dp"
android:layout_height="53dp"
android:ems="10"
android:inputType="textPersonName"
android:text="@string/editText"
tools:ignore="LabelFor,MissingConstraints"
tools:layout_editor_absoluteX="84dp"
tools:layout_editor_absoluteY="225dp"
android:autofillHints="" />
<Button
android:id="@+id/SaveButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/buttonname"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/editText"
app:layout_constraintVertical_bias="0.132" />
</androidx.constraintlayout.widget.ConstraintLayout>
<resources>
<string name="app_name">OpenApp</string>
<string name="text">Please write package name</string>
<string name="buttonname">Save</string>
<string name="shortcutShortLabel">shortcutShortLabel</string>
<string name="shortcutLongLabel">shortcutLongLabel</string>
<string name="editText">jp.naver.line.android</string>
</resources>
まとめ
アシスタントアプリを作ろうという人があまりいないのか、AndroidManifest.xmlに記述するコードを調べるのに手間取りました。早くアプリを完成させたいです。
最後まで読んでいただきありがとうございました。