diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 35cbcf3..f2468f5 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -289,10 +289,6 @@
     <!-- TODO: remove translatable=false attribute once text is stable -->
     <string name="research_send_usage_info" translatable="false">Send usage info</string>
 
-    <!-- Name for the research uploading service to be displayed to users.  [CHAR LIMIT=50] -->
-    <!-- TODO: remove translatable=false attribute once text is stable -->
-    <string name="research_log_uploader_name" translatable="false">Research Uploader Service</string>
-
     <!-- Preference for input language selection -->
     <string name="select_language">Input languages</string>
 
diff --git a/java/src/com/android/inputmethod/research/BootBroadcastReceiver.java b/java/src/com/android/inputmethod/research/BootBroadcastReceiver.java
deleted file mode 100644
index 5124a35..0000000
--- a/java/src/com/android/inputmethod/research/BootBroadcastReceiver.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.android.inputmethod.research;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-
-/**
- * Arrange for the uploading service to be run on regular intervals.
- */
-public final class BootBroadcastReceiver extends BroadcastReceiver {
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
-            ResearchLogger.scheduleUploadingService(context);
-        }
-    }
-}
diff --git a/java/src/com/android/inputmethod/research/ResearchLogUploader.java b/java/src/com/android/inputmethod/research/ResearchLogUploader.java
new file mode 100644
index 0000000..9904a1d
--- /dev/null
+++ b/java/src/com/android/inputmethod/research/ResearchLogUploader.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.research;
+
+import android.Manifest;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.BatteryManager;
+import android.util.Log;
+
+import com.android.inputmethod.latin.R;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+public final class ResearchLogUploader {
+    private static final String TAG = ResearchLogUploader.class.getSimpleName();
+    private static final int UPLOAD_INTERVAL_IN_MS = 1000 * 60 * 15; // every 15 min
+    private static final int BUF_SIZE = 1024 * 8;
+    protected static final int TIMEOUT_IN_MS = 1000 * 4;
+
+    private final boolean mCanUpload;
+    private final Context mContext;
+    private final File mFilesDir;
+    private final URL mUrl;
+    private final ScheduledExecutorService mExecutor;
+
+    public ResearchLogUploader(final Context context, final File filesDir) {
+        mContext = context;
+        mFilesDir = filesDir;
+        final PackageManager packageManager = context.getPackageManager();
+        final boolean hasPermission = packageManager.checkPermission(Manifest.permission.INTERNET,
+                context.getPackageName()) == PackageManager.PERMISSION_GRANTED;
+        if (!hasPermission) {
+            mCanUpload = false;
+            mUrl = null;
+            mExecutor = null;
+            return;
+        }
+        URL tempUrl = null;
+        boolean canUpload = false;
+        ScheduledExecutorService executor = null;
+        try {
+            final String urlString = context.getString(R.string.research_logger_upload_url);
+            if (urlString == null || urlString.equals("")) {
+                return;
+            }
+            tempUrl = new URL(urlString);
+            canUpload = true;
+            executor = Executors.newSingleThreadScheduledExecutor();
+        } catch (MalformedURLException e) {
+            tempUrl = null;
+            e.printStackTrace();
+            return;
+        } finally {
+            mCanUpload = canUpload;
+            mUrl = tempUrl;
+            mExecutor = executor;
+        }
+    }
+
+    public void start() {
+        if (mCanUpload) {
+            mExecutor.scheduleWithFixedDelay(new UploadRunnable(null /* logToWaitFor */,
+                    null /* callback */, false /* forceUpload */),
+                    UPLOAD_INTERVAL_IN_MS, UPLOAD_INTERVAL_IN_MS, TimeUnit.MILLISECONDS);
+        }
+    }
+
+    public void uploadAfterCompletion(final ResearchLog researchLog, final Callback callback) {
+        if (mCanUpload) {
+            mExecutor.submit(new UploadRunnable(researchLog, callback, true /* forceUpload */));
+        }
+    }
+
+    public void uploadNow(final Callback callback) {
+        // Perform an immediate upload.  Note that this should happen even if there is
+        // another upload happening right now, as it may have missed the latest changes.
+        // TODO: Reschedule regular upload tests starting from now.
+        if (mCanUpload) {
+            mExecutor.submit(new UploadRunnable(null /* logToWaitFor */, callback,
+                    true /* forceUpload */));
+        }
+    }
+
+    public interface Callback {
+        public void onUploadCompleted(final boolean success);
+    }
+
+    private boolean isExternallyPowered() {
+        final Intent intent = mContext.registerReceiver(null, new IntentFilter(
+                Intent.ACTION_BATTERY_CHANGED));
+        final int pluggedState = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
+        return pluggedState == BatteryManager.BATTERY_PLUGGED_AC
+                || pluggedState == BatteryManager.BATTERY_PLUGGED_USB;
+    }
+
+    private boolean hasWifiConnection() {
+        final ConnectivityManager manager =
+                (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+        final NetworkInfo wifiInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+        return wifiInfo.isConnected();
+    }
+
+    class UploadRunnable implements Runnable {
+        private final ResearchLog mLogToWaitFor;
+        private final Callback mCallback;
+        private final boolean mForceUpload;
+
+        public UploadRunnable(final ResearchLog logToWaitFor, final Callback callback,
+                final boolean forceUpload) {
+            mLogToWaitFor = logToWaitFor;
+            mCallback = callback;
+            mForceUpload = forceUpload;
+        }
+
+        @Override
+        public void run() {
+            if (mLogToWaitFor != null) {
+                waitFor(mLogToWaitFor);
+            }
+            doUpload();
+        }
+
+        private void waitFor(final ResearchLog researchLog) {
+            try {
+                researchLog.awaitTermination(TIMEOUT_IN_MS, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+
+        private void doUpload() {
+            if (!mForceUpload && (!isExternallyPowered() || !hasWifiConnection())) {
+                return;
+            }
+            if (mFilesDir == null) {
+                return;
+            }
+            final File[] files = mFilesDir.listFiles(new FileFilter() {
+                @Override
+                public boolean accept(File pathname) {
+                    return pathname.getName().startsWith(ResearchLogger.FILENAME_PREFIX)
+                            && !pathname.canWrite();
+                }
+            });
+            boolean success = true;
+            if (files.length == 0) {
+                success = false;
+            }
+            for (final File file : files) {
+                if (!uploadFile(file)) {
+                    success = false;
+                }
+            }
+            if (mCallback != null) {
+                mCallback.onUploadCompleted(success);
+            }
+        }
+
+        private boolean uploadFile(File file) {
+            Log.d(TAG, "attempting upload of " + file.getAbsolutePath());
+            boolean success = false;
+            final int contentLength = (int) file.length();
+            HttpURLConnection connection = null;
+            InputStream fileIs = null;
+            try {
+                fileIs = new FileInputStream(file);
+                connection = (HttpURLConnection) mUrl.openConnection();
+                connection.setRequestMethod("PUT");
+                connection.setDoOutput(true);
+                connection.setFixedLengthStreamingMode(contentLength);
+                final OutputStream os = connection.getOutputStream();
+                final byte[] buf = new byte[BUF_SIZE];
+                int numBytesRead;
+                while ((numBytesRead = fileIs.read(buf)) != -1) {
+                    os.write(buf, 0, numBytesRead);
+                }
+                if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
+                    Log.d(TAG, "upload failed: " + connection.getResponseCode());
+                    InputStream netIs = connection.getInputStream();
+                    BufferedReader reader = new BufferedReader(new InputStreamReader(netIs));
+                    String line;
+                    while ((line = reader.readLine()) != null) {
+                        Log.d(TAG, "| " + reader.readLine());
+                    }
+                    reader.close();
+                    return success;
+                }
+                file.delete();
+                success = true;
+                Log.d(TAG, "upload successful");
+            } catch (Exception e) {
+                e.printStackTrace();
+            } finally {
+                if (fileIs != null) {
+                    try {
+                        fileIs.close();
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                }
+                if (connection != null) {
+                    connection.disconnect();
+                }
+            }
+            return success;
+        }
+    }
+}
diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java
index 814a126..bd62ca3 100644
--- a/java/src/com/android/inputmethod/research/ResearchLogger.java
+++ b/java/src/com/android/inputmethod/research/ResearchLogger.java
@@ -18,14 +18,11 @@
 
 import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.KEYBOARD_LAYOUT_SET;
 
-import android.app.AlarmManager;
 import android.app.AlertDialog;
 import android.app.Dialog;
-import android.app.PendingIntent;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnCancelListener;
-import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
 import android.content.pm.PackageInfo;
@@ -136,9 +133,7 @@
     private KeyboardSwitcher mKeyboardSwitcher;
     private InputMethodService mInputMethodService;
     private final Statistics mStatistics;
-
-    private Intent mUploadIntent;
-    private PendingIntent mUploadPendingIntent;
+    private ResearchLogUploader mResearchLogUploader;
 
     private LogUnit mCurrentLogUnit = new LogUnit();
 
@@ -181,34 +176,11 @@
                 e.apply();
             }
         }
+        mResearchLogUploader = new ResearchLogUploader(ims, mFilesDir);
+        mResearchLogUploader.start();
         mKeyboardSwitcher = keyboardSwitcher;
         mInputMethodService = ims;
         mPrefs = prefs;
-        mUploadIntent = new Intent(mInputMethodService, UploaderService.class);
-        mUploadPendingIntent = PendingIntent.getService(mInputMethodService, 0, mUploadIntent, 0);
-
-        if (ProductionFlag.IS_EXPERIMENTAL) {
-            scheduleUploadingService(mInputMethodService);
-        }
-    }
-
-    /**
-     * Arrange for the UploaderService to be run on a regular basis.
-     *
-     * Any existing scheduled invocation of UploaderService is removed and rescheduled.  This may
-     * cause problems if this method is called often and frequent updates are required, but since
-     * the user will likely be sleeping at some point, if the interval is less that the expected
-     * sleep duration and this method is not called during that time, the service should be invoked
-     * at some point.
-     */
-    public static void scheduleUploadingService(Context context) {
-        final Intent intent = new Intent(context, UploaderService.class);
-        final PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
-        final AlarmManager manager =
-                (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
-        manager.cancel(pendingIntent);
-        manager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                UploaderService.RUN_INTERVAL, UploaderService.RUN_INTERVAL, pendingIntent);
     }
 
     private void cleanupLoggingDir(final File dir, final long time) {
@@ -285,7 +257,6 @@
         final Editor e = mPrefs.edit();
         e.putBoolean(PREF_RESEARCH_HAS_SEEN_SPLASH, true);
         e.apply();
-        restart();
     }
 
     private void setLoggingAllowed(boolean enableLogging) {
@@ -508,11 +479,10 @@
         if (mFeedbackLogBuffer == null) {
             return;
         }
-        if (includeHistory) {
-            commitCurrentLogUnit();
-        } else {
+        if (!includeHistory) {
             mFeedbackLogBuffer.clear();
         }
+        commitCurrentLogUnit();
         final LogUnit feedbackLogUnit = new LogUnit();
         final Object[] values = {
             feedbackContents
@@ -522,14 +492,10 @@
         mFeedbackLogBuffer.shiftIn(feedbackLogUnit);
         publishLogBuffer(mFeedbackLogBuffer, mFeedbackLog, true /* isIncludingPrivateData */);
         mFeedbackLog.close();
-        uploadNow();
+        mResearchLogUploader.uploadAfterCompletion(mFeedbackLog, null);
         mFeedbackLog = new ResearchLog(createLogFile(mFilesDir));
     }
 
-    public void uploadNow() {
-        mInputMethodService.startService(mUploadIntent);
-    }
-
     public void onLeavingSendFeedbackDialog() {
         mInFeedbackDialog = false;
     }
diff --git a/java/src/com/android/inputmethod/research/UploaderService.java b/java/src/com/android/inputmethod/research/UploaderService.java
deleted file mode 100644
index 7a57490..0000000
--- a/java/src/com/android/inputmethod/research/UploaderService.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.android.inputmethod.research;
-
-import android.Manifest;
-import android.app.AlarmManager;
-import android.app.IntentService;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.os.BatteryManager;
-import android.os.Bundle;
-import android.util.Log;
-
-import com.android.inputmethod.latin.R;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileFilter;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-public final class UploaderService extends IntentService {
-    private static final String TAG = UploaderService.class.getSimpleName();
-    public static final long RUN_INTERVAL = AlarmManager.INTERVAL_HOUR;
-    private static final String EXTRA_UPLOAD_UNCONDITIONALLY = UploaderService.class.getName()
-            + ".extra.UPLOAD_UNCONDITIONALLY";
-    private static final int BUF_SIZE = 1024 * 8;
-    protected static final int TIMEOUT_IN_MS = 1000 * 4;
-
-    private boolean mCanUpload;
-    private File mFilesDir;
-    private URL mUrl;
-
-    public UploaderService() {
-        super("Research Uploader Service");
-    }
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-
-        mCanUpload = false;
-        mFilesDir = null;
-        mUrl = null;
-
-        final PackageManager packageManager = getPackageManager();
-        final boolean hasPermission = packageManager.checkPermission(Manifest.permission.INTERNET,
-                getPackageName()) == PackageManager.PERMISSION_GRANTED;
-        if (!hasPermission) {
-            return;
-        }
-
-        try {
-            final String urlString = getString(R.string.research_logger_upload_url);
-            if (urlString == null || urlString.equals("")) {
-                return;
-            }
-            mFilesDir = getFilesDir();
-            mUrl = new URL(urlString);
-            mCanUpload = true;
-        } catch (MalformedURLException e) {
-            e.printStackTrace();
-        }
-    }
-
-    @Override
-    protected void onHandleIntent(Intent intent) {
-        if (!mCanUpload) {
-            return;
-        }
-        boolean isUploadingUnconditionally = false;
-        Bundle bundle = intent.getExtras();
-        if (bundle != null && bundle.containsKey(EXTRA_UPLOAD_UNCONDITIONALLY)) {
-            isUploadingUnconditionally = bundle.getBoolean(EXTRA_UPLOAD_UNCONDITIONALLY);
-        }
-        doUpload(isUploadingUnconditionally);
-    }
-
-    private boolean isExternallyPowered() {
-        final Intent intent = registerReceiver(null, new IntentFilter(
-                Intent.ACTION_BATTERY_CHANGED));
-        final int pluggedState = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
-        return pluggedState == BatteryManager.BATTERY_PLUGGED_AC
-                || pluggedState == BatteryManager.BATTERY_PLUGGED_USB;
-    }
-
-    private boolean hasWifiConnection() {
-        final ConnectivityManager manager =
-                (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
-        final NetworkInfo wifiInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
-        return wifiInfo.isConnected();
-    }
-
-    private void doUpload(final boolean isUploadingUnconditionally) {
-        if (!isUploadingUnconditionally && (!isExternallyPowered() || !hasWifiConnection())) {
-            return;
-        }
-        if (mFilesDir == null) {
-            return;
-        }
-        final File[] files = mFilesDir.listFiles(new FileFilter() {
-            @Override
-            public boolean accept(File pathname) {
-                return pathname.getName().startsWith(ResearchLogger.FILENAME_PREFIX)
-                        && !pathname.canWrite();
-            }
-        });
-        boolean success = true;
-        if (files.length == 0) {
-            success = false;
-        }
-        for (final File file : files) {
-            if (!uploadFile(file)) {
-                success = false;
-            }
-        }
-    }
-
-    private boolean uploadFile(File file) {
-        Log.d(TAG, "attempting upload of " + file.getAbsolutePath());
-        boolean success = false;
-        final int contentLength = (int) file.length();
-        HttpURLConnection connection = null;
-        InputStream fileInputStream = null;
-        try {
-            fileInputStream = new FileInputStream(file);
-            connection = (HttpURLConnection) mUrl.openConnection();
-            connection.setRequestMethod("PUT");
-            connection.setDoOutput(true);
-            connection.setFixedLengthStreamingMode(contentLength);
-            final OutputStream os = connection.getOutputStream();
-            final byte[] buf = new byte[BUF_SIZE];
-            int numBytesRead;
-            while ((numBytesRead = fileInputStream.read(buf)) != -1) {
-                os.write(buf, 0, numBytesRead);
-            }
-            if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
-                Log.d(TAG, "upload failed: " + connection.getResponseCode());
-                InputStream netInputStream = connection.getInputStream();
-                BufferedReader reader = new BufferedReader(new InputStreamReader(netInputStream));
-                String line;
-                while ((line = reader.readLine()) != null) {
-                    Log.d(TAG, "| " + reader.readLine());
-                }
-                reader.close();
-                return success;
-            }
-            file.delete();
-            success = true;
-            Log.d(TAG, "upload successful");
-        } catch (Exception e) {
-            e.printStackTrace();
-        } finally {
-            if (fileInputStream != null) {
-                try {
-                    fileInputStream.close();
-                } catch (IOException e) {
-                    e.printStackTrace();
-                }
-            }
-            if (connection != null) {
-                connection.disconnect();
-            }
-        }
-        return success;
-    }
-}
