Java Code Examples for android.os.SystemClock#elapsedRealtime()

The following examples show how to use android.os.SystemClock#elapsedRealtime() . These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source Project: VideoCRE   File: ThreadUtils.java    License: MIT License 6 votes vote down vote up
public static boolean joinUninterruptibly(final Thread thread, long timeoutMs) {
  final long startTimeMs = SystemClock.elapsedRealtime();
  long timeRemainingMs = timeoutMs;
  boolean wasInterrupted = false;
  while (timeRemainingMs > 0) {
    try {
      thread.join(timeRemainingMs);
      break;
    } catch (InterruptedException e) {
      // Someone is asking us to return early at our convenience. We can't cancel this operation,
      // but we should preserve the information and pass it along.
      wasInterrupted = true;
      final long elapsedTimeMs = SystemClock.elapsedRealtime() - startTimeMs;
      timeRemainingMs = timeoutMs - elapsedTimeMs;
    }
  }
  // Pass interruption information along.
  if (wasInterrupted) {
    Thread.currentThread().interrupt();
  }
  return !thread.isAlive();
}
 
Example 2
void onProgress(long increaseBytes) {
    callbackIncreaseBuffer.addAndGet(increaseBytes);
    model.increaseSoFar(increaseBytes);

    final long now = SystemClock.elapsedRealtime();

    inspectNeedCallbackToUser(now);

    if (handler == null) {
        // direct
        handleProgress();
    } else if (needCallbackProgressToUser.get()) {
        // flow
        sendMessage(handler.obtainMessage(FileDownloadStatus.progress));
    }
}
 
Example 3
/**
 * Sets the frame data received from the camera.  This adds the previous unused frame buffer
 * (if present) back to the camera, and keeps a pending reference to the frame data for
 * future use.
 */
void setNextFrame(byte[] data, Camera camera) {
    synchronized (mLock) {
        if (mPendingFrameData != null) {
            camera.addCallbackBuffer(mPendingFrameData.array());
            mPendingFrameData = null;
        }

        if (!mBytesToByteBuffer.containsKey(data)) {
            Log.d(TAG,
                "Skipping frame.  Could not find ByteBuffer associated with the image " +
                "data from the camera.");
            return;
        }

        // Timestamp and frame ID are maintained here, which will give downstream code some
        // idea of the timing of frames received and when frames were dropped along the way.
        mPendingTimeMillis = SystemClock.elapsedRealtime() - mStartTimeMillis;
        mPendingFrameId++;
        mPendingFrameData = mBytesToByteBuffer.get(data);

        // Notify the processor thread if it is waiting on the next frame (see below).
        mLock.notifyAll();
    }
}
 
Example 4
Source Project: Android-Next   File: TaskImpl.java    License: Apache License 2.0 6 votes vote down vote up
@Override
public void onStarted() {
    if (Config.DEBUG) {
        Log.v(TAG, "onStarted() " + getName() + " cancelled=" + isCancelled());
        dumpCaller();
    }
    mStatus = TaskFuture.RUNNING;
    mStartTime = SystemClock.elapsedRealtime();
    if (isCancelled()) {
        return;
    }
    if (isCallerDead()) {
        if (Config.DEBUG) {
            Log.v(TAG, "onStarted() " + getName() + " caller dead, cancel task");
        }
        cancel();
        return;
    }
    final Runnable runnable = new Runnable() {
        @Override
        public void run() {
            mCb.onTaskStarted(getName(), mInfo.action.getExtras());
        }
    };
    mInfo.handler.post(runnable);
}
 
Example 5
Source Project: flutter_mobile_vision   File: CameraSource.java    License: MIT License 6 votes vote down vote up
/**
 * Sets the frame data received from the camera.  This adds the previous unused frame buffer
 * (if present) back to the camera, and keeps a pending reference to the frame data for
 * future use.
 */
