2014年8月29日金曜日

【Android:開発】2つの操作方法でランチャーにショートカットを登録

Androidでランチャーに自分のアプリのショートカットを置いてもらいたい場合、二つの方法があります。
一つは自分のアプリ内のボタンなどからアプリ自身がBroadcastを投げて依頼する場合、
もう一つはランチャー内の「追加」→「ショートカット」といったメニューを経由して、ランチャー側が自分のアプリを呼び出す場合です。

前者の解説は山ほどありましたが、後者の解説が少なかったので、記録しておきます。





先に後者(ランチャー経由)でのショートカット追加方法を知りたいところですが、ひとまず両対応に向けた準備からしていきましょう。

■自分のアプリをアプリドロワーにもショートカット一覧にも表示させる

ショートカットの配置/設定を行うActivityをショートカット一覧に表示させるにはAndroidManifest.xmlでそのActivityに"android.intent.action.CREATE_SHORTCUT"Actionを記述することで可能ですが、
自分のアプリを両方に表示させようと思い、このような記述をしてしまうと不都合が生じます。

<activity
  android:name=".MainActivity"
  android:label="@string/app_name" android:windowSoftInputMode="adjustResize">
  <intent-filter>
  <action android:name="android.intent.action.MAIN" />
  <category android:name="android.intent.category.LAUNCHER" />
  <action android:name="android.intent.action.CREATE_SHORTCUT" />
  </intent-filter>
 </activity>
こんなときに使えるのがActivity Aliasです。
以下のように変更します。

<activity
  android:name=".MainActivity"
  android:label="@string/app_name" android:windowSoftInputMode="adjustResize">
  <intent-filter>
  <action android:name="android.intent.action.MAIN" />
  <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
</activity>
<activity-alias android:name=".MainActivityShortcut" android:targetActivity=".MainActivity" android:label="@string/app_name" >
  <intent-filter>
  <action android:name="android.intent.action.CREATE_SHORTCUT"/>
  <category android:name="android.intent.category.DEFAULT" />
  </intent-filter>
 </activity-alias>

※Activity AliasはActivity本体の後に記述しなければいけません。
こうすることで、ちょっといいことがあります。
Activity内でランチャーから起動されたかショートカット一覧から起動されたかを見分けることができるのです。素敵!

■Activityの起動のされ方を見分ける

Activity Aliasで起動した場合、ActivityのNameが違うので、それを利用します。

final boolean isShortcut;

if(getIntent().getComponent().getClassName().equals(getPackageName() + ".MainActivityShortcut")){
 //ショートカット選択画面から起動している
 isShortcut = true;
}

else{
 //ホーム画面アプリ一覧から起動している
 isShortcut = false;
}
たったこれだけで、ショートカット一覧から起動しているかを見分けることができます。

そしてこれを利用して、ショートカットを追加する方法を変化させます。
前者の方法(さいごにBroadcastを投げる方)の解説はググればザックザク出てくるわけですが、
それらのコードの最後に大体記述されている

sendBroadcast(intent);
finish();

これを、
if(isShortcut) setResult(RESULT_OK, intent);
else sendBroadcast(intent);
finish();
こうするだけです。
isShortcutがfalseの時はBroadcastを送りランチャーへの登録を依頼、
trueの時は、ランチャーがstartActivityForResultしたことでActivityが呼ばれたわけですから、単純に返してあげるだけであとはランチャーが何とかしてくれる、というわけですね。

なんて簡単な!!!!!
私も拍子抜けしてしまいました。
これだけでランチャーのショートカット一覧からのショートカットの追加にも対応できてしまいます!

----------------

この方法はアプリ「HandySSH」を開発していた時に発見しました。
最後にMainActivity#onCreate()を載せておきます。
お試しあれ!

@Override
protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);


 final boolean isShortcut;
 if(getIntent().getComponent().getClassName().equals(getPackageName() + ".MainActivityShortcut")){
  //ショートカット選択画面から起動している
  isShortcut = true;
 }
 else{
  //ホーム画面アプリ一覧から起動している
  isShortcut = false;
 }

 editName = (EditText)findViewById(R.id.editName);
 editCommand = (EditText)findViewById(R.id.editCommand);
 editDelay  = (EditText)findViewById(R.id.editDelay);
 editHost  = (EditText)findViewById(R.id.editHost);
 editUser  = (EditText)findViewById(R.id.editUser);
 editPass  = (EditText)findViewById(R.id.editPass);

 btnMake = (Button)findViewById(R.id.btnMake);
 if(isShortcut) btnMake.setText(getResources().getString(android.R.string.ok));//もとは"Make shortcut"
 btnMake.setOnClickListener(new OnClickListener() {

  @Override

  public void onClick(View v) {
   // TODO Auto-generated method stub
   //ショートカットをタッチで発行されるIntentを作成
   Intent shortcutIntent = new Intent(Intent.ACTION_VIEW);
   shortcutIntent.setClassName(getApplicationContext(), SSHActivity.class.getName());
   shortcutIntent.putExtra("HOST",editHost.getText().toString());
   shortcutIntent.putExtra("USER",editUser.getText().toString());
   shortcutIntent.putExtra("PASS",editPass.getText().toString());
   shortcutIntent.putExtra("COMMAND",editCommand.getText().toString());
   shortcutIntent.putExtra("DELAY", editDelay.getText().toString());

   //shortcutIntentをショートカットに登録するIntent
   Intent intent = new Intent();

   intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, editName.getText().toString());
   intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);


   Parcelable iconResource = Intent.ShortcutIconResource.fromContext(getApplicationContext(),     R.drawable.ic_launcher);
   intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource);

   intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");

   if(isShortcut) setResult(RESULT_OK, intent);
   else sendBroadcast(intent);
   finish();
  }
 });
}

0 件のコメント:

コメントを投稿

Amazon