Recently Written · git

subread-dictionary

Pop-up dictionary for Android that reads Yomitan dictionaries, with local audio

git clone https://github.com/equwal/subread-dictionary

Log | Files | Refs


docs/provider-api.md (2687 bytes)

1 # The content provider of SubRead Dictionary
2 
3 Another app can ask SubRead Dictionary for the terms of a text and for the audio of a term.
4 SubRead Anki does this for the definition, the reading and the word audio of a card. The
5 provider reads the dictionaries and the audio sources that the user set up in the app.
6 
7 The authority is `space.subread.dictionary.lookup` (`space.subread.dictionary.debug.lookup`
8 for a debug build). On Android 11 and later, the manifest of the caller needs it in its
9 queries:
10 
11 ```xml
12 <queries>
13     <provider android:authorities="space.subread.dictionary.lookup" />
14 </queries>
15 ```
16 
17 ## Terms
18 
19 ```
20 content://space.subread.dictionary.lookup/terms?text=食べた&offset=0
21 ```
22 
23 One row per term that starts at `offset` in `text`, the longest first, then the dictionaries
24 in the order of the settings, then the higher score first. No row when nothing matches or no
25 dictionary is enabled.
26 
27 | Column | Type | What |
28 |---|---|---|
29 | `expression` | text | The term as the dictionary writes it: `食べる`. |
30 | `reading` | text | The reading, in kana. The expression itself when the dictionary gives none. |
31 | `length` | integer | How many characters of the text, from the offset, the term covers. |
32 | `reasons` | text | The deinflection from the text to the term, separated by spaces: `past`. Empty for the dictionary form. |
33 | `dictionary` | text | The title of the dictionary. |
34 | `definition_html` | text | The glossary as simple HTML: `b`, `i`, `u`, `br`, `ul`, `li`, `a`. |
35 | `score` | real | The score of the term in its dictionary. |
36 
37 ## Audio
38 
39 ```
40 content://space.subread.dictionary.lookup/audio?expression=食べる&reading=たべる
41 ```
42 
43 One row when a source has the audio: the local sources in the order of the settings, then
44 the remote ones when they are on. No row when none has.
45 
46 | Column | What |
47 |---|---|
48 | `file` | The name of the file in the cache of the app. |
49 | `mime` | `audio/mpeg`, `audio/ogg`, `audio/wav`, `audio/flac` or `audio/mp4`. |
50 
51 The bytes are then at `content://space.subread.dictionary.lookup/audio/<file>`, to read with
52 `openInputStream`. The file stays for an hour.
53 
54 ```kotlin
55 val uri = Uri.parse("content://space.subread.dictionary.lookup/audio")
56     .buildUpon().appendQueryParameter("expression", "食べる").appendQueryParameter("reading", "たべる").build()
57 val name = contentResolver.query(uri, null, null, null, null)?.use { c ->
58     if (c.moveToFirst()) c.getString(c.getColumnIndexOrThrow("file")) else null
59 }
60 val bytes = name?.let { contentResolver.openInputStream(Uri.parse("content://space.subread.dictionary.lookup/audio/$it"))?.readBytes() }
61 ```
62 
63 The provider is read only: `insert`, `update` and `delete` throw.