diff --git a/src/com/android/contacts/common/activity/RequestImportVCardPermissionsActivity.java b/src/com/android/contacts/common/activity/RequestImportVCardPermissionsActivity.java
index 865f20b..831f6f3 100644
--- a/src/com/android/contacts/common/activity/RequestImportVCardPermissionsActivity.java
+++ b/src/com/android/contacts/common/activity/RequestImportVCardPermissionsActivity.java
@@ -26,7 +26,6 @@
 
     private static final String[] REQUIRED_PERMISSIONS = new String[] {
             permission.READ_CONTACTS,
-            permission.WRITE_EXTERNAL_STORAGE,
     };
 
     @Override
diff --git a/src/com/android/contacts/common/interactions/ImportExportDialogFragment.java b/src/com/android/contacts/common/interactions/ImportExportDialogFragment.java
index 791ad2d..acef822 100644
--- a/src/com/android/contacts/common/interactions/ImportExportDialogFragment.java
+++ b/src/com/android/contacts/common/interactions/ImportExportDialogFragment.java
@@ -136,10 +136,9 @@
                 }
             }
         }
-        if (res.getBoolean(R.bool.config_allow_export_to_sdcard)) {
+        if (res.getBoolean(R.bool.config_allow_export)) {
             if (contactsAreAvailable) {
-                adapter.add(new AdapterEntry(getString(R.string.export_to_sdcard),
-                        R.string.export_to_sdcard));
+                adapter.add(new AdapterEntry(getString(R.string.export), R.string.export));
             }
         }
         if (res.getBoolean(R.bool.config_allow_share_visible_contacts)) {
@@ -162,7 +161,7 @@
                                 adapter.getItem(which).mSubscriptionId);
                         break;
                     }
