diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 34c7a2c..f31f822 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -117,6 +117,13 @@
android:name="android.support.PARENT_ACTIVITY"
android:value="i2p.bote.android.config.ViewIdentityActivity" />
+
+
+
diff --git a/app/src/main/java/i2p/bote/android/config/IdentityShipActivity.java b/app/src/main/java/i2p/bote/android/config/IdentityShipActivity.java
new file mode 100644
index 0000000..0532267
--- /dev/null
+++ b/app/src/main/java/i2p/bote/android/config/IdentityShipActivity.java
@@ -0,0 +1,48 @@
+package i2p.bote.android.config;
+
+import android.os.Bundle;
+import android.support.v7.app.ActionBarActivity;
+import android.widget.Toast;
+
+import i2p.bote.android.InitActivities;
+import i2p.bote.android.R;
+
+public class IdentityShipActivity extends ActionBarActivity implements
+ IdentityShipFragment.Callbacks {
+ public static final String EXPORTING = "exporting";
+
+ boolean mExporting;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_identity_ship);
+
+ // Initialize I2P settings
+ InitActivities init = new InitActivities(this);
+ init.initialize();
+
+ // Enable ActionBar app icon to behave as action to go back
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+
+ if (savedInstanceState == null) {
+ Bundle args = getIntent().getExtras();
+ mExporting = args.getBoolean(EXPORTING);
+ IdentityShipFragment f = IdentityShipFragment.newInstance(mExporting);
+ getSupportFragmentManager().beginTransaction()
+ .add(R.id.identity_ship_frag, f).commit();
+ }
+ }
+
+ // IdentityShipFragment.Callbacks
+
+ public void onTaskFinished() {
+ Toast.makeText(this,
+ mExporting ?
+ R.string.identities_exported :
+ R.string.identities_imported,
+ Toast.LENGTH_SHORT).show();
+ setResult(RESULT_OK);
+ finish();
+ }
+}
diff --git a/app/src/main/java/i2p/bote/android/config/IdentityShipFragment.java b/app/src/main/java/i2p/bote/android/config/IdentityShipFragment.java
new file mode 100644
index 0000000..83af56b
--- /dev/null
+++ b/app/src/main/java/i2p/bote/android/config/IdentityShipFragment.java
@@ -0,0 +1,263 @@
+package i2p.bote.android.config;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Environment;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import java.io.File;
+
+import i2p.bote.I2PBote;
+import i2p.bote.android.R;
+import i2p.bote.android.util.RobustAsyncTask;
+import i2p.bote.android.util.TaskFragment;
+
+public abstract class IdentityShipFragment extends Fragment {
+ private Callbacks mCallbacks = sDummyCallbacks;
+
+ public interface Callbacks {
+ public void onTaskFinished();
+ }
+
+ private static Callbacks sDummyCallbacks = new Callbacks() {
+ public void onTaskFinished() {}
+ };
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ if (!(activity instanceof Callbacks))
+ throw new IllegalStateException("Activity must implement fragment's callbacks.");
+ mCallbacks = (Callbacks) activity;
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ mCallbacks = sDummyCallbacks;
+ }
+
+ // Code to identify the fragment that is calling onActivityResult().
+ static final int SHIP_WAITER = 0;
+ // Tag so we can find the task fragment again, in another
+ // instance of this fragment after rotation.
+ static final String SHIP_WAITER_TAG = "shipWaiterTask";
+
+ TextView mError;
+
+ public static IdentityShipFragment newInstance(boolean exporting) {
+ return new ExportIdentitiesFragment(); // TODO implement importing
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setHasOptionsMenu(true);
+
+ ShipWaiterFrag f = (ShipWaiterFrag) getFragmentManager().findFragmentByTag(SHIP_WAITER_TAG);
+ if (f != null)
+ f.setTargetFragment(this, SHIP_WAITER);
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ mError = (TextView) view.findViewById(R.id.error);
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == SHIP_WAITER) {
+ if (resultCode == Activity.RESULT_OK) {
+ mCallbacks.onTaskFinished();
+ } else if (resultCode == Activity.RESULT_CANCELED) {
+ setInterfaceEnabled(true);
+ mError.setText(data.getStringExtra("error"));
+ }
+ } else {
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+ }
+
+ protected abstract void setInterfaceEnabled(boolean enabled);
+
+ public static class ShipWaiterFrag extends TaskFragment