private void setNextFrame(byte[] data, Camera camera) {
    synchronized (mLock) {
        if (mPendingFrameData != null) {
            camera.addCallbackBuffer(mPendingFrameData.array());
            mPendingFrameData = null;
        }

        if (!bytesToByteBuffer.containsKey(data)) {
            Log.d(TAG,
                    "Skipping frame.  Could not find ByteBuffer associated with the image " +
                            "data from the camera.");
            return;
        }

        // Timestamp and frame ID are maintained here, which will give downstream code some
        // idea of the timing of frames received and when frames were dropped along the way.
        mPendingTimeMillis = SystemClock.elapsedRealtime() - mStartTimeMillis;
        mPendingFrameId++;
        mPendingFrameData = bytesToByteBuffer.get(data);

        // Notify the processor thread if it is waiting on the next frame (see below).
        mLock.notifyAll();
    }
}
 
Example 6
Source Project: weakHandler   File: WeakHandlerTest.java    License: MIT License 6 votes vote down vote up
@Test
public void removeCallbacks() throws InterruptedException {
    final CountDownLatch latch = new CountDownLatch(1);

    long startTime = SystemClock.elapsedRealtime();
    final AtomicBoolean executed = new AtomicBoolean(false);
    Runnable r = new Runnable() {
        @Override
        public void run() {
            executed.set(true);
            latch.countDown();
        }
    };
    mHandler.postDelayed(r, 300);
    mHandler.removeCallbacks(r);
    latch.await(1, TimeUnit.SECONDS);
    assertFalse(executed.get());

    long elapsedTime = SystemClock.elapsedRealtime() - startTime;
    assertTrue(elapsedTime > 300);
}
 
Example 7
Source Project: media-samples   File: MainActivity.java    License: Apache License 2.0 5 votes vote down vote up
@Override
public void onRouteUnselected(MediaRouter router, RouteInfo route) {
    Log.d(TAG, "onRouteUnselected: route=" + route);
    unregisterRemoteControlClient();

    PlaylistItem item = getCheckedPlaylistItem();
    if (item != null) {
        long pos = item.getPosition() +
                (mPaused ? 0 : (SystemClock.elapsedRealtime() - item.getTimestamp()));
        mSessionManager.suspend(pos);
    }
    mPlayer.updatePresentation();
    mPlayer.release();
}
 
Example 8
public static void increaseBadPasscodeTries()
{
    SharedConfig.badPasscodeTries++;
    if (badPasscodeTries >= 3)
    {
        switch (SharedConfig.badPasscodeTries)
        {
            case 3:
                passcodeRetryInMs = 5000;
                break;
            case 4:
                passcodeRetryInMs = 10000;
                break;
            case 5:
                passcodeRetryInMs = 15000;
                break;
            case 6:
                passcodeRetryInMs = 20000;
                break;
            case 7:
                passcodeRetryInMs = 25000;
                break;
            default:
                passcodeRetryInMs = 30000;
                break;
        }
        SharedConfig.lastUptimeMillis = SystemClock.elapsedRealtime();
    }
    saveConfig();
}
 
Example 9
Source Project: BaseProject   File: Progress.java    License: Apache License 2.0 5 votes vote down vote up
public Progress() {
        lastRefreshTime = SystemClock.elapsedRealtime();
        totalSize = -1;
        priority = Priority.DEFAULT;
        date = System.currentTimeMillis();
//        speedBuffer = new ArrayList<>();
        speedBuffer = new CopyOnWriteArrayList<>();
    }
 
Example 10
public void loadPlaylist() {
  blacklistUntilMs = 0;
  if (loadPending || mediaPlaylistLoader.isLoading() || mediaPlaylistLoader.hasFatalError()) {
    // Load already pending, in progress, or a fatal error has been encountered. Do nothing.
    return;
  }
  long currentTimeMs = SystemClock.elapsedRealtime();
  if (currentTimeMs < earliestNextLoadTimeMs) {
    loadPending = true;
    playlistRefreshHandler.postDelayed(this, earliestNextLoadTimeMs - currentTimeMs);
  } else {
    loadPlaylistImmediately();
  }
}
 
Example 11
Source Project: talkback   File: UiChangeStabilizer.java    License: Apache License 2.0 5 votes vote down vote up
private boolean safeToDelayCallToUiChangedListener() {
  long currentTime = SystemClock.elapsedRealtime();
  long timeSinceLastCallToUiChangeListener = currentTime - lastCallToUiChangedListenerTimeMs;

  // Less than 3 calls to possibleChangeToUi &
  return (timeSinceLastCallToUiChangeListener
          < MAX_WAIT_TIME_FOR_MULTIPLE_UI_CHANGES_BEFORE_FORCED_REFRESH_MS)
      || (numUiChangesSinceLastCallToUiChangedListener
          < UI_CHANGES_PER_SECOND_BEFORE_FORCED_REFRESH);
}
 
