diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index f2468f5..35cbcf3 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -289,6 +289,10 @@
     <!-- 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
new file mode 100644
index 0000000..5124a35
--- /dev/null
+++ b/java/src/com/android/inputmethod/research/BootBroadcastReceiver.java
@@ -0,0 +1,33 @@
+/*
+ * 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
deleted file mode 100644
index 9904a1d..0000000
--- a/java/src/com/android/inputmethod/research/ResearchLogUploader.java
+++ /dev/null
@@ -1,240 +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.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 129a04d..918fcf5 100644
--- a/java/src/com/android/inputmethod/research/ResearchLogger.java
+++ b/java/src/com/android/inputmethod/research/ResearchLogger.java
@@ -18,11 +18,14 @@
 
 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;
@@ -139,7 +142,9 @@
     private MainKeyboardView mMainKeyboardView;
     private InputMethodService mInputMethodService;
     private final Statistics mStatistics;
-    private ResearchLogUploader mResearchLogUploader;
+
+    private Intent mUploadIntent;
+    private PendingIntent mUploadPendingIntent;
 
     private LogUnit mCurrentLogUnit = new LogUnit();
 
@@ -181,10 +186,33 @@
                 e.apply();
             }
         }
-        mResearchLogUploader = new ResearchLogUploader(ims, mFilesDir);
-        mResearchLogUploader.start();
         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) {
@@ -267,6 +295,7 @@
         final Editor e = mPrefs.edit();
         e.putBoolean(PREF_RESEARCH_HAS_SEEN_SPLASH, true);
         e.apply();
+        restart();
     }
 
     private void setLoggingAllowed(boolean enableLogging) {
@@ -489,10 +518,11 @@
         if (mFeedbackLogBuffer == null) {
             return;
         }
-        if (!includeHistory) {
+        if (includeHistory) {
+            commitCurrentLogUnit();
+        } else {
             mFeedbackLogBuffer.clear();
         }
-        commitCurrentLogUnit();
         final LogUnit feedbackLogUnit = new LogUnit();
         final Object[] values = {
             feedbackContents
@@ -502,10 +532,14 @@
         mFeedbackLogBuffer.shiftIn(feedbackLogUnit);
         publishLogBuffer(mFeedbackLogBuffer, mFeedbackLog, true /* isIncludingPrivateData */);
         mFeedbackLog.close();
-        mResearchLogUploader.uploadAfterCompletion(mFeedbackLog, null);
+        uploadNow();
         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
new file mode 100644
index 0000000..7a57490
--- /dev/null
+++ b/java/src/com/android/inputmethod/research/UploaderService.java
@@ -0,0 +1,191 @@
+/*
+ * 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;
+    }
+}
