React Native wrapper for the AnkiDroid API
React Native wrapper for the AnkiDroid API
npm install react-native-ankidroid --save
The library will be automatically linked BUT step 4 of the manual installation is still required.
react-native link react-native-ankidroid
android/app/src/main/java/[...]/MainActivity.java
import com.is343.reactnativeankidroid.AnkiDroidPackage;
to the imports at the top of the filenew AnkiDroidPackage()
to the list returned by the getPackages()
methodAppend the following lines to android/settings.gradle
:
include ':react-native-ankidroid'
project(':react-native-ankidroid').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-ankidroid/android')
Insert the following lines inside the dependencies block in android/app/build.gradle
:
implementation project(':react-native-ankidroid')
Add the following lines to /android/app/src/main/res/AndroidManifest.xml
:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" // <---- ADD HERE
package="com.yourpackage.name">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<application
android:name="com.yourpackage.name.MainApplication"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:allowBackup="true"
android:theme="@style/AppTheme"
tools:replace="android:allowBackup" // <---- ADD HERE
>
Execution failed for task ':app:processDebugManifest'.
> Manifest merger failed : Attribute application@allowBackup value=(false) from AndroidManifest.xml:15:7-34 is also present at [com.github.ankidroid:Anki-Android:api-v1.1.0] AndroidManife
st.xml:14:9-35 value=(true).
Suggestion: add 'tools:replace="android:allowBackup"' to <application> element at AndroidManifest.xml:7:5-117 to override.
import AnkiDroid from 'react-native-ankidroid';
await AnkiDroid.isApiAvailable();
AnkiDroid.____________ *(returns a Promise)
modelName
or modelId
is requiredfileUri
: the location of the media to uploadpreferredName
: the name that will be used to access the media in the cardmimeType
: can be either "audio"
or "image"
<img src="myimage.jpg">
and [sound:myaudio.mp3]
android.permission.MANAGE_EXTERNAL_STORAGE
permission granted if you intend to upload a file from external storagenew AnkiDroid(setupOptions)
- creates an instance of your deck[error, responseData]
null
. The data we want to retrieve will always be in the second valueParams | Type | Required | Description |
---|---|---|---|
deckProperties | object | optional if deckId exists |
properties required to search by name / create a new deck |
deckId | string | number | optional if deckProperties exists |
Id of the existing deck to add notes to |
modelProperties | object | optional if modelId exists |
Id of the existing model to add notes to |
modelId | string | number | optional if modelProperties exists |
properties required to search by name / create a new model |
Params | Type | Default | Description |
---|---|---|---|
reference | string | REQUIRED | Deck reference name to store locally in SharedPreferences |
name | string | REQUIRED | Name of the deck to create / add notes to (Will first search for deck by name before creating) |
Params | Type | Default | Description |
---|---|---|---|
name | string | REQUIRED | Name of the model used / created for notes (Will first search for deck by name before creating) |
reference | string | REQUIRED | Model reference name to store locally in SharedPreferences |
modelFields | string[] | REQUIRED | The names of the fields used for the note's model during creation / use (modelFields.length === valueFields.length) |
cardNames | string[] | REQUIRED | Names for the front/back sides of the model (cardNames.length === 2) |
questionFormat | string[] | REQUIRED | Question formatting for each direction of (questionFormat.length === 2) variable names MUST match modelFields names |
answerFormat | string[] | REQUIRED | Answer formatting for each direction of (answerFormat.length === 2) variable names MUST match modelFields names |
tags | string[] | null | Tags to attach to added notes |
css | string | null | css styling information to be shared across all cards. (null for default CSS) |
addNote(valueFields, modelFields)
Param | Type | Description |
---|---|---|
valueFields | string[] | The values for the corresponding model fields. (valueFields.length === modelFields.length) |
modelFields | string[] | The model fields that correspond to the model that will be used. (values must exactly match the model used) |
///////////////////////////////////
// SETTING UP THE DECK AND MODEL //
///////////////////////////////////
// Name of deck which will be created in AnkiDroid
const deckName = 'API Sample Name';
// Name of model which will be created in AnkiDroid (can be any string)
const modelName = 'Sample Model Name';
// Used to save a reference to this deck in the SharedPreferences (can be any string)
const dbDeckReference = 'com.your.app.decks';
// Used to save a reference to this model in the SharedPreferences (can be any string)
const dbModelReference = 'com.your.app.models';
// Optional space separated list of tags to add to every note
const tags = ['API_Sample', 'my', 'tags'];
// List of field names that will be used in AnkiDroid model
const modelFields = [
'Word',
'Translation',
'Meaning',
'Grammar',
'Idiom',
'IdiomTranslation',
'IdiomMeaning',
];
// List of card names that will be used in AnkiDroid (one for each direction of learning)
const cardNames = ['Korean>English', 'English>Korean'];
// CSS to share between all the cards (optional).
const css = `.card {
font-family: NotoSansKR;
font-size: 24px;
text-align: center;
color: black;
background-color: white;
word-wrap: break-word;
}
.big { font-size: 48px; }
.small { font-size: 18px;}`;
// Template for the question of each card
const questionFmt1 = '<div class=big>{{Word}}</div><br>{{Grammar}}';
const questionFmt2 =
'{{Meaning}}<br><br><div class=small>{{Grammar}}<br><br>({{Idiom}})</div>';
const questionFormat = [questionFmt1, questionFmt2];
// Template for the answer (this example is identical for both sides)
const answerFmt1 = `<div class=big>{{Translation}}</div><br>{{Meaning}}
<br><br>
{{IdiomTranslation}}<br>
<a href=\"#\" onclick=\"document.getElementById('hint').style.display='block';return false;\">Idiom Meaning</a>
<div id="hint" style="display: none">{{IdiomMeaning}}</div>
<br><br>
{{Grammar}}<br><div class=small>{{Tags}}</div>`;
const answerFormat = [answerFmt1, answerFmt1];
//////////////////
// ADDING NOTES //
//////////////////
const deckProperties = {
name: deckName,
reference: dbDeckReference,
};
const modelProperties = {
name: modelName,
reference: dbModelReference,
fields: modelFields,
tags,
cardNames,
questionFormat,
answerFormat,
css,
};
const valueFields = [
'사랑',
'love',
'The attitude of sincerely caring about someone out of affection.',
'noun',
'사랑을 속삭이다',
'whisper love',
'For lovers to have a conversation of love.',
];
const settings = {
modelId: undefined,
modelProperties: modelProperties,
deckId: undefined,
deckProperties: deckProperties,
};
const myAnkiDeck = new AnkiDroid(settings);
myAnkiDeck.addNote(valueFields, modelFields);
// returns a promise that returns the added note ID
const newNote = [
'여행사',
'travel agency',
'A company that offers an array of services for travel, including transportation, accomodaton, tour guide, etc.',
'noun',
'',
'',
'',
];
myAnkiDeck.addNote(newNote, modelFields);
npm install && npm run android
Pull requests welcome!