# A Simple HOWTO for Using
Berkeley DB Java Edition
on the
Android Platform

3.3.62, June 04, 2008

## Overview

JE can be used with the Google Android platform. This document discusses how to create a simple program and UI which will allow a user to do trivial JE "gets" and "puts" from within Android.

## Installation

- Start by downloading and installing the Android SDK. Put the Android "tools" directory in your path so that you pick up the command line tools.

## Steps With Android Eclipse Plugin

- Follow the installation instructions to install and configure the Android Eclipse plugin.
- Go to `"File->New->Other Project->Android->Android Project"`. Then provide a Project name, application name, package name (`com.sleepycat.je`), and activity name (`JEExample`).
- Go to "`Project->Properties->Java Build Path->libraries`", and select the "`Add External JARs`" button to add `JE-Version.jar` into the build path.
- Copy `JEExample.java`, `main.xml` and `strings.xml` (see below) to the activity source, `res/layout/main.xml`, and `res/values/strings.xml` (resp.).
- Build a new Configure Launch for this project, then run it as an Android project.

## Steps Witout Android Eclipse Plugin

- Create a `work` directory (referred to as `<work-dir>` in this document).
- Unpack the JE distribution into that directory. If you've already unpacked JE into another location, you can move that directory into the `<work-dir>` but note that the next step is to remove some files, so your distribution will be missing some files found in the original distribution. In the following text, the "je" directory refers to the je-M.N.P directory, where M, N, and P are the release major, minor, and patch versions.
- Remove the `<work-dir>/je/examples`, `<work-dir>/je/src/com/sleepycat/je/jca`, and `<work-dir>/je/test` directories. This step is necessary because Android will attempt to compile all `.java` files in the `<work-dir>`.
- Review `<android-home>/docs/intro/hello-android.html` for instructions on how to create a project. Do
  `activityCreator --out <work-dir> com.sleepycat.je.JEExample`
  This creates `<work-dir>/src/com/sleepycat/je/JEExample.java`
- Replace the `compile` target in the <work-dir>/build.xml with following:
  `<target name="compile" depends="dirs, resource-src, aidl">
  <javac encoding="ascii" target="1.5" debug="true" extdirs=""
  srcdir="."
  destdir="${outdir-classes}">
  <classpath>
  <pathelement location="location of your jdk tooks.jar"/>
  <pathelement location="${android-jar}"/>
  </classpath>
  </javac>
  </target>
  `
- Replace the generated contents of `<work-dir>/src/com/sleepycat/je/JEExample.java`, `<work-dir>/res/layout/main.xml`, `<work-dir>/res/value/strings.xml` with codes of the JEExample.java, main.xml and strings.xml at the bottom of this file.
- In `<work-dir>`, do
  `ant`
  This should build JE and `JEExample.java` as well as convert the resulting class files to dex files. This also creates
  `<work-dir>/bin/JEExample.apk`
- Run the Android emulator.
- Install the JEExample application.
  `adb install bin/JEExample.apk`

## Run the test

- Run the JEExample application in the emulator by clicking on the Home icon, then the Applications folder, then the JEExample icon. A screen titled "JEExample" should appear with a TextEdit box, a "Put Data" button, and a "Get Data" button.
- Put some key/data pairs into the JE database by entering (e.g.)
  `k1/data1`
  and pressing the "Put Data" button.
- Retrieve ("get") key/data pairs from the JE database by entering (e.g.)
  `k1`
  and pressing the "Get Data" button.

## Source Code

