Android library that creates app shortcuts from annotations

Overview

Shortbread

Android library that generates app shortcuts for activities and methods annotated with @Shortcut. No need to touch the manifest, create XML files or use the shortcut manager. Just annotate the code that you want the shortcut to call.

Sample

The four shortcuts above are produced by the following code:

@Shortcut(id = "movies", icon = R.drawable.ic_shortcut_movies, shortLabel = "Movies")
class MoviesActivity : Activity() {

    // ...

    @Shortcut(id = "add_movie", icon = R.drawable.ic_shortcut_add, shortLabel = "Add movie")
    fun addMovie() {
        // could show an AddMovieDialogFragment for example
    }
}
@Shortcut(id = "books", icon = R.drawable.ic_shortcut_books, shortLabel = "Books")
class BooksActivity : Activity() {

    // ...

    @Shortcut(id = "favorite_books", icon = R.drawable.ic_shortcut_favorite, shortLabel = "Favorite books")
    fun showFavoriteBooks() {
        // could show a FavoriteBooksFragment for example
    }
}

To display the shortcuts, call Shortbread.create(Context context) as early as possible in the app, for example in onCreate of a custom Application.

class App : Application() {

    override fun onCreate() {
        super.onCreate()

        Shortbread.create(this)
    }
}

Shortcuts can be customized with attributes, just like using the framework API.

Kotlin
@Shortcut(
    id = "books",
    icon = R.drawable.ic_shortcut_books,
    shortLabel = "Books",
    shortLabelRes = R.string.shortcut_books_short_label,
    longLabel = "List of books",
    longLabelRes = R.string.shortcut_books_long_label,
    rank = 2, // order in list, relative to other shortcuts
    disabledMessage = "No books are available",
    disabledMessageRes = R.string.shortcut_books_disabled_message,
    enabled = true, // default
    backStack = [MainActivity::class, MainActivity::class],
    activity = MainActivity::class, // the launcher activity to which the shortcut should be attached
    action = "shortcut_books" // intent action to identify the shortcut from the launched activity
)
Java
@Shortcut(
    id = "books",
    icon = R.drawable.ic_shortcut_books,
    shortLabel = "Books",
    shortLabelRes = R.string.shortcut_books_short_label,
    longLabel = "List of books",
    longLabelRes = R.string.shortcut_books_long_label,
    rank = 2, // order in list, relative to other shortcuts
    disabledMessage = "No books are available",
    disabledMessageRes = R.string.shortcut_books_disabled_message,
    enabled = true, // default
    backStack = {MainActivity.class, LibraryActivity.class},
    activity = MainActivity.class, // the launcher activity to which the shortcut should be attached
    action = "shortcut_books" // intent action to identify the shortcut from the launched activity
)

Download

Shortbread is available on mavenCentral().

Kotlin
apply plugin: 'kotlin-kapt'

dependencies {
    implementation 'com.github.matthiasrobbers:shortbread:1.2.0'
    kapt 'com.github.matthiasrobbers:shortbread-compiler:1.2.0'
}
Java
dependencies {
    implementation 'com.github.matthiasrobbers:shortbread:1.2.0'
    annotationProcessor 'com.github.matthiasrobbers:shortbread-compiler:1.2.0'
}

Non-final resource IDs

If you are using resource IDs in @Shortcut attributes auch as shortLabelRes, which is recommended, you may see this warning in Android Studio:

Resource IDs will be non-final in Android Gradle Plugin version 5.0, avoid using them as annotation attributes.

If the annotation is located inside a library, the project won't even compile. To overcome this, add the Shortbread Gradle plugin and apply it to your modules:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.github.matthiasrobbers:shortbread-gradle-plugin:1.2.0'
    }
}
apply plugin: 'com.github.matthiasrobbers.shortbread'

Now make sure you use R2 instead of R inside all @Shortcut annotations. If you are using mipmap as shortcut icon resource type, switch to drawable by simply moving the resources from the mipmap- folders to the corresponding drawable- folders.

