diff options
Diffstat (limited to 'samples/browseable/JobScheduler/src/com.example.android.jobscheduler/MainActivity.java')
-rw-r--r-- | samples/browseable/JobScheduler/src/com.example.android.jobscheduler/MainActivity.java | 271 |
1 files changed, 172 insertions, 99 deletions
diff --git a/samples/browseable/JobScheduler/src/com.example.android.jobscheduler/MainActivity.java b/samples/browseable/JobScheduler/src/com.example.android.jobscheduler/MainActivity.java index 624e22d02..fbb817261 100644 --- a/samples/browseable/JobScheduler/src/com.example.android.jobscheduler/MainActivity.java +++ b/samples/browseable/JobScheduler/src/com.example.android.jobscheduler/MainActivity.java @@ -18,17 +18,19 @@ package com.example.android.jobscheduler; import android.app.Activity; import android.app.job.JobInfo; -import android.app.job.JobParameters; import android.app.job.JobScheduler; import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.content.res.Resources; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.Messenger; +import android.os.PersistableBundle; +import android.support.annotation.ColorRes; +import android.support.annotation.Nullable; import android.text.TextUtils; +import android.util.Log; import android.view.View; import android.widget.CheckBox; import android.widget.EditText; @@ -36,105 +38,97 @@ import android.widget.RadioButton; import android.widget.TextView; import android.widget.Toast; -import com.example.android.jobscheduler.service.TestJobService; +import com.example.android.jobscheduler.service.MyJobService; +import java.lang.ref.WeakReference; +import java.util.List; + + +/** + * Schedules and configures jobs to be executed by a {@link JobScheduler}. + * <p> + * {@link MyJobService} can send messages to this via a {@link Messenger} + * that is sent in the Intent that starts the Service. + */ public class MainActivity extends Activity { - private static final String TAG = "MainActivity"; + private static final String TAG = MainActivity.class.getSimpleName(); - public static final int MSG_UNCOLOUR_START = 0; - public static final int MSG_UNCOLOUR_STOP = 1; - public static final int MSG_SERVICE_OBJ = 2; + public static final int MSG_UNCOLOR_START = 0; + public static final int MSG_UNCOLOR_STOP = 1; + public static final int MSG_COLOR_START = 2; + public static final int MSG_COLOR_STOP = 3; + + public static final String MESSENGER_INTENT_KEY + = BuildConfig.APPLICATION_ID + ".MESSENGER_INTENT_KEY"; + public static final String WORK_DURATION_KEY = + BuildConfig.APPLICATION_ID + ".WORK_DURATION_KEY"; + + private EditText mDelayEditText; + private EditText mDeadlineEditText; + private EditText mDurationTimeEditText; + private RadioButton mWiFiConnectivityRadioButton; + private RadioButton mAnyConnectivityRadioButton; + private CheckBox mRequiresChargingCheckBox; + private CheckBox mRequiresIdleCheckbox; + + private ComponentName mServiceComponent; + + private int mJobId = 0; + + // Handler for incoming messages from the service. + private IncomingMessageHandler mHandler; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.sample_main); - Resources res = getResources(); - defaultColor = res.getColor(R.color.none_received); - startJobColor = res.getColor(R.color.start_received); - stopJobColor = res.getColor(R.color.stop_received); // Set up UI. - mShowStartView = (TextView) findViewById(R.id.onstart_textview); - mShowStopView = (TextView) findViewById(R.id.onstop_textview); - mParamsTextView = (TextView) findViewById(R.id.task_params); mDelayEditText = (EditText) findViewById(R.id.delay_time); + mDurationTimeEditText = (EditText) findViewById(R.id.duration_time); mDeadlineEditText = (EditText) findViewById(R.id.deadline_time); mWiFiConnectivityRadioButton = (RadioButton) findViewById(R.id.checkbox_unmetered); mAnyConnectivityRadioButton = (RadioButton) findViewById(R.id.checkbox_any); mRequiresChargingCheckBox = (CheckBox) findViewById(R.id.checkbox_charging); mRequiresIdleCheckbox = (CheckBox) findViewById(R.id.checkbox_idle); - mServiceComponent = new ComponentName(this, TestJobService.class); - // Start service and provide it a way to communicate with us. - Intent startServiceIntent = new Intent(this, TestJobService.class); - startServiceIntent.putExtra("messenger", new Messenger(mHandler)); - startService(startServiceIntent); - } - // UI fields. - int defaultColor; - int startJobColor; - int stopJobColor; - - private TextView mShowStartView; - private TextView mShowStopView; - private TextView mParamsTextView; - private EditText mDelayEditText; - private EditText mDeadlineEditText; - private RadioButton mWiFiConnectivityRadioButton; - private RadioButton mAnyConnectivityRadioButton; - private CheckBox mRequiresChargingCheckBox; - private CheckBox mRequiresIdleCheckbox; + mServiceComponent = new ComponentName(this, MyJobService.class); - ComponentName mServiceComponent; - /** Service object to interact scheduled jobs. */ - TestJobService mTestService; - - private static int kJobId = 0; + mHandler = new IncomingMessageHandler(this); + } - Handler mHandler = new Handler(/* default looper */) { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_UNCOLOUR_START: - mShowStartView.setBackgroundColor(defaultColor); - break; - case MSG_UNCOLOUR_STOP: - mShowStopView.setBackgroundColor(defaultColor); - break; - case MSG_SERVICE_OBJ: - mTestService = (TestJobService) msg.obj; - mTestService.setUiCallback(MainActivity.this); - } - } - }; + @Override + protected void onStop() { + // A service can be "started" and/or "bound". In this case, it's "started" by this Activity + // and "bound" to the JobScheduler (also called "Scheduled" by the JobScheduler). This call + // to stopService() won't prevent scheduled jobs to be processed. However, failing + // to call stopService() would keep it alive indefinitely. + stopService(new Intent(this, MyJobService.class)); + super.onStop(); + } - private boolean ensureTestService() { - if (mTestService == null) { - Toast.makeText(MainActivity.this, "Service null, never got callback?", - Toast.LENGTH_SHORT).show(); - return false; - } - return true; + @Override + protected void onStart() { + super.onStart(); + // Start service and provide it a way to communicate with this class. + Intent startServiceIntent = new Intent(this, MyJobService.class); + Messenger messengerIncoming = new Messenger(mHandler); + startServiceIntent.putExtra(MESSENGER_INTENT_KEY, messengerIncoming); + startService(startServiceIntent); } /** - * UI onclick listener to schedule a job. What this job is is defined in - * TestJobService#scheduleJob(). + * Executed when user clicks on SCHEDULE JOB. */ public void scheduleJob(View v) { - if (!ensureTestService()) { - return; - } - - JobInfo.Builder builder = new JobInfo.Builder(kJobId++, mServiceComponent); + JobInfo.Builder builder = new JobInfo.Builder(mJobId++, mServiceComponent); String delay = mDelayEditText.getText().toString(); - if (delay != null && !TextUtils.isEmpty(delay)) { + if (!TextUtils.isEmpty(delay)) { builder.setMinimumLatency(Long.valueOf(delay) * 1000); } String deadline = mDeadlineEditText.getText().toString(); - if (deadline != null && !TextUtils.isEmpty(deadline)) { + if (!TextUtils.isEmpty(deadline)) { builder.setOverrideDeadline(Long.valueOf(deadline) * 1000); } boolean requiresUnmetered = mWiFiConnectivityRadioButton.isChecked(); @@ -147,49 +141,128 @@ public class MainActivity extends Activity { builder.setRequiresDeviceIdle(mRequiresIdleCheckbox.isChecked()); builder.setRequiresCharging(mRequiresChargingCheckBox.isChecked()); - mTestService.scheduleJob(builder.build()); + // Extras, work duration. + PersistableBundle extras = new PersistableBundle(); + String workDuration = mDurationTimeEditText.getText().toString(); + if (TextUtils.isEmpty(workDuration)) { + workDuration = "1"; + } + extras.putLong(WORK_DURATION_KEY, Long.valueOf(workDuration) * 1000); + + builder.setExtras(extras); + // Schedule job + Log.d(TAG, "Scheduling job"); + JobScheduler tm = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); + tm.schedule(builder.build()); } + /** + * Executed when user clicks on CANCEL ALL. + */ public void cancelAllJobs(View v) { - JobScheduler tm = - (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); + JobScheduler tm = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); tm.cancelAll(); + Toast.makeText(MainActivity.this, R.string.all_jobs_cancelled, Toast.LENGTH_SHORT).show(); } /** - * UI onclick listener to call jobFinished() in our service. + * Executed when user clicks on FINISH LAST TASK. */ public void finishJob(View v) { - if (!ensureTestService()) { - return; + JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); + List<JobInfo> allPendingJobs = jobScheduler.getAllPendingJobs(); + if (allPendingJobs.size() > 0) { + // Finish the last one + int jobId = allPendingJobs.get(0).getId(); + jobScheduler.cancel(jobId); + Toast.makeText( + MainActivity.this, String.format(getString(R.string.cancelled_job), jobId), + Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText( + MainActivity.this, getString(R.string.no_jobs_to_cancel), + Toast.LENGTH_SHORT).show(); } - mTestService.callJobFinished(); - mParamsTextView.setText(""); } /** - * Receives callback from the service when a job has landed - * on the app. Colours the UI and post a message to - * uncolour it after a second. + * A {@link Handler} allows you to send messages associated with a thread. A {@link Messenger} + * uses this handler to communicate from {@link MyJobService}. It's also used to make + * the start and stop views blink for a short period of time. */ - public void onReceivedStartJob(JobParameters params) { - mShowStartView.setBackgroundColor(startJobColor); - Message m = Message.obtain(mHandler, MSG_UNCOLOUR_START); - mHandler.sendMessageDelayed(m, 1000L); // uncolour in 1 second. - mParamsTextView.setText("Executing: " + params.getJobId() + " " + params.getExtras()); - } + private static class IncomingMessageHandler extends Handler { - /** - * Receives callback from the service when a job that - * previously landed on the app must stop executing. - * Colours the UI and post a message to uncolour it after a - * second. - */ - public void onReceivedStopJob() { - mShowStopView.setBackgroundColor(stopJobColor); - Message m = Message.obtain(mHandler, MSG_UNCOLOUR_STOP); - mHandler.sendMessageDelayed(m, 2000L); // uncolour in 1 second. - mParamsTextView.setText(""); + // Prevent possible leaks with a weak reference. + private WeakReference<MainActivity> mActivity; + + IncomingMessageHandler(MainActivity activity) { + super(/* default looper */); + this.mActivity = new WeakReference<>(activity); + } + + @Override + public void handleMessage(Message msg) { + MainActivity mainActivity = mActivity.get(); + if (mainActivity == null) { + // Activity is no longer available, exit. + return; + } + View showStartView = mainActivity.findViewById(R.id.onstart_textview); + View showStopView = mainActivity.findViewById(R.id.onstop_textview); + Message m; + switch (msg.what) { + /* + * Receives callback from the service when a job has landed + * on the app. Turns on indicator and sends a message to turn it off after + * a second. + */ + case MSG_COLOR_START: + // Start received, turn on the indicator and show text. + showStartView.setBackgroundColor(getColor(R.color.start_received)); + updateParamsTextView(msg.obj, "started"); + + // Send message to turn it off after a second. + m = Message.obtain(this, MSG_UNCOLOR_START); + sendMessageDelayed(m, 1000L); + break; + /* + * Receives callback from the service when a job that previously landed on the + * app must stop executing. Turns on indicator and sends a message to turn it + * off after two seconds. + */ + case MSG_COLOR_STOP: + // Stop received, turn on the indicator and show text. + showStopView.setBackgroundColor(getColor(R.color.stop_received)); + updateParamsTextView(msg.obj, "stopped"); + + // Send message to turn it off after a second. + m = obtainMessage(MSG_UNCOLOR_STOP); + sendMessageDelayed(m, 2000L); + break; + case MSG_UNCOLOR_START: + showStartView.setBackgroundColor(getColor(R.color.none_received)); + updateParamsTextView(null, ""); + break; + case MSG_UNCOLOR_STOP: + showStopView.setBackgroundColor(getColor(R.color.none_received)); + updateParamsTextView(null, ""); + break; + } + } + + private void updateParamsTextView(@Nullable Object jobId, String action) { + TextView paramsTextView = (TextView) mActivity.get().findViewById(R.id.task_params); + if (jobId == null) { + paramsTextView.setText(""); + return; + } + String jobIdText = String.valueOf(jobId); + paramsTextView.setText(String.format("Job ID %s %s", jobIdText, action)); + } + + private int getColor(@ColorRes int color) { + return mActivity.get().getResources().getColor(color); + } } } |