-                    case R.string.export_to_sdcard: {
+                    case R.string.export: {
                         dismissDialog = true;
                         Intent exportIntent = new Intent(getActivity(), ExportVCardActivity.class);
                         exportIntent.putExtra(VCardCommonArguments.ARG_CALLING_ACTIVITY,
diff --git a/src/com/android/contacts/common/vcard/ExportVCardActivity.java b/src/com/android/contacts/common/vcard/ExportVCardActivity.java
index f956c7c..172f2f5 100644
--- a/src/com/android/contacts/common/vcard/ExportVCardActivity.java
+++ b/src/com/android/contacts/common/vcard/ExportVCardActivity.java
@@ -51,52 +51,8 @@
         DialogInterface.OnClickListener, DialogInterface.OnCancelListener {
     private static final String LOG_TAG = "VCardExport";
     private static final boolean DEBUG = VCardService.DEBUG;
-
-    /**
-     * Handler used when some Message has come from {@link VCardService}.
-     */
-    private class IncomingHandler extends Handler {
-        @Override
-        public void handleMessage(Message msg) {
-            if (DEBUG) Log.d(LOG_TAG, "IncomingHandler received message.");
-
-            if (msg.arg1 != 0) {
-                Log.i(LOG_TAG, "Message returned from vCard server contains error code.");
-                if (msg.obj != null) {
-                    mErrorReason = (String)msg.obj;
-                }
-                showDialog(msg.arg1);
-                return;
-            }
-
-            switch (msg.what) {
-            case VCardService.MSG_SET_AVAILABLE_EXPORT_DESTINATION:
-                if (msg.obj == null) {
-                    Log.w(LOG_TAG, "Message returned from vCard server doesn't contain valid path");
-                    mErrorReason = getString(R.string.fail_reason_unknown);
-                    showDialog(R.id.dialog_fail_to_export_with_reason);
-                } else {
-                    mTargetFileName = (String)msg.obj;
-                    if (TextUtils.isEmpty(mTargetFileName)) {
-                        Log.w(LOG_TAG, "Destination file name coming from vCard service is empty.");
-                        mErrorReason = getString(R.string.fail_reason_unknown);
-                        showDialog(R.id.dialog_fail_to_export_with_reason);
-                    } else {
-                        if (DEBUG) {
-                            Log.d(LOG_TAG,
-                                    String.format("Target file name is set (%s). " +
-                                            "Show confirmation dialog", mTargetFileName));
-                        }
-                        showDialog(R.id.dialog_export_confirmation);
-                    }
-                }
-                break;
-            default:
-                Log.w(LOG_TAG, "Unknown message type: " + msg.what);
-                super.handleMessage(msg);
-            }
-        }
-    }
+    private static final int REQUEST_CREATE_DOCUMENT = 100;
+    private static final String VCARD_MIME_TYPE = "text/vcard";
 
     /**
      * True when this Activity is connected to {@link VCardService}.
@@ -113,41 +69,11 @@
     private volatile boolean mProcessOngoing = true;
 
     private VCardService mService;
-    private final Messenger mIncomingMessenger = new Messenger(new IncomingHandler());
     private static final BidiFormatter mBidiFormatter = BidiFormatter.getInstance();
 
-    // Used temporarily when asking users to confirm the file name
-    private String mTargetFileName;
-
     // String for storing error reason temporarily.
     private String mErrorReason;
 
-    private class ExportConfirmationListener implements DialogInterface.OnClickListener {
-        private final Uri mDestinationUri;
-
-        public ExportConfirmationListener(String path) {
-            this(Uri.parse("file://" + path));
-        }
-
-        public ExportConfirmationListener(Uri uri) {
-            mDestinationUri = uri;
-        }
-
-        public void onClick(DialogInterface dialog, int which) {
-            if (which == DialogInterface.BUTTON_POSITIVE) {
-                if (DEBUG) {
-                    Log.d(LOG_TAG,
-                            String.format("Try sending export request (uri: %s)", mDestinationUri));
-                }
-                final ExportRequest request = new ExportRequest(mDestinationUri);
-                // The connection object will call finish().
-                mService.handleExportRequest(request, new NotificationImportExportListener(
-                        ExportVCardActivity.this));
-            }
-            unbindAndFinish();
-        }
-    }
-
     @Override
     protected void onCreate(Bundle bundle) {
         super.onCreate(bundle);
@@ -156,23 +82,10 @@
             return;
         }
 
-        // Check directory is available.
-        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
-            Log.w(LOG_TAG, "External storage is in state " + Environment.getExternalStorageState() +
-                    ". Cancelling export");
-            showDialog(R.id.dialog_sdcard_not_found);
-            return;
-        }
+        connectVCardService();
+    }
 
-        final File targetDirectory = Environment.getExternalStorageDirectory();
-        if (!(targetDirectory.exists() &&
-                targetDirectory.isDirectory() &&
-                targetDirectory.canRead()) &&
-                !targetDirectory.mkdirs()) {
-            showDialog(R.id.dialog_sdcard_not_found);
-            return;
-        }
-
+    private void connectVCardService() {
         final String callingActivity = getIntent().getExtras()
                 .getString(VCardCommonArguments.ARG_CALLING_ACTIVITY);
         Intent intent = new Intent(this, VCardService.class);
@@ -194,12 +107,35 @@
     }
 
     @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == REQUEST_CREATE_DOCUMENT) {
+            if (resultCode == Activity.RESULT_OK && data != null && data.getData() != null) {
+                final Uri mTargetFileName = data.getData();
+                if (DEBUG) Log.d(LOG_TAG, "exporting to " + mTargetFileName);
+                final ExportRequest request = new ExportRequest(mTargetFileName);
+                // The connection object will call finish().
+                mService.handleExportRequest(request, new NotificationImportExportListener(
+                        ExportVCardActivity.this));
+            } else if (DEBUG) {
+                Log.d(LOG_TAG, "create document cancelled or no data returned");
+            }
+            unbindAndFinish();
+        }
+    }
+
+    @Override
     public synchronized void onServiceConnected(ComponentName name, IBinder binder) {
         if (DEBUG) Log.d(LOG_TAG, "connected to service, requesting a destination file name");
         mConnected = true;
         mService = ((VCardService.MyBinder) binder).getService();
-        mService.handleRequestAvailableExportDestination(mIncomingMessenger);
-        // Wait until MSG_SET_AVAILABLE_EXPORT_DESTINATION message is available.
+
+        // Have the user choose where vcards will be exported to
+        final Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
+        intent.addCategory(Intent.CATEGORY_OPENABLE);
+        intent.setType(VCARD_MIME_TYPE);
+        intent.putExtra(Intent.EXTRA_TITLE, mBidiFormatter.unicodeWrap(
+                getString(R.string.exporting_vcard_filename), TextDirectionHeuristics.LTR));
+        startActivityForResult(intent, REQUEST_CREATE_DOCUMENT);
     }
 
     // Use synchronized since we don't want to call unbindAndFinish() just after this call.
@@ -216,31 +152,9 @@
         }
     }
 
-    /**
-     * Returns the name of the target path with additional formatting characters to improve its
-     * appearance in bidirectional text.
-     */
-    private String getTargetFileForDisplay() {
-        if (mTargetFileName == null) {
-            return null;
-        }
-        return mBidiFormatter.unicodeWrap(mTargetFileName, TextDirectionHeuristics.LTR);
-    }
-
     @Override
     protected Dialog onCreateDialog(int id, Bundle bundle) {
         switch (id) {
-            case R.id.dialog_export_confirmation: {
-                return new AlertDialog.Builder(this)
-                        .setTitle(R.string.confirm_export_title)
-                        .setMessage(getString(R.string.confirm_export_message,
-                                getTargetFileForDisplay()))
-                        .setPositiveButton(android.R.string.ok,
-                                new ExportConfirmationListener(mTargetFileName))
-                        .setNegativeButton(android.R.string.cancel, this)
-                        .setOnCancelListener(this)
-                        .create();
-            }
             case R.string.fail_reason_too_many_vcard: {
                 mProcessOngoing = false;
                 return new AlertDialog.Builder(this)
@@ -261,13 +175,6 @@
                         .setOnCancelListener(this)
                         .create();
             }
-            case R.id.dialog_sdcard_not_found: {
-                mProcessOngoing = false;
-                return new AlertDialog.Builder(this)
-                        .setIconAttribute(android.R.attr.alertDialogIcon)
-                        .setMessage(R.string.no_sdcard_message)
-                        .setPositiveButton(android.R.string.ok, this).create();
-            }
         }
         return super.onCreateDialog(id, bundle);
     }
@@ -276,24 +183,12 @@
     protected void onPrepareDialog(int id, Dialog dialog, Bundle args) {
         if (id == R.id.dialog_fail_to_export_with_reason) {
             ((AlertDialog)dialog).setMessage(mErrorReason);
-        } else if (id == R.id.dialog_export_confirmation) {
-            ((AlertDialog)dialog).setMessage(
-                    getString(R.string.confirm_export_message, getTargetFileForDisplay()));
         } else {
             super.onPrepareDialog(id, dialog, args);
         }
     }
 
     @Override
-    protected void onStop() {
-        super.onStop();
-
-        if (!isFinishing()) {
-            unbindAndFinish();
-        }
-    }
-
-    @Override
     public void onClick(DialogInterface dialog, int which) {
         if (DEBUG) Log.d(LOG_TAG, "ExportVCardActivity#onClick() is called");
         unbindAndFinish();
diff --git a/src/com/android/contacts/common/vcard/VCardService.java b/src/com/android/contacts/common/vcard/VCardService.java
index 0a50bec..b78c06f 100644
--- a/src/com/android/contacts/common/vcard/VCardService.java
+++ b/src/com/android/contacts/common/vcard/VCardService.java
@@ -57,12 +57,6 @@
 
     /* package */ final static boolean DEBUG = false;
 
-    /* package */ static final int MSG_IMPORT_REQUEST = 1;
-    /* package */ static final int MSG_EXPORT_REQUEST = 2;
-    /* package */ static final int MSG_CANCEL_REQUEST = 3;
-    /* package */ static final int MSG_REQUEST_AVAILABLE_EXPORT_DESTINATION = 4;
-    /* package */ static final int MSG_SET_AVAILABLE_EXPORT_DESTINATION = 5;
-
     /**
      * Specifies the type of operation. Used when constructing a notification, canceling
      * some operation, etc.
@@ -115,18 +109,6 @@
     private final List<CustomMediaScannerConnectionClient> mRemainingScannerConnections =
             new ArrayList<CustomMediaScannerConnectionClient>();
 
-    /* ** vCard exporter params ** */
-    // If true, VCardExporter is able to emits files longer than 8.3 format.
-    private static final boolean ALLOW_LONG_FILE_NAME = false;
-
-    private File mTargetDirectory;
-    private String mFileNamePrefix;
-    private String mFileNameSuffix;
-    private int mFileIndexMinimum;
-    private int mFileIndexMaximum;
-    private String mFileNameExtension;
-    private Set<String> mExtensionsToConsider;
-    private String mErrorReason;
     private MyBinder mBinder;
 
     private String mCallingActivity;
@@ -146,32 +128,6 @@
         super.onCreate();
         mBinder = new MyBinder();
         if (DEBUG) Log.d(LOG_TAG, "vCard Service is being created.");
-        initExporterParams();
-    }
-
-    private void initExporterParams() {
-        mTargetDirectory = Environment.getExternalStorageDirectory();
-        mFileNamePrefix = getString(R.string.config_export_file_prefix);
-        mFileNameSuffix = getString(R.string.config_export_file_suffix);
-        mFileNameExtension = getString(R.string.config_export_file_extension);
-
-        mExtensionsToConsider = new HashSet<String>();
-        mExtensionsToConsider.add(mFileNameExtension);
-
-        final String additionalExtensions =
-            getString(R.string.config_export_extensions_to_consider);
-        if (!TextUtils.isEmpty(additionalExtensions)) {
-            for (String extension : additionalExtensions.split(",")) {
-                String trimed = extension.trim();
-                if (trimed.length() > 0) {
-                    mExtensionsToConsider.add(trimed);
-                }
-            }
-        }
-
-        final Resources resources = getResources();
-        mFileIndexMinimum = resources.getInteger(R.integer.config_export_file_min_index);
-        mFileIndexMaximum = resources.getInteger(R.integer.config_export_file_max_index);
     }
 
     @Override
@@ -304,25 +260,6 @@
         stopServiceIfAppropriate();
     }
 
-    public synchronized void handleRequestAvailableExportDestination(final Messenger messenger) {
-        if (DEBUG) Log.d(LOG_TAG, "Received available export destination request.");
-        final String path = getAppropriateDestination(mTargetDirectory);
-        final Message message;
-        if (path != null) {
-            message = Message.obtain(null,
-                    VCardService.MSG_SET_AVAILABLE_EXPORT_DESTINATION, 0, 0, path);
-        } else {
-            message = Message.obtain(null,
-                    VCardService.MSG_SET_AVAILABLE_EXPORT_DESTINATION,
-                    R.id.dialog_fail_to_export_with_reason, 0, mErrorReason);
-        }
-        try {
-            messenger.send(message);
-        } catch (RemoteException e) {
-            Log.w(LOG_TAG, "Failed to send reply for available export destination request.", e);
-        }
-    }
-
     /**
      * Checks job list and call {@link #stopSelf()} when there's no job and no scanner connection
      * is remaining.
@@ -456,89 +393,4 @@
             }
         }
     }
-
-    /**
-     * Returns an appropriate file name for vCard export. Returns null when impossible.
-     *
-     * @return destination path for a vCard file to be exported. null on error and mErrorReason
-     * is correctly set.
-     */
-    private String getAppropriateDestination(final File destDirectory) {
-        /*
-         * Here, file names have 5 parts: directory, prefix, index, suffix, and extension.
-         * e.g. "/mnt/sdcard/prfx00001sfx.vcf" -> "/mnt/sdcard", "prfx", "00001", "sfx", and ".vcf"
-         *      (In default, prefix and suffix is empty, so usually the destination would be
-         *       /mnt/sdcard/00001.vcf.)
-         *
-         * This method increments "index" part from 1 to maximum, and checks whether any file name
-         * following naming rule is available. If there's no file named /mnt/sdcard/00001.vcf, the
-         * name will be returned to a caller. If there are 00001.vcf 00002.vcf, 00003.vcf is
-         * returned. We format these numbers in the US locale to ensure we they appear as
-         * english numerals.
-         *
-         * There may not be any appropriate file name. If there are 99999 vCard files in the
-         * storage, for example, there's no appropriate name, so this method returns
-         * null.
-         */
-
-        // Count the number of digits of mFileIndexMaximum
-        // e.g. When mFileIndexMaximum is 99999, fileIndexDigit becomes 5, as we will count the
-        int fileIndexDigit = 0;
-        {
-            // Calling Math.Log10() is costly.
-            int tmp;
-            for (fileIndexDigit = 0, tmp = mFileIndexMaximum; tmp > 0;
-                fileIndexDigit++, tmp /= 10) {
-            }
-        }
-
-        // %s05d%s (e.g. "p00001s")
-        final String bodyFormat = "%s%0" + fileIndexDigit + "d%s";
-
-        if (!ALLOW_LONG_FILE_NAME) {
-            final String possibleBody =
-                    String.format(Locale.US, bodyFormat, mFileNamePrefix, 1, mFileNameSuffix);
-            if (possibleBody.length() > 8 || mFileNameExtension.length() > 3) {
-                Log.e(LOG_TAG, "This code does not allow any long file name.");
-                mErrorReason = getString(R.string.fail_reason_too_long_filename,
-                        String.format("%s.%s", possibleBody, mFileNameExtension));
-                Log.w(LOG_TAG, "File name becomes too long.");
-                return null;
-            }
-        }
-
-        for (int i = mFileIndexMinimum; i <= mFileIndexMaximum; i++) {
-            boolean numberIsAvailable = true;
-            final String body
-                    = String.format(Locale.US, bodyFormat, mFileNamePrefix, i, mFileNameSuffix);
-            // Make sure that none of the extensions of mExtensionsToConsider matches. If this
-            // number is free, we'll go ahead with mFileNameExtension (which is included in
-            // mExtensionsToConsider)
-            for (String possibleExtension : mExtensionsToConsider) {
-                final File file = new File(destDirectory, body + "." + possibleExtension);
-                final String path = file.getAbsolutePath();
-                synchronized (this) {
-                    // Is this being exported right now? Skip this number
-                    if (mReservedDestination.contains(path)) {
-                        if (DEBUG) {
-                            Log.d(LOG_TAG, String.format("%s is already being exported.", path));
-                        }
-                        numberIsAvailable = false;
-                        break;
-                    }
-                }
-                if (file.exists()) {
-                    numberIsAvailable = false;
-                    break;
-                }
-            }
-            if (numberIsAvailable) {
-                return new File(destDirectory, body + "." + mFileNameExtension).getAbsolutePath();
-            }
-        }
-
-        Log.w(LOG_TAG, "Reached vCard number limit. Maybe there are too many vCard in the storage");
-        mErrorReason = getString(R.string.fail_reason_too_many_vcard);
-        return null;
-    }
 }
