Aedict

Multi-Functional Dictionary Every Japanese Learner Needs

Save several hundred dollars/euros, no hardware dictionary necessary. The only Japanese dictionary for Android worth paying for.

Get it on Google Play Get it on Amazon AppStore Get it on Amazon Underground

Detecting Aedict

Aedict 3.x presence can be queried as follows:

public static boolean isAedictPresent(Activity context) {
    final Intent intent = new Intent("sk.baka.aedict3.action.ACTION_SEARCH_JMDICT");
    return !activity.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY).isEmpty();
}

Searching for a string in Aedict

Important: you can use Service API to query Aedict, since Aedict 3.30. For more details, please scroll down.

To display the Search Activity in Aedict, you can use the following intent: "sk.baka.aedict3.action.ACTION_SEARCH_JMDICT".

Intent ExtraSinceTypeMeaning
kanjis 2.0 String What to search for. Aedict 3.x accepts anything: kanji, hiragana, katakana, romaji, english, french, etc. Aedict 3.x also automatically deinflects words. See other parameters for details.
deinflect 3.2 Boolean Defaults to true. If set to false, no verb deinflection is performed.
match_jp 3.2 Enum Defaults to StartsWith. May have the following values: Exact - exact match; StartsWith - matches any JMDict entry starting with given term; EndsWith - matches any JMDict entry ending with given term; Substring - matches any JMDict entry which contains given term
match_sense 3.2 Enum Defaults to Exact. Defines how the term is matched to the sense (english, french, dutch, etc) part of the JMDict entry. May have the following values: Exact - exact word match, e.g. "auto" will match "auto mechanic" but not "automechanic"; StartsWith - "car" will match "crane carrier" but not "ecar"; EndsWith and Substring are unsupported because of Lucene limitations
analysis_fallback 3.2 Boolean Defaults to true. If true, Aedict will try to analyze given japanese sentence present in the "kanjis" field if JMDict search returns no results. If false, analysis is not performed and Aedict simply displays "No Results"
search_in_examples 3.2 Boolean Defaults to false. If false, JMDict search is performed. If true, Tatoeba example sentence search is performed.
search_in_kanjidic 3.4.35BooleanDefaults to false. If false, JMDict search is performed. If true, Kanjidic2 search is performed.
return_results3.4.9BooleanDefaults to false. If false, results are simply shown in Aedict as a list. If true, results are returned as a result intent - just send this intent using startActivityForResult() function and then wait for the response intent in the onActivityResult() function; more info here: http://developer.android.com/training/basics/intents/result.html. The intent will contain serializable extra "result", which can be cast to ArrayList<HashMap<String, String>>. The result will contain a list of entries, represented as a HashMap, mapping from variable name (omitting the starting/trailing percent characters) to the variable contents. For a list of variables, please see Custom Export Format; also see bug #243 for details.
return_user_selected_result3.4.35BooleanDefaults to false. If true and the user clicks an entry, the entry itself is sent back as a response data Intent, containing all tags as String extras.
prolong_vowels3.4.31BooleanDefaults to false. If true, searching e.g. for shojiki will also find shoujiki
jlpt3.4.31IntegerMissing by default, 1..5, corresponds to JNLP N1..N5 levels, N5 being the easiest one. Only applicable to JMDict search. If specified, result words must belong to the JNLP level specified
commonOnly3.4.31BooleanDefaults to false. Applicable to JMDict search only. If true, only common words (P) are returned
showEntryDetailOnSingleResult3.7BooleanDefaults to false. If true and the search produces only one entry, that one entry's details is shown immediately. However, if return_results is set to true then this is ignored
maxResults3.32IntegerDefaults to 200 for JMDict search, 100 for example sentence search. Maximum number of results to return.
disable_globbing3.39.12BooleanDefaults to false. If true, * and ? characters are treated as other delimiters and ignored.

Example:

final Intent intent = new Intent("sk.baka.aedict3.action.ACTION_SEARCH_JMDICT");
intent.putExtra("kanjis", "saseru");
intent.putExtra("deinflect", false);
intent.putExtra("match_jp", "Exact");
startActivity(intent);

Searching for a string in Aedict, no UI

If you wish to use return_results but you do not like Aedict showing you UI, please use "sk.baka.aedict3.action.ACTION_SEARCH_JMDICT_NOUI" action instead. You can use all of the parameters mentioned above; however the return_results parameter will be ignored and will always be true. This is available since Aedict 3.18.

Exporting Flashcard

Aedict is able to export selected entry as a flash card, by sending a special intent, with the following contents:

Intent Action"org.openintents.action.CREATE_FLASHCARD"
Intent extra "SOURCE_TEXT""Aedict Notepad"
Intent extra "TARGET_TEXT"The String entry details in the form of "[default]\n"+ kanji + " [" + reading +"]:" + english

Aedict 3.4.9 is now also able to export intents as described here: https://code.google.com/p/ankidroid/wiki/AddIntent#Proposed_new_Intent. For more information see bug #264

Kanji search activities

Since Aedict 3.5, you can start the following action to search for a kanji (all data entered by the user):

  • sk.baka.aedict3.action.ACTION_SEARCH_UNITED

You can start the activity as follows:

final Intent intent = new Intent("sk.baka.aedict3.action.ACTION_SEARCH_UNITED");
startActivityForResult(intent, xx);

When the user clicks a kanji, the activity terminates and the kanji is returned, in the kanji field:

public void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (requestCode == xx && resultCode == Activity.RESULT_OK) {
    String kanji = data.getStringExtra("kanji");
    // do something with the kanji.
  }
}

Programmatic Kanji search