- JEExample.java

      package com.sleepycat.je;

      import android.app.Activity;
      import android.app.AlertDialog;
      import android.util.Log;
      import android.os.Bundle;
      import android.view.View;
      import android.widget.Button;
      import android.widget.EditText;
      import android.widget.TextView;

      import java.io.File;

      import com.sleepycat.je.Database;
      import com.sleepycat.je.DatabaseConfig;
      import com.sleepycat.je.DatabaseEntry;
      import com.sleepycat.je.DatabaseException;
      import com.sleepycat.je.Environment;
      import com.sleepycat.je.EnvironmentConfig;
      import com.sleepycat.je.OperationStatus;
      import com.sleepycat.je.Transaction;

      public class JEExample extends Activity {

          @Override
          public void onCreate(Bundle icicle) {
              super.onCreate(icicle);

              try {
                  final File envDir = new File("/data/je");
                  final EnvironmentConfig envConfig = new EnvironmentConfig();
                  envConfig.setTransactional(true);
                  envConfig.setAllowCreate(true);
                  final Environment env = new Environment(envDir, envConfig);
                  final DatabaseConfig dbConfig = new DatabaseConfig();
                  dbConfig.setTransactional(true);
                  dbConfig.setAllowCreate(true);
                  final Database db = env.openDatabase(null, "exampledb", dbConfig);

                  setContentView(R.layout.main);
                  final Button button1 = (Button) findViewById(R.id.do_put);
                  button1.setOnClickListener(new Button.OnClickListener() {
                      public void onClick(View v) {

                          final EditText editText =
                              (EditText) findViewById(R.id.entry);
                          final String keyData = editText.getText().toString();
                          final int idx = keyData.indexOf("/");
                          String key = null;
                          String data = null;
                          String result = null;
                          if (idx < 0) {
                              result = "enter key/data to put";
                          } else {
                              key = keyData.substring(0, idx);
                              data = keyData.substring(idx + 1);
                              result = key + "/" + data;
                              final DatabaseEntry keyEntry =
                                  new DatabaseEntry(key.getBytes());
                              final DatabaseEntry dataEntry =
                                  new DatabaseEntry(data.getBytes());

                              try {
                                  final Transaction txn =
                                      env.beginTransaction(null, null);
                                  final OperationStatus res =
                                      db.put(txn, keyEntry, dataEntry);
                                  if (res != OperationStatus.SUCCESS) {
                                      result = "Error: " + res.toString();
                                  }
                                  txn.commit();
                              } catch (DatabaseException DE) {
                                  result = "Caught exception: " + DE.toString();
                              }
                          }
                          Log.d("JE", "did put of: " + result);

                          if (result.contains("Caught exception:")) {
                              AlertDialog.show(JEExample.this, "Put Data", 0,
                                               "Put Data Failed!", "Quit", true);
                          } else {
                              AlertDialog.show(JEExample.this, "Put Data", 0,
                                               "Put Data Successful!", "Quit", true);
                          }
                      }
                  });

                  final Button button2 = (Button) findViewById(R.id.do_get);
                  button2.setOnClickListener(new Button.OnClickListener() {
                      public void onClick(View v) {

                          final EditText editText =
                              (EditText) findViewById(R.id.entry);
                          final String key = editText.getText().toString();
                          final DatabaseEntry keyEntry =
                              new DatabaseEntry(key.getBytes());
                          final DatabaseEntry dataEntry = new DatabaseEntry();
                          String result = null;
                          try {
                              final Transaction txn =
                                  env.beginTransaction(null, null);
                              final OperationStatus res =
                                  db.get(txn, keyEntry, dataEntry, null);
                              if (res != OperationStatus.SUCCESS) {
                                  result = "Error: " + res.toString();
                              } else {
                                  result = new String(dataEntry.getData());
                              }
                              txn.commit();
                          } catch (DatabaseException DE) {
                              result = "Caught exception: " + DE.toString();
                          }
                          Log.d("JE", "did get of: " + result);
                          if (result.contains("Caught exception:")) {
                              AlertDialog.show(JEExample.this, "Get Data", 0,
                                               "Get Data Failed", "Quit", true);
                          } else {
                              AlertDialog.show(JEExample.this, "Get Data", 0,
                                               result, "Quit", true);
                          }
                      }
                  });
              } catch (Exception DE) {
                  TextView tv = new TextView(this);
                  tv.setText("blew chunks " + DE);
                  setContentView(tv);
              }
          }
      }

  Note: You should create the JE environment directory by doing: "`adb shell mkdir /data/je`"
  You can remove the JE Environment files by doing "`adb shell rm /data/je/*`".
- res/layout/main.xml

      <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="vertical"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          >

        <TextView android:id="@+id/label"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:text="JEExample"
          />

        <EditText android:id="@+id/entry"
                  android:layout_width="fill_parent"
                  android:layout_height="wrap_content"
                  android:background="@android:drawable/editbox_background"
                  android:layout_below="@id/label"
          />

        <Button android:id="@+id/do_put"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/button_put"
          />

        <Button android:id="@+id/do_get"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/button_get"
          />
      </LinearLayout>

- res/values/strings.xml

      <?xml version="1.0" encoding="utf-8"?>
      <resources>
          <string name="app_name">JEExample</string>
          <string name="button_put">Put Data</string>
          <string name="button_get">Get Data</string>
      </resources>

Please report bugs to the Berkeley DB Java Edition OTN forum.