Example 12
Source Project: K-Sonic   File: SimpleDecoderAudioRenderer.java    License: MIT License 5 votes vote down vote up
private void maybeInitDecoder() throws ExoPlaybackException {
  if (decoder != null) {
    return;
  }

  drmSession = pendingDrmSession;
  ExoMediaCrypto mediaCrypto = null;
  if (drmSession != null) {
    @DrmSession.State int drmSessionState = drmSession.getState();
    if (drmSessionState == DrmSession.STATE_ERROR) {
      throw ExoPlaybackException.createForRenderer(drmSession.getError(), getIndex());
    } else if (drmSessionState == DrmSession.STATE_OPENED
        || drmSessionState == DrmSession.STATE_OPENED_WITH_KEYS) {
      mediaCrypto = drmSession.getMediaCrypto();
    } else {
      // The drm session isn't open yet.
      return;
    }
  }

  try {
    long codecInitializingTimestamp = SystemClock.elapsedRealtime();
    TraceUtil.beginSection("createAudioDecoder");
    decoder = createDecoder(inputFormat, mediaCrypto);
    TraceUtil.endSection();
    long codecInitializedTimestamp = SystemClock.elapsedRealtime();
    eventDispatcher.decoderInitialized(decoder.getName(), codecInitializedTimestamp,
        codecInitializedTimestamp - codecInitializingTimestamp);
    decoderCounters.decoderInitCount++;
  } catch (AudioDecoderException e) {
    throw ExoPlaybackException.createForRenderer(e, getIndex());
  }
}
 
Example 13
protected final void start(Intent intent) {
    if (mDelay == 0L) {
        mContext.startService(intent);
    } else {
        Object service = mContext.getSystemService(Context.ALARM_SERVICE);
        AlarmManager manager = (AlarmManager) service;
        long triggerAtTime = SystemClock.elapsedRealtime() + mDelay;
        int requestCode = (int) triggerAtTime;
        int flags = 0;
        PendingIntent op = PendingIntent.getService(mContext, requestCode, intent, flags);
        manager.set(AlarmManager.ELAPSED_REALTIME, triggerAtTime, op);
    }
}
 
Example 14
@Override
public void onCreate() {
    super.onCreate();

    Log.i(TAG, "onCreate Called");

    startupRealtime = SystemClock.elapsedRealtime();

    CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
            .setDefaultFontPath("fonts/OpenSans-Regular.ttf")
            .setFontAttrId(R.attr.fontPath)
            .build()
    );

    if (!BuildConfig.DEBUG) {
        try {
            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());

            if (prefs.getBoolean(getString(R.string.key_dbgCrashlytics), getResources().getBoolean(R.bool.default_dbgCrashlytics))) {
                Fabric.with(this, new Crashlytics());
            }
            if (prefs.getBoolean(getString(R.string.key_dbgAnswers), getResources().getBoolean(R.bool.default_dbgAnswers))) {
                Fabric.with(this, new Answers(), new Crashlytics());
            }

            if (prefs.getBoolean(getString(R.string.key_dbgRemoteLogcat), getResources().getBoolean(R.bool.default_dbgRemoteLogcat))) {
                Bugfender.init(this, BuildConfig.BUGFENDER_API_KEY, BuildConfig.DEBUG);
                Bugfender.enableLogcatLogging();
                Bugfender.setDeviceString("NightscoutURL", prefs.getString(getString(R.string.key_nightscoutURL), "Not set"));
            }
        } catch (Exception ignored) {
        }
    }

    Realm.init(this);

    RealmConfiguration realmConfiguration = new RealmConfiguration.Builder()
            .modules(new MainModule())
            .deleteRealmIfMigrationNeeded()
            .build();
    Realm.setDefaultConfiguration(realmConfiguration);

    storeConfiguration = new RealmConfiguration.Builder()
            .name("store.realm")
            .modules(new StoreModule())
            .deleteRealmIfMigrationNeeded()
            .build();

    userLogConfiguration = new RealmConfiguration.Builder()
            .name("userlog.realm")
            .modules(new UserLogModule())
            .deleteRealmIfMigrationNeeded()
            .build();

    historyConfiguration = new RealmConfiguration.Builder()
            .name("history.realm")
            .modules(new HistoryModule())
            .deleteRealmIfMigrationNeeded()
            .build();

    // Uploader specific string formatting and localisation formatting accessible from any module
    FormatKit.init(this);

    // Some Android versions will leak if ConnectivityManager not attached to app context here
    connectivityManager = (ConnectivityManager) getApplicationContext()
            .getSystemService(CONNECTIVITY_SERVICE);
}
 
