Skip to content

[API] Added fields to cards endpoints#20589

Merged
mikehardy merged 1 commit intoankidroid:mainfrom
lonewolf2208:issue-20458-card-raw-fields
Apr 19, 2026
Merged

[API] Added fields to cards endpoints#20589
mikehardy merged 1 commit intoankidroid:mainfrom
lonewolf2208:issue-20458-card-raw-fields

Conversation

@lonewolf2208
Copy link
Copy Markdown
Contributor

@lonewolf2208 lonewolf2208 commented Mar 25, 2026

Purpose / Description

  • Expose a small set of easier/raw card properties from the content provider. Fields - reps, lapses, type, original_deck_id.

Fixes

Approach

  • Added new public columns in FlashCardsContract.Card
  • Populated them in CardContentProvider.addCardToCursor()
  • Kept them opt-in, so DEFAULT_PROJECTION did not change

How Has This Been Tested?

  • added/updated ContentProviderTest coverage for the new fields
    Regarding below testing I tweaked the debug build to allow com.android.shell for manual provider queries; not part of the PR
  • manually queried the debug provider at content://com.ichi2.anki.debug.flashcards/cards
Screenshot 2026-03-26 at 2 58 28 AM - manually queried with explicit projection _id:reps:lapses:type:original_deck_id Screenshot 2026-03-26 at 2 59 37 AM

verified that querying without an explicit projection still returned the old default fields, so the new fields remain opt-in

Learning (optional, can help others)

Have shared my learnings here in this comment

Checklist

Please, go through these checks before submitting the PR.

  • You have a descriptive commit message with a short title (first line, max 50 chars).
  • You have commented your code, particularly in hard-to-understand areas
  • You have performed a self-review of your own code
  • [] UI changes: include screenshots of all affected screens (in particular showing any new or changed strings)
  • [] UI Changes: You have tested your change using the Google Accessibility Scanner

Copy link
Copy Markdown
Member

@david-allison david-allison left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great start! Sorry, there's going to be a fair amount of nitpicking over the API, as breaking changes are hard work.

