when I using Dynamic shortcuts, I got a Exception:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.waterbottle.v1/com.waterbottle.v1.NovaMainActivity}: java.lang.IllegalStateException: Launcher activity not found for package com.waterbottle.v1
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.IllegalStateException: Launcher activity not found for package com.waterbottle.v1
at android.os.Parcel.readException(Parcel.java:1692)
at android.os.Parcel.readException(Parcel.java:1637)
at android.content.pm.IShortcutService$Stub$Proxy.setDynamicShortcuts(IShortcutService.java:356)
at android.content.pm.ShortcutManager.setDynamicShortcuts(ShortcutManager.java:495)
at com.waterbottle.main.guide.MainActivity.createShortcut(MainActivity.java:392)
at com.waterbottle.main.guide.MainActivity.onCreate(MainActivity.java:348)
at com.waterbottle.v1.NovaMainActivity.onCreate(NovaMainActivity.java:15)
at android.app.Activity.performCreate(Activity.java:6679)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Here is my code:
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("waterbottle://needreview"));
ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);
ShortcutInfo shortcut = new ShortcutInfo.Builder(this, "addReview")
.setShortLabel("Add review")
.setLongLabel("Add review")
.setIcon(Icon.createWithResource(getApplicationContext(), R.drawable.comments))
.setIntent(intent)
.build();
ArrayList<ShortcutInfo> shortcutInfos = new ArrayList<>();
shortcutInfos.add(shortcut);
shortcutManager.addDynamicShortcuts(shortcutInfos);
}
I put it in my MainActivity onCreate();
Here is the ShortcutManager.java code:
/**
* Publish the list of shortcuts. All existing dynamic shortcuts from the caller app
* will be replaced. If there are already pinned shortcuts with the same IDs,
* the mutable pinned shortcuts are updated.
*
* <p>This API will be rate-limited.
*
* @return {@code true} if the call has succeeded. {@code false} if the call is rate-limited.
*
* @throws IllegalArgumentException if {@link #getMaxShortcutCountPerActivity()} is exceeded,
* or when trying to update immutable shortcuts.
*
* @throws IllegalStateException when the user is locked.
*/
public boolean setDynamicShortcuts(@NonNull List<ShortcutInfo> shortcutInfoList) {
try {
return mService.setDynamicShortcuts(mContext.getPackageName(),
new ParceledListSlice(shortcutInfoList), injectMyUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
I don't know what "IllegalStateException when the user is locked." means.
Here is my entire manifest file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.waterbottle.main">
<uses-permission xmlns:tools="http://schemas.android.com/tools"
android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions" />
<application>
<activity
android:name="com.waterbottle.main.guide.SplashScreenActivity"
android:configChanges="orientation|keyboardHidden"
android:label="@string/dpapp_name"
android:screenOrientation="nosensor"
android:theme="@style/Theme.WaterbottleNoTitle.SplashBackground">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
<meta-data android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" />
</activity>
<activity
android:name="com.waterbottle.main.guide.MainActivity"
android:configChanges="orientation|keyboardHidden"
android:label="@string/app_name"
android:launchMode="singleTask"
android:screenOrientation="nosensor"
android:windowSoftInputMode="adjustNothing">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="home"
android:scheme="waterbottle" />
</intent-filter>
</activity>
<activity
android:name="com.waterbottle.ugc.review.ui.NeedReviewActivity"
android:launchMode="singleTop"
android:screenOrientation="nosensor"
android:windowSoftInputMode="stateHidden|adjustResize">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:host="recommenddealreview"
android:scheme="waterbottle" />
<data
android:host="needreview"
android:scheme="waterbottle" />
</intent-filter>
</activity>
<activity
android:name="com.waterbottle.main.city.CityListPickerActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="nosensor">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="selectcity"
android:scheme="waterbottle" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/city_searchable" />
<meta-data
android:name="android.app.default_searchable"
android:value="com.waterbottle.city.CityListActivity" />
</activity>
<activity
android:name="com.waterbottle.main.city.CityListSwitchActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="nosensor">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="switchcity"
android:scheme="waterbottle" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/city_searchable" />
<meta-data
android:name="android.app.default_searchable"
android:value="com.waterbottle.city.CityListActivity" />
</activity>
<activity
android:name="com.waterbottle.main.home.UserCodeActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:launchMode="singleTask"
android:screenOrientation="nosensor"
android:windowSoftInputMode="stateHidden|adjustResize">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="usercode"
android:scheme="waterbottle" />
</intent-filter>
</activity>
<activity
android:name="com.waterbottle.main.login.nativelogin.LoginActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="nosensor"
android:windowSoftInputMode="stateHidden">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:host="login"
android:scheme="waterbottle" />
</intent-filter>
</activity>
<activity
android:name="com.waterbottle.main.login.nativelogin.FastLoginActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="nosensor">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:host="fastlogin"
android:scheme="waterbottle" />
<data
android:host="sublogin"
android:scheme="waterbottle" />
</intent-filter>
</activity>
<activity
android:name="com.waterbottle.main.login.nativelogin.SignupActivity"
android:configChanges="orientation|keyboardHidden|keyboard"
android:screenOrientation="nosensor">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="signup"
android:scheme="waterbottle" />
</intent-filter>
</activity>
<activity
android:name="com.waterbottle.main.login.nativelogin.LoginWebActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="nosensor">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:host="loginweb"
android:scheme="waterbottle" />
</intent-filter>
</activity>
<service android:name=".guide.SplashDownloadIntentService" />
<service
android:name="com.waterbottle.main.accessibilityservice.NovaAccessibilityService"
android:enabled="true"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/accessibility_service_config" />
</service>
</application>
</manifest>
This one permission is required for App Shortcuts:
While when setting any Intent Action on the App Shortcut ...
any activity's
<intent-filter>
in theManifest.xml
needs to filter for it:Intent.ACTION_MAIN
requires:Intent.ACTION_DEFAULT
requires:Intent.ACTION_VIEW
requires:@see Intents and Intent Filters, <intent-filter>, ShortcutManager.