Since Aedict 3.4.35, you can send the following intent, to search by kanji parts or the SKIP code: the "sk.baka.aedict3.action.ACTION_SEARCH_KANJIDIC2" intent. When fired, Aedict3 will perform a search, it will show result list to the user and the selected kanji is returned back to the caller activity. The following table summarizes the intent parameters:

Intent ExtraSinceTypeMeaning
parts3.4.35StringAll parts the kanji must contain. Note that if a non-part character is present, the result will return zero results
skip3.4.35StringIgnored if parts extra is not null. If present, it must be in the format of 4-1-4

Example:

final Intent intent = new Intent("sk.baka.aedict3.action.ACTION_SEARCH_KANJIDIC2");
intent.putExtra("parts", "豆頁");
startActivityForResult(intent, xx);

When the user clicks a kanji, the activity terminates and the kanji is returned, in the kanji field:

public void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (requestCode == xx && resultCode == Activity.RESULT_OK) {
    String kanji = data.getStringExtra("kanji");
    // do something with the kanji 頭
  }
}

Resolve Kanjis

Since Aedict 3.7:

final Intent intent = new Intent("sk.baka.aedict3.action.ACTION_RESOLVE_KANJIDIC2");
intent.putExtra("kanji", "豆頭");
startActivityForResult(intent, xx);

Will result in an immediate response, with no UI being displayed at Aedict's side:

public void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (requestCode == xx && resultCode == Activity.RESULT_OK) {
    List> result = data.getSerializableExtra("result");
    String readingOf豆 = result.get(0).get("reading");
    ...
  }
}

The intent will contain serializable extra "result", which can be cast to List<HashMap<String, String>>. The result will contain a list of entries, represented as a HashMap, mapping from variable name (omitting the starting/trailing percent characters) to the variable contents. For a list of variables, please see Custom Export Format.

Since Aedict 3.31: To resolve given kanji set and show the result on-screen, in Aedict's activity:

final Intent intent = new Intent("sk.baka.aedict3.action.ACTION_RESOLVE_KANJIS");
intent.putExtra("kanjis", "豆頭");
startActivity(intent);

This will show a list with two kanjis, 豆 and 頭.

Service API

Since Aedict 3.30: You can now query Aedict Service API instead of launching Intents. This has the advantage that Aedict is really hidden in the background, and the API is simpler. Just use the following helper class freely.


import java.util.List;
import java.util.Map;

import org.jetbrains.annotations.NotNull;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;

/**
 * A simple Aedict client. Just create the client in your Activity onStart() method and destroy it in your Activity onStop() method.
 * @author mvy
 */
public class AedictClient {

	private final Listener listener;
	private final Context context;

	/**
	 * @param listener notifies you of results computed by Aedict.
	 */
	public AedictClient(Context context, Listener listener) {
		this.listener = listener;
		this.context = context;
		final Intent intent = new Intent("sk.baka.aedict3.action.ACTION_SEARCH_SERVICE");
		// the intent must be explicit, otherwise Jellybean will crash
		// http://stackoverflow.com/questions/27981246/dealing-with-implicit-intent-future-deprecation-in-lollipop
		intent.setPackage("sk.baka.aedict3");
		context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
		mIsBound = true;
	}

	public interface Listener {
		/**
		 * Notifies you of result.
		 * @param entries a list of result entries, represented as a map, mapping variable name to a value. For example,
		 * the map will contain key "kanji" with the value of "母". See http://aedict.eu/export.html for a list of all variables which
		 * will be present in the map. Never null, may be empty.
		 */
		void onResult(List<Map<String, String>> entries);
	}

	/**
	 * http://aedict.eu/api.html
	 * See the ACTION_SEARCH_JMDICT Activity.
	 */
	private static final int SEARCH_JMDICT = 0;

	/**
	 * http://aedict.eu/api.html
	 * 

* See the ACTION_RESOLVE_KANJIDIC2 Activity. */ private static final int RESOLVE_KANJI = 1; private class IncomingHandler extends Handler { @Override public void handleMessage(@NotNull Message msg) { final List<Map<String, String>> result = (List<Map<String, String>>) msg.getData().getSerializable("result"); listener.onResult(result); } } private final Messenger messenger = new Messenger(new IncomingHandler()); /** * Performs JMDict/Tatoeba search. See http://aedict.eu/api.html for more information. * @param kanjis the search query, Aedict 3.x accepts anything: kanji, hiragana, katakana, romaji, english, french, etc. Aedict 3.x also automatically deinflects words. See other parameters for details. * @param otherArgs other arguments as specified at http://aedict.eu/api.html * @throws RemoteException */ public void searchJmdict(String kanjis, Bundle otherArgs) throws RemoteException { if (otherArgs == null) { otherArgs = new Bundle(); } otherArgs.putString("kanjis", kanjis); send(SEARCH_JMDICT, otherArgs); } private void send(int what, Bundle b) throws RemoteException { final Message msg = Message.obtain(null, what); msg.setData(b); msg.replyTo = messenger; aedictService.send(msg); } /** * Resolves all given kanji characters. All non-kanji characters are ignored. * @param kanji resolve given Kanji characters, e.g. "豆頭" * @throws RemoteException */ public void resolveKanjis(String kanji) throws RemoteException { final Bundle b = new Bundle(); b.putString("kanji", kanji); send(RESOLVE_KANJI, b); } private Messenger aedictService = null; private boolean mIsBound; /** * Class for interacting with the main interface of the service. */ private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { aedictService = new Messenger(service); } public void onServiceDisconnected(ComponentName className) { aedictService = null; } }; /** * Call in your Activity onStop(), to unbind from the search service. */ public void destroy() { if (mIsBound) { context.unbindService(mConnection); mIsBound = false; } } }

Links