안드로이드 7.1 (25) 이상에서, 앱에 대한 바로가기 를 설정 가능합니다. 사용하는 런처에서 표시됩니다. 자주 사용하는 작업이나 권장되는 작업을 빨리 접근 할 수 있게 해줍니다. (Works 대응되어 있습니다.)
꾹 눌러서 표시 가능한데, 기존의 UX 와 겹쳐서 사람들이 많이 쓰는데는 시간이 걸릴 듯 합니다.
각 바로가기는 한개 또는 여러개의 intent
를 가지고 있습니다. 해당 intent 로 어떤 작업을 하게 할지 정할 수 있습니다.
- 지도에서 특정 위치로 바로 이동
- 친구에게 메시지 보내기
- 비디오 앱에서 다음 에피소드를 표시하기
- 게임에서 "불러오기" 같은 기능
바로가기 메뉴를 띄우면 항상 존재합니다.
예 ) 메시지앱에서 "새 메시지", 크롬 앱에서 "북마크" 등 일반적으로 바로 사용가능한 기능들
런처에서 알아야 하기 때문에 manifest 를 설정해주어야 합니다.
런처에서 처음 띄우게 설정된 <activity>
에 metadata 를 추가하면 됩니다. 그리고 android:resource 태그에 바로가기를 설정한 shortcut xml 을 명시해줍니다.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication">
<application ... >
<activity android:name="Main">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" />
</activity>
</application>
</manifest>
해당 xml 에서는 <shortcut>
의 목록을 만들어주며 해당 바로가기당 어떤 intent를 들고 있을 지 명시해주면 됩니다.
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:shortcutId="compose"
android:enabled="true"
android:icon="@drawable/compose_icon"
android:shortcutShortLabel="@string/compose_shortcut_short_label1"
android:shortcutLongLabel="@string/compose_shortcut_long_label1"
android:shortcutDisabledMessage="@string/compose_disabled_message1">
<intent
android:action="android.intent.action.VIEW"
android:targetPackage="com.example.myapplication"
android:targetClass="com.example.myapplication.ComposeActivity" />
<!-- If your shortcut is associated with multiple intents, include them
here. The last intent in the list determines what the user sees when
they launch this shortcut. -->
<categories android:name="android.shortcut.conversation" />
</shortcut>
<!-- Specify more shortcuts here. -->
</shortcuts>
하나의 바로가기에 여러개의 intent 를 설정하면 시스템은 가장 마지막 intent 부터 보이게 만듭니다. 즉 명시한 순서대로 backstack 을 만듭니다. 뒤로가기 버튼 등으로 모든 stack 이 제거됬을 때 런처로 이동하게 됩니다.
사용자가 앱을 사용함에 따라 변경 가능한 바로가기 메뉴입니다. 예를 들면 즐겨찾기한 사람에게 연락하기, 특정 위치로 바로 지도앱을 켜기 등이 있습니다.
ShortcutManager
api가 Dynamic Shortcut 을 만들 수 있게 해줍니다.
- Publish :
setDynamicShortcuts()
로 바로가기 목록을 전체 다 재정의 하거나,addDynamicShortcuts()
로 이미 있는 리스트에 추가할 수 있습니다. - Update:
updateShortcuts()
- Remove: 전부 지우려면
removeAllDynamicShortcuts()
, 특정 바로가기만 지우려면removeDynamicShortcuts(List<String> shortcutIds)
예시:
ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);
ShortcutInfo shortcut = new ShortcutInfo.Builder(this, "id1")
.setShortLabel("Web site")
.setLongLabel("Open the web site")
.setIcon(Icon.createWithResource(context, R.drawable.icon_website))
.setIntent(new Intent(Intent.ACTION_VIEW,
Uri.parse("https://www.mysite.example.com/")))
.build();
shortcutManager.setDynamicShortcuts(Arrays.asList(shortcut));
동적으로 intent 를 설정할 때 setintents() 로 여러개의 intent 를 설정 할 수 있고 static short처럼 해당 이벤트가 생길때 back stack을 만들게 됩니다.
8.0 이상에서 사용 가능한 기능입니다.
앱을 길게 누를 때 나오는 바로가기 각각의 아이콘을 제공해줍니다.
권한이 필요한 기능입니다. 이기능을 쓰면 런처에서 사용자에게 권한을 요청하는데, 만약 거부한다면 이 기능을 쓸 수 없습니다. 근데 삼성 런처에서는 못봄...
isRequestPinShortcutSupported()
로 기기의 기본 런처가 이 기능을 제공하는지 확인합니다.- 바로가기의 존재 여부에 따라
ShortcutInfo
객체를 두가지 방법으로 만들기- 이미 있을 경우, 바로가기의 id 만 가지는
ShortcutInfo
객체 사용 - 새로운 바로가기일 경우, id, intent, shortcut label 을 모두 가지는
ShortcutInfo
사용
- 이미 있을 경우, 바로가기의 id 만 가지는
requestPinShortcut()
을 통해 런처에 요청.PendingIntent
를 통해 만든 앱에 바로가기가 성공적으로 만들어 졌는지 여부를 전달 가능
만약 런처가 바로가기를 지원하지 않는다면 앱은 콜백을 받지 못합니다.
예시 :
ShortcutManager mShortcutManager =
context.getSystemService(ShortcutManager.class);
if (mShortcutManager.isRequestPinShortcutSupported()) {
// Assumes there's already a shortcut with the ID "my-shortcut".
// The shortcut must be enabled.
ShortcutInfo pinShortcutInfo =
new ShortcutInfo.Builder(context, "my-shortcut").build();
// Create the PendingIntent object only if your app needs to be notified
// that the user allowed the shortcut to be pinned. Note that, if the
// pinning operation fails, your app isn't notified. We assume here that the
// app has implemented a method called createShortcutResultIntent() that
// returns a broadcast intent.
Intent pinnedShortcutCallbackIntent =
mShortcutManager.createShortcutResultIntent(pinShortcutInfo);
// Configure the intent so that your app's broadcast receiver gets
// the callback successfully.
PendingIntent successCallback = PendingIntent.getBroadcast(context, 0,
pinnedShortcutCallbackIntent, 0);
mShortcutManager.requestPinShortcut(pinShortcutInfo,
successCallback.getIntentSender());
}
Note: See also the support library APIs,isRequestPinShortcutSupported()
andrequestPinShortcut()
, which work on Android 7.1 (API level 25) and lower. The support library falls back to the deprecatedEXTRA_SHORTCUT_INTENT
extra to attempt the pinning process.
앱에서 reportShortcutUsed()
를 호출해서 어떤 바로가기를 사용했는지에 대한 기록을 유지 가능합니다. (id 를 전달)
둘중 하나의 상황에서 보낼 수 있습니다.
- 사용자가 해당 id 를 가지는 바로가기를 선택
- 사용자가 앱을 직접 열어서 바로가기와 같은 작업을 수행 할 때
바로가기는 런처에서 유지되기 때문에 , 앱상에서는 더이상 존재하지 않는 기능이 보여질 수도 있습니다. 그래서 사용자가 더이상 선택하지 않기를 원할 때는 disableShortcuts(List<String> shortcutIds)
를 사용 가능합니다.
void disableShortcuts (List<String> shortcutIds, CharSequence disabledMessage)
를 사용하면 직접 에러 메시지를 띄울 수도 있습니다.
만약 앱을 업데이트 시에 정적 바로가기를 없앴다면 , 시스템이 알아서 disable 해줍니다.
setDynamicShortcuts()
, addDynamicShortcuts()
, updateShortcuts()
사용시 , 백그라운드 앱에서는 특정 횟수만 호출 할 수 있습니다. (액티비티가 없는 앱이나, forground에서 실행되는 service).
Production 환경에서는 이 제한을 앱을 foreground 로 실행하게 해서 초기화 할 수 있습니다.
왜 그런가?
개발 환경에서는 개발자메뉴 > shortcutManager api 초기화 로 가능하고,
Adb 에서는 아래 방법으로 가능합니다.
$ adb shell cmd shortcut reset-throttling [ --user your-user-id ]
기기를 바꿀 때도 바로가기를 그대로 유지하고 싶다면 manifest 에서 android:allowBackup="true"
를 설정하면 됩니다.
- Static shortcut 은 사용자가 앱을 설치 시 자동으로 적용
- Dynamic shortcut 은 백업되지 않습니다. 그래서 따로 앱 안에 새 기기에서 설치될 시에 바로가기를 추가하는 로직을 추가해주어야 합니다.
- Pinned Shortcut 은 런처에 저장됩니다. 그러나 해당 바로가기의 아이콘은 저장하지 않습니다. 그래서 앱 내에서 이미지를 저장해서 따로 복구해주어야 합니다. (원격 사용 등의 방법이 있을 듯 합니다)
public class MainActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ShortcutManager shortcutManager =
getSystemService(ShortcutManager.class);
if (shortcutManager.getDynamicShortcuts().size() == 0) {
// Application restored. Need to re-publish dynamic shortcuts.
if (shortcutManager.getPinnedShortcuts().size() > 0) {
// Pinned shortcuts have been restored. Use
// updateShortcuts() to make sure they contain
// up-to-date information.
}
}
}
// ...
}
App Shortcuts Design Guidelines. 통일성을 보장해줍니다.
5개 까지 제공하기는 하지만 보기 좋게 하기 위함
"shortDescription" = 10자
"longDescription" = 25자
reportShortcutUsed()
사용. 특정 바로가기의 기능을 다른 방법으로 접근하는 것을 고려?
슈퍼마켓으로 가는 길을 안내하는 바로가기를 만들었는데, 만약 슈퍼마켓의 이름은 바뀌로 위치는 바뀌지 않았다면 이름만 업데이트 하는것이 적적하고, 다른 위치의 슈퍼마켓에서 쇼핑을 시작했다면 , 새로 바로가기를 만드는 것이 좋습니다.
getDynamicShortcuts()
를 통해 앱을 켤 때마다 확인해서 원하는 바로가기가 유지되고 있는지 봐야합니다. (없으면 re-publicsh)
The Android AppShortcuts sample further demonstrates the use of the APIs covered on this page.