Skip to content

Most visited

Recently visited

navigation
JobScheduler / src / com.example.android.jobscheduler /

MainActivity.java

1
/*
2
 * Copyright 2013 The Android Open Source Project
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
 
17
package com.example.android.jobscheduler;
18
 
19
import android.app.Activity;
20
import android.app.job.JobInfo;
21
import android.app.job.JobScheduler;
22
import android.content.ComponentName;
23
import android.content.Context;
24
import android.content.Intent;
25
import android.os.Bundle;
26
import android.os.Handler;
27
import android.os.Message;
28
import android.os.Messenger;
29
import android.os.PersistableBundle;
30
import android.support.annotation.ColorRes;
31
import android.support.annotation.Nullable;
32
import android.text.TextUtils;
33
import android.util.Log;
34
import android.view.View;
35
import android.widget.CheckBox;
36
import android.widget.EditText;
37
import android.widget.RadioButton;
38
import android.widget.TextView;
39
import android.widget.Toast;
40
 
41
import com.example.android.jobscheduler.service.MyJobService;
42
 
43
import java.lang.ref.WeakReference;
44
import java.util.List;
45
 
46
 
47
/**
48
 * Schedules and configures jobs to be executed by a {@link JobScheduler}.
49
 * <p>
50
 * {@link MyJobService} can send messages to this via a {@link Messenger}
51
 * that is sent in the Intent that starts the Service.
52
 */