@Shortcut(icon = R2.drawable.ic_shortcut_movies, shortLabelRes = R2.string.label_movies)

The plugin uses the Butter Knife Gradle plugin to generate the R2 class with final values. Referencing them does not make the warning disappear (you can suppress it with @SuppressLint("NonConstantResourceId")), but most likely will be the only way to use resource IDs in annotations in the future.

Alternative to Gradle plugin

If for you can't (or don't want to) use the plugin, you can use the additional deprecated string attributes like iconResName, shortLabelResName and so on.

@Shortcut(iconResName = "ic_shortcut_movies", shortLabelResName = "label_movies")

License

Copyright 2017 Matthias Robbers

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • Getting java.lang.ClassNotFoundException while trying to init the library

    Getting java.lang.ClassNotFoundException while trying to init the library

    I'm getting this exception when I call Shortbread.create(this); in my Application class. Am I missing something?

    OS: 7.1 Device: Google Pixel

    java.lang.ClassNotFoundException: shortbread.ShortbreadGenerated
    W/System.err:     at java.lang.Class.classForName(Native Method)
    W/System.err:     at java.lang.Class.forName(Class.java:400)
    W/System.err:     at java.lang.Class.forName(Class.java:326)
    W/System.err:     at shortbread.Shortbread.create(Shortbread.java:37)
    Caused by: java.lang.ClassNotFoundException: Didn't find class "shortbread.ShortbreadGenerated"
    
    opened by cre8ivejp 8
  • Crashing on onCreate() Application

    Crashing on onCreate() Application

    Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference at shortbread.Shortbread.setShortcuts(Shortbread.java:66) at shortbread.Shortbread.create(Shortbread.java:48) at com.popstack.mvoter2015.MVoterApp.onCreate(MVoterApp.java:22) at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1024) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5403) at android.app.ActivityThread.-wrap2(ActivityThread.java)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1545)  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)

    duplicate 
    opened by dev-myatminsoe 3
  • Support for Kotlin

    Support for Kotlin

    As of now, the library doesn't work properly in Kotlin. It gives the following error

    An annotation argument should be compile-time constant. 
    

    This is the code that i am using.

    @Shortcut(id = "mastered", icon =  R.drawable.favorites, shortLabelRes = R.string.mastered_category)
    

    The above error comes both for drawable and string resources.

    opened by maskaravivek 2
  • Ability to remove and add shortcuts [Enhancement]

    Ability to remove and add shortcuts [Enhancement]

    Hey there, cool lib!

    Not sure if this is the same as Dynamic shortcuts, but essentially adding and removing shortcuts from the application.

    Most apps are very dynamic and change views/layouts based on conditions..this would be really helpful

    Regards

    opened by Akshshr 2
  • Multiple shortcuts in same Activity

    Multiple shortcuts in same Activity

    Hello,

    First of all, it's a very lovely library. My application is very fragment heavy, and I wish to add multiple @Shortcut to the same activity. Is this possible in the current iteration? Or could it be solved using the @Repeatable annotation? http://docs.oracle.com/javase/tutorial/java/annotations/repeating.html

    opened by THMCombine 2
  • Error:(8, 26) error: cannot find symbol class ShortcutInfo

    Error:(8, 26) error: cannot find symbol class ShortcutInfo

    package shortbread;

    import android.annotation.SuppressLint; import android.app.Activity; import android.app.TaskStackBuilder; import android.content.Context; import android.content.Intent; import android.content.pm.ShortcutInfo; import android.graphics.drawable.Icon; import com.devzapps.irctcquicktatkalbooking.Activity.TicketViewer; import java.util.ArrayList; import java.util.Arrays; import java.util.List;

    @SuppressLint({ "NewApi", "ResourceType" }) public final class ShortbreadGenerated { public static List<List> createShortcuts(Context context) { List enabledShortcuts = new ArrayList<>(); List disabledShortcuts = new ArrayList<>(); enabledShortcuts.add(new ShortcutInfo.Builder(context, "ticket_list") .setShortLabel("My Tickets") .setIcon(Icon.createWithResource(context, 2130837744)) .setIntents(TaskStackBuilder.create(context) .addParentStack(TicketViewer.class) .addNextIntent(new Intent(context, TicketViewer.class) .setAction(Intent.ACTION_VIEW)) .getIntents()) .setRank(0) .build()); return Arrays.asList(enabledShortcuts, disabledShortcuts); }

    public static void callMethodShortcut(Activity activity) {
    }
    

    }

    Error on ShortBreadGenerated.java

    opened by JP1016 2
  • Do not special work

    Do not special work

    hi i use shortbread in my project step by step but not change any thing and i when touch my app icon open my app like before! my phone for test is sony xperia z1 android 5.1

    opened by mbf5923 2
  • not working in Kotlin

    not working in Kotlin

    in this kotlin code this is not working

    class MoviesActivity : Activity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_splash_screen)
        }
    
        @Shortcut(id = "add_movie1", icon = R.drawable.ic_settings, shortLabel = "Add movie1", rank = 4)
        fun addMovie() {
    
        }
    }
    

    but in java same it's working fine

    public class MoviesActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_splash_screen);
        }
    
        @Shortcut(id = "add_movie1", icon = R.drawable.ic_settings, shortLabel = "Add movie1", rank = 4)
        public void addMovie() {
    
        }
    }
    
    opened by rajumark 1
  • Support for Java 8

    Support for Java 8

    Seeing this warning

    Warning:Supported source version 'RELEASE_7' from annotation processor 'shortbread.ShortcutProcessor' less than -source '1.8'

    Guessing its gotta do with the Java version the lib is written to

    opened by Akshshr 1
  • Is there a method call back when a shortcut is received by an activity?

    Is there a method call back when a shortcut is received by an activity?

    Hey!

    Is there/there should be a method that gets a call back declared in the activity in case one wants to further handle intent from the shortcut, so you can post process that from the call back method.

    Would be really cool!

    For example:

    public onShortcutCalled(String shortcutId){ if(shortcutId == "profile"){ //Open profile } if(shortcutId == "cats"){ //Open cats } }

    opened by Akshshr 1
  • Error:(9, 36) error: cannot find symbol class Activity

    Error:(9, 36) error: cannot find symbol class Activity

    package shortbread;

    import android.annotation.SuppressLint; import android.app.TaskStackBuilder; import android.content.Context; import android.content.Intent; import android.content.pm.ShortcutInfo; import android.graphics.drawable.Icon; import com.abc.TestApp.Activity; import com.abc.TestApp.Activity.ActivityTwo; import java.util.ArrayList; import java.util.Arrays; import java.util.List;

    @SuppressLint({ "NewApi", "ResourceType" }) public final class ShortbreadGenerated { public static List<List> createShortcuts(Context context) { List enabledShortcuts = new ArrayList<>(); List disabledShortcuts = new ArrayList<>(); enabledShortcuts.add(new ShortcutInfo.Builder(context, "test") .setShortLabel(context.getString(2131230812)) .setIcon(Icon.createWithResource(context, 2130837607)) .setIntents(TaskStackBuilder.create(context) .addParentStack(ActivityTwo.class) .addNextIntent(new Intent(Intent.ACTION_VIEW).setClass(context, Activity.ActivityOne.class)) .addNextIntent(new Intent(Intent.ACTION_VIEW).setClass(context, Activity.ActivityThree.class)) .addNextIntent(new Intent(context, ActivityTwo.class) .setAction(Intent.ACTION_VIEW)) .getIntents()) .setRank(2) .build()); return Arrays.asList(enabledShortcuts, disabledShortcuts); }

    public static void callMethodShortcut(android.app.Activity activity) {
    }
    

    }

    error in ShortbreadGenerated.java Error:(9, 36) error: cannot find symbol class Activity error is in this line "import com.abc.TestApp.Activity;"

    Code is

    @Shortcut(id = "test", icon = R.drawable.ic_test, shortLabelRes = R.string.shortcut_test, rank = 2, backStack = {ActivityOne.class, ActivityThree.class} )

    If I remove backstack, then its working fine. But, with backstack or activity its giving the error

    One more thing I just want to mention, that I have different packages for different activities.

    opened by avtarsingh1122 1
  • Support for dynamic app shortcuts

    Support for dynamic app shortcuts

    The library is based on the creation of dynamic app shortcuts but itself does not provide this functionality. The annotated shortcuts are always displayed.

    Any ideas how the implement that feature?

    opened by AndreRoss 6
Releases(v.1.4.0)
  • v.1.4.0(Apr 10, 2021)

    • Improve: Shortbread is now an isolating annotation processor, which improves the performance of incremental annotation processing. Before, the processor type was aggregating and it would generate a single class ShortbreadGenerated. Now it generates one class for each activity that contains shortcuts, e.g. MoviesActivity_Shortcuts. The generated classes are still only used by the library itself, the consumer does not interact with them.
    • Improve: Shortcut methods/functions don't have to be public anymore. Any visibility higher than private is enough.
    • Fix: When using R2, resource values sometimes were not properly read when the incremental annotation processing was incremental
    • New: The module :sample-library shows how to use Shortbread in a library module
    Source code(tar.gz)
    Source code(zip)
  • v1.3.0(Mar 31, 2021)

    • New: Shortbread is now initialized automatically using App Startup
    • Deprecated: Shortbread.create(context) - no need to call this anymore as the shortcuts are set automatically during app startup
    • Fix: Resource values sometimes were not properly read when the incremental annotation processing was incremental
    • Improve: ActivityLifecycleCallbacks will not be registered if there are no method shortcuts
    Source code(tar.gz)
    Source code(zip)
  • v1.2.0(Mar 14, 2021)

    • New: Support for non-final resource IDs. See README.md for detailed usage instructions.
    • Update: androidx.annotation:annotation to 1.1.0
    • Update: Android Gradle plugin to 4.1.2
    • Migrated publishing from JCenter to Maven Central
    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Jul 21, 2020)

    • New: Support for incremental annotation processing
    • Switch from Support annotations library to androidx.annotation
    • Java 8 is now required
    • Minimum SDK increased from 9 to 14 (app shortcuts are still not available before 25)
    • Update: Android Gradle plugin to 3.6.4
    • Some small changes to bring everything to 2020
    Source code(tar.gz)
    Source code(zip)
  • v.1.0.2(Sep 24, 2017)

    • Fix: Annotated methods are called before onCreate() (#13)

    • Update: Support annotations library to 26.0.2. This requires the new Google Maven Repository:

        google()
      

      or

        maven {
            url "https://maven.google.com"
        }
      
    Source code(tar.gz)
    Source code(zip)
  • v1.0.1(Mar 4, 2017)

    • Fix: Shortbread.create(context) can now also be called if there are no @Shortcut annotations in the code, which before produced a crash. Previously created shortcuts are now removed.
    • Fix: Internal NullPointerException when an activity containing method shortcuts is not launched via a method shortcut
    • Add Javadoc for the public API
    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Feb 11, 2017)

Owner
Matthias Robbers
Android developer at @DieTechniker
Matthias Robbers
Kotlin-native webserver for simple image annotations

Kotlin-native webserver for simple image annotations

null 1 Feb 26, 2022
Koin Annotations - help declare Koin definition in a very fast and intuitive way, and generate all underlying Koin DSL for you

The goal of Koin Annotations project is to help declare Koin definition in a very fast and intuitive way, and generate all underlying Koin DSL for you. The goal is to help developer experience to scale and go fast ?? , thanks to Kotlin Compilers.

insert-koin.io 68 Jan 6, 2023
[Android Library] A SharedPreferences helper library to save and fetch the values easily.

Preference Helper A SharedPreferences helper library to save and fetch the values easily. Featured in Use in your project Add this to your module's bu

Naveen T P 13 Apr 4, 2020
Android app with minimal UI to run snowflake pluggable transports proxy, based on library IPtProxy

Simple Kotlin app for testing IPtProxy's snowflake proxy on Android Essentially a button for starting and stopping a Snowflake Proxy with the default

null 2 Jun 26, 2022
Library App - Using Android studio / Final project

Library-App Library App - Using Android studio / Final project Screens SplashScreen: it’s launcher activity will be moved to MainActivity auto after 2

Baseel 3 Feb 2, 2022
This is a sample app to use [Molecule library] and solve some scoping problems in Android development.

Android sample app Problem It's started when P.Y. in Twitter shared this tweet and his post, which is a correct complain about introducing a new set o

Hadi 37 Oct 28, 2022
Movie app that receives popular movies and allows the user to search for the specific movie through the Rest API with help of retrofit library &MVVM architecture.

MovieClue Millions of movies, TV shows and people to discover. Explore now Movie app that recieves popular movies and allow the user to search for spe

Shubham Tomar 6 Mar 31, 2022
Kamper - a small KMM/KMP library that provides performance monitoring for your app.

?? Kamper Kamper is a KMP/KMM library that implements a unified way to track application performances. The solution is based on plugin design patterns

S. Mellouk 31 Jun 10, 2022
This is a demo android app representing implementation of SE principles in android app development

Articles Demo This repository contains a sample Android App that shows most popular articles data from NY Times API. This is a sample app that shows h

Waesem Abbas 2 Jan 20, 2022
Name of your app is an android app that allows building a todo list

Project 1 - SimpleToDo Name of your app is an android app that allows building a todo list and basic todo items management functionality including add

Javier Nazario 0 Nov 23, 2021
Matches-simulator-app - App Android Nativo de Simulação de Partidas

Matches Simulator App App Android Nativo de Simulação de Partidas. Este repositório foi organizado em algumas branches que representam as implementaçõ

DIO 127 Dec 28, 2022
Matches-simulator-app - App Android Nativo de Simulação de Partidas de Futebol

Matches Simulator App App Android Nativo de Simulação de Partidas de Futebol - E

Glaucio Coutinho da Silva 1 Jan 18, 2022
A beautiful Fashion Store like Android App Mock built on Jetpack Compose with compose navigation, hilt, dark theme support and google's app architecture found on uplabs Here

A beautiful Fashion Store like Android App Mock built on Jetpack Compose with compose navigation, hilt, dark theme support and google's app architecture found on uplabs Here

Puncz 87 Nov 30, 2022
Crunch-Mobile - A Food Delivery Mobile App which uses Modern App Architecture Pattern, Firebase And a Simple Restful Api

Crunch-Mobile This is a Food Delivery Mobile App which uses Modern App Architect

Bright Ugwu 1 Jan 1, 2022
MVIExample - A sample app showing how to build an app using the MVI architecture pattern

MVIExample A sample app showing how to build an app using the MVI architecture p

Yasser AKBBACH 0 Jan 8, 2022
Notes-App-Kotlin - Notes App Built Using Kotlin

Notes-App-Kotlin Splash Screen Home Page Adding New Notes Filter Feature Search

Priyanka 4 Oct 2, 2022
Oratio Library for Android Studio helps you simplify your Android TTS codes

Oratio Oratio is a library for Android Studio. This library is useful to a number of developers who are currently making apps using android TTS(Text-T

Jacob Lim 1 Oct 28, 2021
Android Ptrace Inject for all ABIs and all APIs. Help you inject Shared Library on Android.

Android Ptrace Inject 中文可以参考我的注释内容进行理解 我写的注释相对来说比较全面了 How to build Make sure you have CMake and Ninja in your PATH Edit CMakeLists.txt. Set ANDROID_ND

SsageParuders 65 Dec 19, 2022