Example 15
private void handleReportLocation(boolean hasLatLong, Location location) {
    if (location.hasSpeed()) {
        mItarSpeedLimitExceeded = location.getSpeed() > ITAR_SPEED_LIMIT_METERS_PER_SECOND;
    }

    if (mItarSpeedLimitExceeded) {
        Log.i(TAG, "Hal reported a speed in excess of ITAR limit." +
                "  GPS/GNSS Navigation output blocked.");
        if (mStarted) {
            mGnssMetrics.logReceivedLocationStatus(false);
        }
        return;  // No output of location allowed
    }

    if (VERBOSE) Log.v(TAG, "reportLocation " + location.toString());

    // It would be nice to push the elapsed real-time timestamp
    // further down the stack, but this is still useful
    location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
    location.setExtras(mLocationExtras.getBundle());

    try {
        mILocationManager.reportLocation(location, false);
    } catch (RemoteException e) {
        Log.e(TAG, "RemoteException calling reportLocation");
    }

    if (mStarted) {
        mGnssMetrics.logReceivedLocationStatus(hasLatLong);
        if (hasLatLong) {
            if (location.hasAccuracy()) {
                mGnssMetrics.logPositionAccuracyMeters(location.getAccuracy());
            }
            if (mTimeToFirstFix > 0) {
                int timeBetweenFixes = (int) (SystemClock.elapsedRealtime() - mLastFixTime);
                mGnssMetrics.logMissedReports(mFixInterval, timeBetweenFixes);
            }
        }
    }

    mLastFixTime = SystemClock.elapsedRealtime();
    // report time to first fix
    if (mTimeToFirstFix == 0 && hasLatLong) {
        mTimeToFirstFix = (int) (mLastFixTime - mFixRequestTime);
        if (DEBUG) Log.d(TAG, "TTFF: " + mTimeToFirstFix);
        if (mStarted) {
            mGnssMetrics.logTimeToFirstFixMilliSecs(mTimeToFirstFix);
        }

        // notify status listeners
        mListenerHelper.onFirstFix(mTimeToFirstFix);
    }

    if (mSingleShot) {
        stopNavigating();
    }

    if (mStarted && mStatus != LocationProvider.AVAILABLE) {
        // For devices that use framework scheduling, a timer may be set to ensure we don't
        // spend too much power searching for a location, when the requested update rate is slow.
        // As we just recievied a location, we'll cancel that timer.
        if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mFixInterval < NO_FIX_TIMEOUT) {
            mAlarmManager.cancel(mTimeoutIntent);
        }

        // send an intent to notify that the GPS is receiving fixes.
        Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
        intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, true);
        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
        updateStatus(LocationProvider.AVAILABLE);
    }

    if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted &&
            mFixInterval > GPS_POLLING_THRESHOLD_INTERVAL) {
        if (DEBUG) Log.d(TAG, "got fix, hibernating");
        hibernate();
    }
}
 
