Back to project page android-class.
The source code is released under:
MIT License
If you think the Android project android-class listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.android.deskclock.stopwatch; /*ww w .ja v a 2 s . com*/ import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.IBinder; import android.preference.PreferenceManager; import android.view.View; import android.widget.RemoteViews; import com.android.deskclock.CircleTimerView; import com.android.deskclock.DeskClock; import com.android.deskclock.R; import com.android.deskclock.Utils; /** * TODO: Insert description here. (generated by sblitz) */ public class StopwatchService extends Service { // Member fields private int mNumLaps; private long mElapsedTime; private long mStartTime; private boolean mLoadApp; private NotificationManager mNotificationManager; // Constants for intent information // Make this a large number to avoid the alarm ID's which seem to be 1, 2, ... // Must also be different than TimerReceiver.IN_USE_NOTIFICATION_ID private static final int NOTIFICATION_ID = Integer.MAX_VALUE - 1; @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { mNumLaps = 0; mElapsedTime = 0; mStartTime = 0; mLoadApp = false; mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); } @Override public int onStartCommand(Intent intent, int flags, int startId) { if (intent == null) { return Service.START_NOT_STICKY; } if (mStartTime == 0 || mElapsedTime == 0 || mNumLaps == 0) { // May not have the most recent values. readFromSharedPrefs(); } String actionType = intent.getAction(); long actionTime = intent.getLongExtra(Stopwatches.MESSAGE_TIME, Utils.getTimeNow()); boolean showNotif = intent.getBooleanExtra(Stopwatches.SHOW_NOTIF, true); boolean updateCircle = showNotif; // Don't save updates to the cirle if we're in the app. if (actionType.equals(Stopwatches.START_STOPWATCH)) { mStartTime = actionTime; writeSharedPrefsStarted(mStartTime, updateCircle); if (showNotif) { setNotification(mStartTime - mElapsedTime, true, mNumLaps); } else { saveNotification(mStartTime - mElapsedTime, true, mNumLaps); } } else if (actionType.equals(Stopwatches.LAP_STOPWATCH)) { mNumLaps++; long lapTimeElapsed = actionTime - mStartTime + mElapsedTime; writeSharedPrefsLap(lapTimeElapsed, updateCircle); if (showNotif) { setNotification(mStartTime - mElapsedTime, true, mNumLaps); } else { saveNotification(mStartTime - mElapsedTime, true, mNumLaps); } } else if (actionType.equals(Stopwatches.STOP_STOPWATCH)) { mElapsedTime = mElapsedTime + (actionTime - mStartTime); writeSharedPrefsStopped(mElapsedTime, updateCircle); if (showNotif) { setNotification(actionTime - mElapsedTime, false, mNumLaps); } else { saveNotification(mElapsedTime, false, mNumLaps); } } else if (actionType.equals(Stopwatches.RESET_STOPWATCH)) { mLoadApp = false; writeSharedPrefsReset(updateCircle); clearSavedNotification(); stopSelf(); } else if (actionType.equals(Stopwatches.RESET_AND_LAUNCH_STOPWATCH)) { mLoadApp = true; writeSharedPrefsReset(updateCircle); clearSavedNotification(); closeNotificationShade(); stopSelf(); } else if (actionType.equals(Stopwatches.SHARE_STOPWATCH)) { closeNotificationShade(); Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND); shareIntent.setType("text/plain"); shareIntent.putExtra( Intent.EXTRA_SUBJECT, Stopwatches.getShareTitle(getApplicationContext())); shareIntent.putExtra(Intent.EXTRA_TEXT, Stopwatches.buildShareResults( getApplicationContext(), mElapsedTime, readLapsFromPrefs())); Intent chooserIntent = Intent.createChooser(shareIntent, null); chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); getApplication().startActivity(chooserIntent); } else if (actionType.equals(Stopwatches.SHOW_NOTIF)) { // SHOW_NOTIF sent from the DeskClock.onPause // If a notification is not displayed, this service's work is over if (!showSavedNotification()) { stopSelf(); } } else if (actionType.equals(Stopwatches.KILL_NOTIF)) { mNotificationManager.cancel(NOTIFICATION_ID); } // We want this service to continue running until it is explicitly // stopped, so return sticky. return START_STICKY; } @Override public void onDestroy() { mNotificationManager.cancel(NOTIFICATION_ID); clearSavedNotification(); mNumLaps = 0; mElapsedTime = 0; mStartTime = 0; if (mLoadApp) { Intent activityIntent = new Intent(getApplicationContext(), DeskClock.class); activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); activityIntent.putExtra( DeskClock.SELECT_TAB_INTENT_EXTRA, DeskClock.STOPWATCH_TAB_INDEX); startActivity(activityIntent); mLoadApp = false; } } private void setNotification(long clockBaseTime, boolean clockRunning, int numLaps) { Context context = getApplicationContext(); // Intent to load the app for a non-button click. Intent intent = new Intent(context, DeskClock.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra(DeskClock.SELECT_TAB_INTENT_EXTRA, DeskClock.STOPWATCH_TAB_INDEX); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT); // Set up remoteviews for the notification. RemoteViews remoteViewsCollapsed = new RemoteViews(getPackageName(), R.layout.stopwatch_notif_collapsed); remoteViewsCollapsed.setOnClickPendingIntent(R.id.swn_collapsed_hitspace, pendingIntent); remoteViewsCollapsed.setChronometer( R.id.swn_collapsed_chronometer, clockBaseTime, null, clockRunning); remoteViewsCollapsed.setImageViewResource(R.id.notification_icon, R.drawable.stat_notify_stopwatch); RemoteViews remoteViewsExpanded = new RemoteViews(getPackageName(), R.layout.stopwatch_notif_expanded); remoteViewsExpanded.setOnClickPendingIntent(R.id.swn_expanded_hitspace, pendingIntent); remoteViewsExpanded.setChronometer( R.id.swn_expanded_chronometer, clockBaseTime, null, clockRunning); remoteViewsExpanded.setImageViewResource(R.id.notification_icon, R.drawable.stat_notify_stopwatch); if (clockRunning) { // Left button: lap remoteViewsExpanded.setTextViewText( R.id.swn_left_button, getResources().getText(R.string.sw_lap_button)); Intent leftButtonIntent = new Intent(context, StopwatchService.class); leftButtonIntent.setAction(Stopwatches.LAP_STOPWATCH); remoteViewsExpanded.setOnClickPendingIntent(R.id.swn_left_button, PendingIntent.getService(context, 0, leftButtonIntent, 0)); remoteViewsExpanded.setTextViewCompoundDrawables(R.id.swn_left_button, R.drawable.ic_notify_lap, 0, 0, 0); // Right button: stop clock remoteViewsExpanded.setTextViewText( R.id.swn_right_button, getResources().getText(R.string.sw_stop_button)); Intent rightButtonIntent = new Intent(context, StopwatchService.class); rightButtonIntent.setAction(Stopwatches.STOP_STOPWATCH); remoteViewsExpanded.setOnClickPendingIntent(R.id.swn_right_button, PendingIntent.getService(context, 0, rightButtonIntent, 0)); remoteViewsExpanded.setTextViewCompoundDrawables(R.id.swn_right_button, R.drawable.ic_notify_stop, 0, 0, 0); // Show the laps if applicable. if (numLaps > 0) { String lapText = String.format( context.getString(R.string.sw_notification_lap_number), numLaps); remoteViewsCollapsed.setTextViewText(R.id.swn_collapsed_laps, lapText); remoteViewsCollapsed.setViewVisibility(R.id.swn_collapsed_laps, View.VISIBLE); remoteViewsExpanded.setTextViewText(R.id.swn_expanded_laps, lapText); remoteViewsExpanded.setViewVisibility(R.id.swn_expanded_laps, View.VISIBLE); } else { remoteViewsCollapsed.setViewVisibility(R.id.swn_collapsed_laps, View.GONE); remoteViewsExpanded.setViewVisibility(R.id.swn_expanded_laps, View.GONE); } } else { // Left button: reset clock remoteViewsExpanded.setTextViewText( R.id.swn_left_button, getResources().getText(R.string.sw_reset_button)); Intent leftButtonIntent = new Intent(context, StopwatchService.class); leftButtonIntent.setAction(Stopwatches.RESET_AND_LAUNCH_STOPWATCH); remoteViewsExpanded.setOnClickPendingIntent(R.id.swn_left_button, PendingIntent.getService(context, 0, leftButtonIntent, 0)); remoteViewsExpanded.setTextViewCompoundDrawables(R.id.swn_left_button, R.drawable.ic_notify_reset, 0, 0, 0); // Right button: start clock remoteViewsExpanded.setTextViewText( R.id.swn_right_button, getResources().getText(R.string.sw_start_button)); Intent rightButtonIntent = new Intent(context, StopwatchService.class); rightButtonIntent.setAction(Stopwatches.START_STOPWATCH); remoteViewsExpanded.setOnClickPendingIntent(R.id.swn_right_button, PendingIntent.getService(context, 0, rightButtonIntent, 0)); remoteViewsExpanded.setTextViewCompoundDrawables(R.id.swn_right_button, R.drawable.ic_notify_start, 0, 0, 0); // Show stopped string. remoteViewsCollapsed.setTextViewText(R.id.swn_collapsed_laps, getString(R.string.swn_stopped)); remoteViewsCollapsed.setViewVisibility(R.id.swn_collapsed_laps, View.VISIBLE); remoteViewsExpanded.setTextViewText(R.id.swn_expanded_laps, getString(R.string.swn_stopped)); remoteViewsExpanded.setViewVisibility(R.id.swn_expanded_laps, View.VISIBLE); } Intent dismissIntent = new Intent(context, StopwatchService.class); dismissIntent.setAction(Stopwatches.RESET_STOPWATCH); Notification notification = new Notification.Builder(context) .setAutoCancel(!clockRunning) .setContent(remoteViewsCollapsed) .setOngoing(clockRunning) .setDeleteIntent(PendingIntent.getService(context, 0, dismissIntent, 0)) .setSmallIcon(R.drawable.ic_tab_stopwatch_activated) .setPriority(Notification.PRIORITY_MAX).build(); notification.bigContentView = remoteViewsExpanded; mNotificationManager.notify(NOTIFICATION_ID, notification); } /** Save the notification to be shown when the app is closed. **/ private void saveNotification(long clockTime, boolean clockRunning, int numLaps) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( getApplicationContext()); SharedPreferences.Editor editor = prefs.edit(); if (clockRunning) { editor.putLong(Stopwatches.NOTIF_CLOCK_BASE, clockTime); editor.putLong(Stopwatches.NOTIF_CLOCK_ELAPSED, -1); editor.putBoolean(Stopwatches.NOTIF_CLOCK_RUNNING, true); } else { editor.putLong(Stopwatches.NOTIF_CLOCK_ELAPSED, clockTime); editor.putLong(Stopwatches.NOTIF_CLOCK_BASE, -1); editor.putBoolean(Stopwatches.NOTIF_CLOCK_RUNNING, false); } editor.putBoolean(Stopwatches.PREF_UPDATE_CIRCLE, false); editor.apply(); } /** Show the most recently saved notification. **/ private boolean showSavedNotification() { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( getApplicationContext()); long clockBaseTime = prefs.getLong(Stopwatches.NOTIF_CLOCK_BASE, -1); long clockElapsedTime = prefs.getLong(Stopwatches.NOTIF_CLOCK_ELAPSED, -1); boolean clockRunning = prefs.getBoolean(Stopwatches.NOTIF_CLOCK_RUNNING, false); int numLaps = prefs.getInt(Stopwatches.PREF_LAP_NUM, -1); if (clockBaseTime == -1) { if (clockElapsedTime == -1) { return false; } else { // We don't have a clock base time, so the clock is stopped. // Use the elapsed time to figure out what time to show. mElapsedTime = clockElapsedTime; clockBaseTime = Utils.getTimeNow() - clockElapsedTime; } } setNotification(clockBaseTime, clockRunning, numLaps); return true; } private void clearSavedNotification() { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( getApplicationContext()); SharedPreferences.Editor editor = prefs.edit(); editor.remove(Stopwatches.NOTIF_CLOCK_BASE); editor.remove(Stopwatches.NOTIF_CLOCK_RUNNING); editor.remove(Stopwatches.NOTIF_CLOCK_ELAPSED); editor.apply(); } private void closeNotificationShade() { Intent intent = new Intent(); intent.setAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); sendBroadcast(intent); } private void readFromSharedPrefs() { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( getApplicationContext()); mStartTime = prefs.getLong(Stopwatches.PREF_START_TIME, 0); mElapsedTime = prefs.getLong(Stopwatches.PREF_ACCUM_TIME, 0); mNumLaps = prefs.getInt(Stopwatches.PREF_LAP_NUM, Stopwatches.STOPWATCH_RESET); } private long[] readLapsFromPrefs() { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( getApplicationContext()); int numLaps = prefs.getInt(Stopwatches.PREF_LAP_NUM, Stopwatches.STOPWATCH_RESET); long[] laps = new long[numLaps]; long prevLapElapsedTime = 0; for (int lap_i = 0; lap_i < numLaps; lap_i++) { String key = Stopwatches.PREF_LAP_TIME + Integer.toString(lap_i + 1); long lap = prefs.getLong(key, 0); if (lap == prevLapElapsedTime && lap_i == numLaps - 1) { lap = mElapsedTime; } laps[numLaps - lap_i - 1] = lap - prevLapElapsedTime; prevLapElapsedTime = lap; } return laps; } private void writeToSharedPrefs(Long startTime, Long lapTimeElapsed, Long elapsedTime, Integer state, boolean updateCircle) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( getApplicationContext()); SharedPreferences.Editor editor = prefs.edit(); if (startTime != null) { editor.putLong(Stopwatches.PREF_START_TIME, startTime); mStartTime = startTime; } if (lapTimeElapsed != null) { int numLaps = prefs.getInt(Stopwatches.PREF_LAP_NUM, 0); if (numLaps == 0) { mNumLaps++; numLaps++; } editor.putLong(Stopwatches.PREF_LAP_TIME + Integer.toString(numLaps), lapTimeElapsed); numLaps++; editor.putLong(Stopwatches.PREF_LAP_TIME + Integer.toString(numLaps), lapTimeElapsed); editor.putInt(Stopwatches.PREF_LAP_NUM, numLaps); } if (elapsedTime != null) { editor.putLong(Stopwatches.PREF_ACCUM_TIME, elapsedTime); mElapsedTime = elapsedTime; } if (state != null) { if (state == Stopwatches.STOPWATCH_RESET) { editor.putInt(Stopwatches.PREF_STATE, Stopwatches.STOPWATCH_RESET); } else if (state == Stopwatches.STOPWATCH_RUNNING) { editor.putInt(Stopwatches.PREF_STATE, Stopwatches.STOPWATCH_RUNNING); } else if (state == Stopwatches.STOPWATCH_STOPPED) { editor.putInt(Stopwatches.PREF_STATE, Stopwatches.STOPWATCH_STOPPED); } } editor.putBoolean(Stopwatches.PREF_UPDATE_CIRCLE, updateCircle); editor.apply(); } private void writeSharedPrefsStarted(long startTime, boolean updateCircle) { writeToSharedPrefs(startTime, null, null, Stopwatches.STOPWATCH_RUNNING, updateCircle); if (updateCircle) { long time = Utils.getTimeNow(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( getApplicationContext()); long intervalStartTime = prefs.getLong( Stopwatches.KEY + CircleTimerView.PREF_CTV_INTERVAL_START, -1); if (intervalStartTime != -1) { intervalStartTime = time; SharedPreferences.Editor editor = prefs.edit(); editor.putLong(Stopwatches.KEY + CircleTimerView.PREF_CTV_INTERVAL_START, intervalStartTime); editor.putBoolean(Stopwatches.KEY + CircleTimerView.PREF_CTV_PAUSED, false); editor.apply(); } } } private void writeSharedPrefsLap(long lapTimeElapsed, boolean updateCircle) { writeToSharedPrefs(null, lapTimeElapsed, null, null, updateCircle); if (updateCircle) { long time = Utils.getTimeNow(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( getApplicationContext()); SharedPreferences.Editor editor = prefs.edit(); long laps[] = readLapsFromPrefs(); int numLaps = laps.length; long lapTime = laps[1]; if (numLaps == 2) { // Have only hit lap once. editor.putLong(Stopwatches.KEY + CircleTimerView.PREF_CTV_INTERVAL, lapTime); } else { editor.putLong(Stopwatches.KEY + CircleTimerView.PREF_CTV_MARKER_TIME, lapTime); } editor.putLong(Stopwatches.KEY + CircleTimerView.PREF_CTV_ACCUM_TIME, 0); if (numLaps < Stopwatches.MAX_LAPS) { editor.putLong(Stopwatches.KEY + CircleTimerView.PREF_CTV_INTERVAL_START, time); editor.putBoolean(Stopwatches.KEY + CircleTimerView.PREF_CTV_PAUSED, false); } else { editor.putLong(Stopwatches.KEY + CircleTimerView.PREF_CTV_INTERVAL_START, -1); } editor.apply(); } } private void writeSharedPrefsStopped(long elapsedTime, boolean updateCircle) { writeToSharedPrefs(null, null, elapsedTime, Stopwatches.STOPWATCH_STOPPED, updateCircle); if (updateCircle) { long time = Utils.getTimeNow(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( getApplicationContext()); long accumulatedTime = prefs.getLong( Stopwatches.KEY + CircleTimerView.PREF_CTV_ACCUM_TIME, 0); long intervalStartTime = prefs.getLong( Stopwatches.KEY + CircleTimerView.PREF_CTV_INTERVAL_START, -1); accumulatedTime += time - intervalStartTime; SharedPreferences.Editor editor = prefs.edit(); editor.putLong(Stopwatches.KEY + CircleTimerView.PREF_CTV_ACCUM_TIME, accumulatedTime); editor.putBoolean(Stopwatches.KEY + CircleTimerView.PREF_CTV_PAUSED, true); editor.putLong( Stopwatches.KEY + CircleTimerView.PREF_CTV_CURRENT_INTERVAL, accumulatedTime); editor.apply(); } } private void writeSharedPrefsReset(boolean updateCircle) { writeToSharedPrefs(null, null, null, Stopwatches.STOPWATCH_RESET, updateCircle); } }