@@ -608,6 +608,26 @@ public object FlashCardsContract {
*/
public const val DECK_ID: String = "deck_id"

/**
* The total number of reviews this card has received.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be more detailed. What's a review? When does the count start? Does rescheduling cause this? Grade Now?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hope this helps - b8f96bb

public const val REPS: String = "reps"

/**
* The total number of times this card has lapsed.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be more detailed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hope this helps - b8f96bb

public const val LAPSES: String = "lapses"

/**
* The raw card type code. This is distinct from queue and note type.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Give values and meaning

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done b8f96bb

Comment thread api/src/main/java/com/ichi2/anki/FlashCardsContract.kt
public const val TYPE: String = "type"

/**
* The original deck id for cards currently in a filtered deck. This is 0 for regular cards.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reword 'regular cards' to be more precise

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done b8f96bb

}

@Test
fun testQueryCardRawPropertiesAcrossCardUris() {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One test per property. Compare to the value you set on the card, not the value on the Card object

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done - b8f96bb

@lonewolf2208 lonewolf2208 marked this pull request as ready for review March 25, 2026 22:18
Copy link
Copy Markdown
Member

@david-allison david-allison left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests don't run

@Ayush-Patel-56
Copy link
Copy Markdown
Contributor

Hi @lonewolf2208 try to use semantic commits

@david-allison david-allison added the Needs Author Reply Waiting for a reply from the original author label Mar 26, 2026
@lonewolf2208
Copy link
Copy Markdown
Contributor Author

Apologies @david-allison fixed the tests now

@Begarudev

This comment was marked as low quality.

@lonewolf2208
Copy link
Copy Markdown
Contributor Author

@david-allison a friendly reminder to review this

@david-allison david-allison requested a review from a team April 4, 2026 18:35
@david-allison david-allison changed the title Added fields to cards endpoints [API] Added fields to cards endpoints Apr 4, 2026
Copy link
Copy Markdown
Member

@david-allison david-allison left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahaa... API change, so docs should be 'perfect'

Code doesn't need changes.

Comment thread api/src/main/java/com/ichi2/anki/FlashCardsContract.kt Outdated
Comment thread api/src/main/java/com/ichi2/anki/FlashCardsContract.kt Outdated
public const val LAPSES: String = "lapses"

/**
* The stored Anki card type code. This is distinct from queue and note type.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this helps describe the concept.

The type is the 'stage' in learning: treat it as a FSM. A card moves from 0 to 1, to 2, then from 2 to 3, to 2...

queue shares a lot of the same values, but it's about how to select the card: temporary actions such as bury or suspend can change the queue of a card to stop it from being displayed. The 'type' is more permanent: suspending and unsuspending a card would not impact whether to use learning steps or the card properties, and also does not affect FSRS.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lmk if this works - fcca098

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added more comments - this is the onyl one I feel could do with another round

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies @david-allison, for requesting another review on the same item. I’ve made the updates and hope it’s clearer this time - 55e9eea

Comment thread api/src/main/java/com/ichi2/anki/FlashCardsContract.kt Outdated
Copy link
Copy Markdown
Member

@david-allison david-allison left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ALMOST THERE!!!! Thanks so much. Great job with the links

Comment thread api/src/main/java/com/ichi2/anki/FlashCardsContract.kt Outdated
Comment thread api/src/main/java/com/ichi2/anki/FlashCardsContract.kt Outdated
Comment thread api/src/main/java/com/ichi2/anki/FlashCardsContract.kt Outdated
Copy link
Copy Markdown
Member

@david-allison david-allison left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much!

Comment on lines +641 to +642
* Think of this as a simple state machine that affects how the card is scheduled when it
* is answered. A card typically moves `0 -> 1 -> 2`; if a review card lapses, it
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A little informal, but I like it. LGTM!

@david-allison david-allison added Needs Second Approval Has one approval, one more approval to merge and removed Needs Author Reply Waiting for a reply from the original author labels Apr 5, 2026
@NicolasNewman
Copy link
Copy Markdown

Awesome seeing this already been done! This is my first time using the API and I was scratching my head trying to figure out how to access type before realizing it wasn't exposed. Looking forward to seeing it get merged in!

@david-allison
Copy link
Copy Markdown
Member

@NicolasNewman Thanks!!

Feel free to list anything you create here: https://github.com/ankidroid/Anki-Android/wiki/Third-Party-Apps

Copy link
Copy Markdown
Member

@mikehardy mikehardy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm all for API changes (well, well-considered ones) - the beauty of open code and open APIs is that you have no idea what people will build, but they can't if you don't open it up.

That's just a philosophical statement, you've put in the work here so I'm sure I'm preaching to the choir. Well done, and thanks, let's go

@mikehardy mikehardy added Pending Merge Things with approval that are waiting future merge (e.g. targets a future release, CI wait, etc) and removed Needs Second Approval Has one approval, one more approval to merge labels Apr 19, 2026
Refine card field docs and tests

test: fix nullable cursor handling in provider tests

docs: refine card field KDoc in FlashCardsContract

docs: clarify FlashCardsContract.Card.TYPE KDoc
@mikehardy mikehardy force-pushed the issue-20458-card-raw-fields branch from 55e9eea to e299c47 Compare April 19, 2026 15:47
@mikehardy
Copy link
Copy Markdown
Member

Pulled PR locally, rebased to current main, ran ./gradlew jacocoTestReport to verify I hadn't messed anything up and that it worked with current code.

Going to squash locally (these seem like a single change...) then re-push with the commits nicely in the squash, then en-queue for our normal rebase-merge-queue

🫡

@mikehardy mikehardy enabled auto-merge April 19, 2026 15:47
@mikehardy mikehardy added this pull request to the merge queue Apr 19, 2026
Merged via the queue into ankidroid:main with commit 570c05a Apr 19, 2026
15 checks passed
@github-actions github-actions bot added this to the 2.24 release milestone Apr 19, 2026
@github-actions github-actions bot removed the Pending Merge Things with approval that are waiting future merge (e.g. targets a future release, CI wait, etc) label Apr 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expand CardContentProvider with more fields from Card

6 participants