Example 16
public static void init(@NonNull Context aContext, @NonNull Client client) {
    // When initializing the telemetry library it will make sure that all directories exist and
    // are readable/writable.
    final StrictMode.ThreadPolicy threadPolicy = StrictMode.allowThreadDiskWrites();
    try {
        final Resources resources = aContext.getResources();
        final boolean telemetryEnabled = SettingsStore.getInstance(aContext).isTelemetryEnabled();
        final TelemetryConfiguration configuration = new TelemetryConfiguration(aContext)
                .setServerEndpoint("https://incoming.telemetry.mozilla.org")
                .setAppName(APP_NAME + "_" + DeviceType.getDeviceTypeId())
                .setUpdateChannel(BuildConfig.BUILD_TYPE)
                .setPreferencesImportantForTelemetry(resources.getString(R.string.settings_key_locale))
                .setCollectionEnabled(telemetryEnabled)
                .setUploadEnabled(telemetryEnabled)
                // We need to set this to 1 as we want the telemetry opt-in/out ping always to be sent and the minimum is 3 by default.
                .setMinimumEventsForUpload(1)
                .setBuildId(String.valueOf(BuildConfig.VERSION_CODE));

        final JSONPingSerializer serializer = new JSONPingSerializer();
        final FileTelemetryStorage storage = new FileTelemetryStorage(configuration, serializer);
        TelemetryScheduler scheduler;
        if (DeviceType.isOculus6DOFBuild()) {
            scheduler = new FxRTelemetryScheduler();
        } else {
            scheduler = new JobSchedulerTelemetryScheduler();
        }

        TelemetryHolder.set(new Telemetry(configuration, storage, new TelemetryClient(client), scheduler)
                .addPingBuilder(new TelemetryCorePingBuilder(configuration))
                .addPingBuilder(new TelemetryMobileEventPingBuilder(configuration)));

        // Check if the Telemetry status has ever been saved (enabled/disabled)
        boolean saved = SettingsStore.getInstance(aContext).telemetryStatusSaved();
        // Check if we have already sent the previous status event
        boolean sent = SettingsStore.getInstance(aContext).isTelemetryPingUpdateSent();
        // If the Telemetry status has been changed but that ping has not been sent, we send it now
        // This should only been true for versions of the app prior to implementing the Telemetry status ping
        // We only send the status ping if it was disabled
        if (saved && !sent && !telemetryEnabled) {
            telemetryStatus(false);
            SettingsStore.getInstance(aContext).setTelemetryPingUpdateSent(true);
        }

    } finally {
        StrictMode.setThreadPolicy(threadPolicy);
    }

    sessionStartTime = SystemClock.elapsedRealtime();
}
 
Example 17
Source Project: letv   File: OpenConfig.java    License: Apache License 2.0 4 votes vote down vote up
private void a(JSONObject jSONObject) {
    b("cgi back, do update");
    this.e = jSONObject;
    a("com.tencent.open.config.json", jSONObject.toString());
    this.f = SystemClock.elapsedRealtime();
}
 
Example 18
public void draw(Canvas canvas) {
    final float radius = AndroidUtilities.lerp(thumbWidth / 2f, smallLineHeight / 2f, transitionProgress);
    rect.left = horizontalPadding + AndroidUtilities.lerp(thumbWidth / 2f, 0, transitionProgress);
    rect.top = AndroidUtilities.lerp((height - lineHeight) / 2f, height - AndroidUtilities.dp(3) - smallLineHeight, transitionProgress);
    rect.bottom = AndroidUtilities.lerp((height + lineHeight) / 2f, height - AndroidUtilities.dp(3), transitionProgress);

    // background
    rect.right = horizontalPadding + AndroidUtilities.lerp(width - thumbWidth / 2f, parentView.getWidth() - horizontalPadding * 2f, transitionProgress);
    setPaintColor(selected ? backgroundSelectedColor : backgroundColor, 1f - transitionProgress);
    canvas.drawRoundRect(rect, radius, radius, paint);

    // buffered
    if (bufferedProgress > 0) {
        rect.right = horizontalPadding + AndroidUtilities.lerp(thumbWidth / 2f + bufferedProgress * (width - thumbWidth), parentView.getWidth() - horizontalPadding * 2f, transitionProgress);
        setPaintColor(selected ? backgroundSelectedColor : cacheColor, 1f - transitionProgress);
        canvas.drawRoundRect(rect, radius, radius, paint);
    }

    // progress
    rect.right = horizontalPadding + AndroidUtilities.lerp(thumbWidth / 2f + (pressed ? draggingThumbX : thumbX), (parentView.getWidth() - horizontalPadding * 2f) * getProgress(), transitionProgress);
    if (transitionProgress > 0f && rect.width() > 0) {
        // progress stroke
        strokePaint.setAlpha((int) (transitionProgress * 255 * 0.2f));
        canvas.drawRoundRect(rect, radius, radius, strokePaint);
    }
    setPaintColor(ColorUtils.blendARGB(progressColor, smallLineColor, transitionProgress), 1f);
    canvas.drawRoundRect(rect, radius, radius, paint);

    // circle
    setPaintColor(ColorUtils.blendARGB(circleColor, getProgress() == 0 ? Color.TRANSPARENT : smallLineColor, transitionProgress), 1f - transitionProgress);
    int newRad = AndroidUtilities.dp(pressed ? 8 : 6);
    if (currentRadius != newRad) {
        long newUpdateTime = SystemClock.elapsedRealtime();
        long dt = newUpdateTime - lastUpdateTime;
        lastUpdateTime = newUpdateTime;
        if (dt > 18) {
            dt = 16;
        }
        if (currentRadius < newRad) {
            currentRadius += AndroidUtilities.dp(1) * (dt / 60.0f);
            if (currentRadius > newRad) {
                currentRadius = newRad;
            }
        } else {
            currentRadius -= AndroidUtilities.dp(1) * (dt / 60.0f);
            if (currentRadius < newRad) {
                currentRadius = newRad;
            }
        }
        if (parentView != null) {
            parentView.invalidate();
        }
    }
    final float circleRadius = AndroidUtilities.lerp(currentRadius, 0, transitionProgress);
    canvas.drawCircle(rect.right, rect.centerY(), circleRadius, paint);
}
 