53
public class MainActivity extends Activity {
54
 
55
    private static final String TAG = MainActivity.class.getSimpleName();
56
 
57
    public static final int MSG_UNCOLOR_START = 0;
58
    public static final int MSG_UNCOLOR_STOP = 1;
59
    public static final int MSG_COLOR_START = 2;
60
    public static final int MSG_COLOR_STOP = 3;
61
 
62
    public static final String MESSENGER_INTENT_KEY
63
            = BuildConfig.APPLICATION_ID + ".MESSENGER_INTENT_KEY";
64
    public static final String WORK_DURATION_KEY =
65
            BuildConfig.APPLICATION_ID + ".WORK_DURATION_KEY";
66
 
67
    private EditText mDelayEditText;
68
    private EditText mDeadlineEditText;
69
    private EditText mDurationTimeEditText;
70
    private RadioButton mWiFiConnectivityRadioButton;
71
    private RadioButton mAnyConnectivityRadioButton;
72
    private CheckBox mRequiresChargingCheckBox;
73
    private CheckBox mRequiresIdleCheckbox;
74
 
75
    private ComponentName mServiceComponent;
76
 
77
    private int mJobId = 0;
78
 
79
    // Handler for incoming messages from the service.
80
    private IncomingMessageHandler mHandler;
81
 
82
    @Override
83
    public void onCreate(Bundle savedInstanceState) {
84
        super.onCreate(savedInstanceState);
85
        setContentView(R.layout.sample_main);
86
 
87
        // Set up UI.
88
        mDelayEditText = (EditText) findViewById(R.id.delay_time);
89
        mDurationTimeEditText = (EditText) findViewById(R.id.duration_time);
90
        mDeadlineEditText = (EditText) findViewById(R.id.deadline_time);
91
        mWiFiConnectivityRadioButton = (RadioButton) findViewById(R.id.checkbox_unmetered);
92
        mAnyConnectivityRadioButton = (RadioButton) findViewById(R.id.checkbox_any);
93
        mRequiresChargingCheckBox = (CheckBox) findViewById(R.id.checkbox_charging);
94
        mRequiresIdleCheckbox = (CheckBox) findViewById(R.id.checkbox_idle);
95
        mServiceComponent = new ComponentName(this, MyJobService.class);
96
 
97
        mHandler = new IncomingMessageHandler(this);
98
    }
99
 
100
    @Override
101
    protected void onStop() {
102
        // A service can be "started" and/or "bound". In this case, it's "started" by this Activity
103
        // and "bound" to the JobScheduler (also called "Scheduled" by the JobScheduler). This call
104
        // to stopService() won't prevent scheduled jobs to be processed. However, failing
105
        // to call stopService() would keep it alive indefinitely.
106
        stopService(new Intent(this, MyJobService.class));
107
        super.onStop();
108
    }
109
 
110
    @Override
111
    protected void onStart() {
112
        super.onStart();
113
        // Start service and provide it a way to communicate with this class.
114
        Intent startServiceIntent = new Intent(this, MyJobService.class);
115
        Messenger messengerIncoming = new Messenger(mHandler);
116
        startServiceIntent.putExtra(MESSENGER_INTENT_KEY, messengerIncoming);
117
        startService(startServiceIntent);
118
    }
119
 
120
    /**
121
     * Executed when user clicks on SCHEDULE JOB.
122
     */
123
    public void scheduleJob(View v) {
124
        JobInfo.Builder builder = new JobInfo.Builder(mJobId++, mServiceComponent);
125
 
126
        String delay = mDelayEditText.getText().toString();
127
        if (!TextUtils.isEmpty(delay)) {
128
            builder.setMinimumLatency(Long.valueOf(delay) * 1000);
129
        }
130
        String deadline = mDeadlineEditText.getText().toString();
131
        if (!TextUtils.isEmpty(deadline)) {
132
            builder.setOverrideDeadline(Long.valueOf(deadline) * 1000);
133
        }
134
        boolean requiresUnmetered = mWiFiConnectivityRadioButton.isChecked();
135
        boolean requiresAnyConnectivity = mAnyConnectivityRadioButton.isChecked();
136
        if (requiresUnmetered) {
137
            builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
138
        } else if (requiresAnyConnectivity) {
139
            builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
140
        }
141
        builder.setRequiresDeviceIdle(mRequiresIdleCheckbox.isChecked());
142
        builder.setRequiresCharging(mRequiresChargingCheckBox.isChecked());
143
 
144
        // Extras, work duration.
145
        PersistableBundle extras = new PersistableBundle();
146
        String workDuration = mDurationTimeEditText.getText().toString();
147
        if (TextUtils.isEmpty(workDuration)) {
148
            workDuration = "1";
149
        }
150
        extras.putLong(WORK_DURATION_KEY, Long.valueOf(workDuration) * 1000);
151
 
152
        builder.setExtras(extras);
153
 
154
        // Schedule job
155
        Log.d(TAG, "Scheduling job");
156
        JobScheduler tm = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
157
        tm.schedule(builder.build());
158
    }
159
 
160
    /**
161
     * Executed when user clicks on CANCEL ALL.
162
     */
163
    public void cancelAllJobs(View v) {
164
        JobScheduler tm = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
165
        tm.cancelAll();
166
        Toast.makeText(MainActivity.this, R.string.all_jobs_cancelled, Toast.LENGTH_SHORT).show();
167
    }
168
 
169
    /**
170
     * Executed when user clicks on FINISH LAST TASK.
171
     */
172
    public void finishJob(View v) {
173
        JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
174
        List<JobInfo> allPendingJobs = jobScheduler.getAllPendingJobs();
175
        if (allPendingJobs.size() > 0) {
176
            // Finish the last one
177
            int jobId = allPendingJobs.get(0).getId();
178
            jobScheduler.cancel(jobId);
179
            Toast.makeText(
180
                    MainActivity.this, String.format(getString(R.string.cancelled_job), jobId),
181
                    Toast.LENGTH_SHORT).show();
182
        } else {
183
            Toast.makeText(
184
                    MainActivity.this, getString(R.string.no_jobs_to_cancel),
185
                    Toast.LENGTH_SHORT).show();
186
        }
187
    }
188
 
189
    /**
190
     * A {@link Handler} allows you to send messages associated with a thread. A {@link Messenger}
191
     * uses this handler to communicate from {@link MyJobService}. It's also used to make
192
     * the start and stop views blink for a short period of time.
193
     */
194
    private static class IncomingMessageHandler extends Handler {
195
 
196
        // Prevent possible leaks with a weak reference.
197
        private WeakReference<MainActivity> mActivity;
198
 
199
        IncomingMessageHandler(MainActivity activity) {
200
            super(/* default looper */);
201
            this.mActivity = new WeakReference<>(activity);
202
        }
203
 
204
        @Override
205
        public void handleMessage(Message msg) {
206
            MainActivity mainActivity = mActivity.get();
207
            if (mainActivity == null) {
208
                // Activity is no longer available, exit.
209
                return;
210
            }
211
            View showStartView = mainActivity.findViewById(R.id.onstart_textview);
212
            View showStopView = mainActivity.findViewById(R.id.onstop_textview);
213
            Message m;
214
            switch (msg.what) {
215
                /*
216
                 * Receives callback from the service when a job has landed
217
                 * on the app. Turns on indicator and sends a message to turn it off after
218
                 * a second.
219
                 */
220
                case MSG_COLOR_START:
221
                    // Start received, turn on the indicator and show text.
222
                    showStartView.setBackgroundColor(getColor(R.color.start_received));
223
                    updateParamsTextView(msg.obj, "started");
224
 
225
                    // Send message to turn it off after a second.
226
                    m = Message.obtain(this, MSG_UNCOLOR_START);
227
                    sendMessageDelayed(m, 1000L);
228
                    break;
229
                /*
230
                 * Receives callback from the service when a job that previously landed on the
231
                 * app must stop executing. Turns on indicator and sends a message to turn it
232
                 * off after two seconds.
233
                 */
234
                case MSG_COLOR_STOP:
235
                    // Stop received, turn on the indicator and show text.
236
                    showStopView.setBackgroundColor(getColor(R.color.stop_received));
237
                    updateParamsTextView(msg.obj, "stopped");
238
 
239
                    // Send message to turn it off after a second.
240
                    m = obtainMessage(MSG_UNCOLOR_STOP);
241
                    sendMessageDelayed(m, 2000L);
242
                    break;
243
                case MSG_UNCOLOR_START:
244
                    showStartView.setBackgroundColor(getColor(R.color.none_received));
245
                    updateParamsTextView(null, "");
246
                    break;
247
                case MSG_UNCOLOR_STOP:
248
                    showStopView.setBackgroundColor(getColor(R.color.none_received));
249
                    updateParamsTextView(null, "");
250
                    break;
251
            }
252
        }
253
 
254
        private void updateParamsTextView(@Nullable Object jobId, String action) {
255
            TextView paramsTextView = (TextView) mActivity.get().findViewById(R.id.task_params);
256
            if (jobId == null) {
257
                paramsTextView.setText("");
258
                return;
259
            }
260
            String jobIdText = String.valueOf(jobId);
261
            paramsTextView.setText(String.format("Job ID %s %s", jobIdText, action));
262
        }
263
 
264
        private int getColor(@ColorRes int color) {
265
            return mActivity.get().getResources().getColor(color);
266
        }
267
    }
268
}
This site uses cookies to store your preferences for site-specific language and display options.