AnkiDroid Companion needs to track which deck the user is studying. Since decks can be renamed in AnkiDroid, the app implements a robust system for mapping deck names to deck IDs and persisting these references.
Deck references are stored in Android’s SharedPreferences for persistence across app sessions:
private static final String DECK_REF_DB = "com.ichi2.anki.api.decks";/** * Save a mapping from deckName to getDeckId in the SharedPreferences */public void storeDeckReference(String deckName, long deckId) { final SharedPreferences decksDb = mContext.getSharedPreferences(DECK_REF_DB, Context.MODE_PRIVATE); decksDb.edit().putLong(deckName, deckId).apply();}
The findDeckIdByName() method implements intelligent deck lookup with rename detection:
/** * Try to find the given deck by name, accounting for potential renaming of the deck by the user as follows: * If there's a deck with deckName then return it's ID * If there's no deck with deckName, but a ref to deckName is stored in SharedPreferences, and that deck exist in * AnkiDroid (i.e. it was renamed), then use that deck. Note: this deck will not be found if your app is re-installed * If there's no reference to deckName anywhere then return null * @param deckName the name of the deck to find * @return the did of the deck in Anki */public Long findDeckIdByName(String deckName) { SharedPreferences decksDb = mContext.getSharedPreferences(DECK_REF_DB, Context.MODE_PRIVATE); // Look for deckName in the deck list Long did = getDeckId(deckName); if (did != null) { // If the deck was found then return it's id return did; } else { // Otherwise try to check if we have a reference to a deck that was renamed and return that did = decksDb.getLong(deckName, -1); if (did != -1 && mApi.getDeckName(did) != null) { return did; } else { // If the deck really doesn't exist then return null return null; } }}
Direct Lookup: Search for a deck with the exact name
ID-based Lookup: If not found, check SharedPreferences for a stored ID and verify that deck still exists
Return Null: If neither approach finds the deck
Important: If the app is reinstalled, the SharedPreferences data is lost. Renamed decks will only be found if they’re renamed back to the original name.
The private getDeckId() method performs the actual lookup in AnkiDroid’s deck list:
/** * Get the ID of the deck which matches the name * @param deckName Exact name of deck (note: deck names are unique in Anki) * @return the ID of the deck that has given name, or null if no deck was found or API error */private Long getDeckId(String deckName) { Map<Long, String> deckList = mApi.getDeckList(); if (deckList != null) { for (Map.Entry<Long, String> entry : deckList.entrySet()) { if (entry.getValue().equalsIgnoreCase(deckName)) { return entry.getKey(); } } } return null;}