Example 19
@Override
public void draw(Canvas canvas) {
    if (currentAnimationProgress == 1.0f) {
        canvas.drawRect(getBounds(), paint);
    } else if (currentAnimationProgress != 0.0f) {
        float interpolatedProgress;
        if (isSelected) {
            interpolatedProgress = CubicBezierInterpolator.EASE_OUT_QUINT.getInterpolation(currentAnimationProgress);
        } else {
            interpolatedProgress = 1.0f - CubicBezierInterpolator.EASE_OUT_QUINT.getInterpolation(1.0f - currentAnimationProgress);
        }
        Rect bounds = getBounds();
        float centerX = bounds.centerX();
        float centerY = bounds.centerY();
        float x1;
        float y1;
        if (touchOverrideX >= 0 && touchOverrideY >= 0) {
            x1 = touchOverrideX;
            y1 = touchOverrideY;
        } else if (touchX >= 0 && touchY >= 0) {
            x1 = touchX;
            y1 = touchY;
        } else {
            x1 = centerX;
            y1 = centerY;
        }
        x1 = centerX + (1.0f - interpolatedProgress) * (x1 - centerX);
        y1 = centerY + (1.0f - interpolatedProgress) * (y1 - centerY);
        canvas.drawCircle(x1, y1, finalRadius * interpolatedProgress, paint);
    }
    if (animationInProgress) {
        long newTime = SystemClock.elapsedRealtime();
        long dt = newTime - lastAnimationTime;
        if (dt > 20) {
            dt = 17;
        }
        lastAnimationTime = newTime;

        boolean finished = false;
        if (isSelected) {
            currentAnimationProgress += dt / 240.0f;
            if (currentAnimationProgress >= 1.0f) {
                currentAnimationProgress = 1.0f;
                finished = true;
            }
        } else {
            currentAnimationProgress -= dt / 240.0f;
            if (currentAnimationProgress <= 0.0f) {
                currentAnimationProgress = 0.0f;
                finished = true;
            }
        }
        if (finished) {
            touchX = -1;
            touchY = -1;
            touchOverrideX = -1;
            touchOverrideY = -1;
            animationInProgress = false;
        }
        invalidate();
    }
}
 
Example 20
/**
 * Sets the task to run. The task will run after the delay or once {@link #resume()} is
 * called, whichever occurs last. The previously scheduled task, if any, is cancelled.
 * @param r Task to run.
 * @param delayMs Delay in milliseconds after which to run the task.
 */
public void setRunnable(Runnable r, long delayMs) {
    cancel();
    mRunnable = r;
    mScheduledTime = SystemClock.elapsedRealtime() + delayMs;
}