安卓權威編程指南 挑戰練習(第26章 在 Lollipop 設備上使用 JobService)
阿新 • • 發佈:2017-09-08
gallery sha params build 運行 intent ble 一次 lol
26.11 挑戰練習:在 Lollipop 設備上使用 JobService 請創建另一個 PollService 實現版本。新的 PollService 應該繼承 JobService 並使用 JobScheduler 來運行。在 PollService 啟動代碼中,檢查系統版本是否為Lollipop:如果是,就 使用 JobScheduler 計劃運行 JobService ;如果不是,依然使用 AlarmManager 實現。
JobService類:
1 package com.bignerdranch.android.photogallery;
2
3 import android.app.Notification;
4 import android.app.PendingIntent;
5 import android.app.job.JobInfo;
6 import android.app.job.JobParameters;
7 import android.app.job.JobScheduler;
8 import android.content.ComponentName;
9 import android.content.Context;
10 import android.content.Intent;
11 import android.content.res.Resources;
12 import android.os.AsyncTask;
13 import android.support.v4.app.NotificationCompat;
14 import android.support.v4.app.NotificationManagerCompat;
15 import android.util.Log;
16
17 import java.util.List;
18
19 /**
20 * Created by Leo on 2017/7/22.
21 */
22
23 public class JobService extends android.app.job.JobService {
24
25 private static final String TAG = "PollService";
26
27 private PollTask mCurrentTask;
28
29 @Override
30 public boolean onStartJob(JobParameters parms){ //服務啟動後執行
31 mCurrentTask = new PollTask();
32 mCurrentTask.execute(parms); //開啟AsyncTask
33 return true;
34 }
35
36 @Override
37 public boolean onStopJob(JobParameters params) {
38 if(mCurrentTask != null){
39 mCurrentTask.cancel(true);
40 }
41 return false;
42 }
43
44
45 public static void setServiceAlarm(Context context,Boolean shouldStartAlarm){ //Fragment中啟動服務需要調用的方法.用於在Fragment啟動JobService
46 final int JOB_ID = 1;
47 JobScheduler scheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
48 if(shouldStartAlarm){
49 scheduler.cancel(JOB_ID);
50 }else{
51 JobInfo jobInfo = new JobInfo.Builder(JOB_ID, new ComponentName(context, JobService.class))
52 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
53 .setPeriodic(1000 * 60)
54 .setPersisted(true)
55 .build();
56 scheduler.schedule(jobInfo);
57 }
58
59 }
60
61 //判斷是否已經計劃好了任務
62 public static boolean isHasBeenScheduled(Context context){
63
64 final int JOB_ID = 1;
65
66 JobScheduler scheduler = (JobScheduler)context.getSystemService(JOB_SCHEDULER_SERVICE);
67
68 boolean hasBeenScheduled = false;
69
70 for (JobInfo jobInfo : scheduler.getAllPendingJobs()) {
71 if (jobInfo.getId() == JOB_ID) {
72 hasBeenScheduled = true;
73 }
74 }
75
76 return hasBeenScheduled;
77 }
78
79 public JobService(){
80 super();
81 }
82
83
84 //用於執行
85 private class PollTask extends AsyncTask<JobParameters,Void ,List<GalleryItem>> {
86 //在doInBackground()方法中獲取到最新的結果集。
87 @Override
88 protected List<GalleryItem> doInBackground(JobParameters... params) {
89 JobParameters jobParams = params[0];
90
91 //不需要手動判斷網絡連接狀態了
92
93 String query = QueryPreferences.getStoredQuery(JobService.this); //獲取查詢值
94
95 List<GalleryItem> items;
96
97 //獲取最新結果集
98 if(query == null){
99 items = new FlickrFetcher().fetchRecentPhotos();
100 }else{
101 items = new FlickrFetcher().searchPhotos(query);
102 }
103
104 jobFinished(jobParams,false);
105
106 return items; //將items返回出去, onPostExcute()方法會接受到
107 }
108
109 @Override
110 protected void onPostExecute(List<GalleryItem> items) {
111 String lastResultId = QueryPreferences.getLastResultId(JobService.this);
112 //獲取第一條結果
113 String resultId = items.get(0).getId();
114 //確認是否不同於上一次結果ID ,不同的話彈出Notification。
115 if(resultId.equals(lastResultId)){
116 Log.i(TAG, "Got a old result" + resultId);
117 }else{
118 Log.i(TAG, "Got a new result" + resultId);
119
120 Resources resources = getResources();
121 Intent i = PhotoGalleryActivity.newIntent(JobService.this);
122 PendingIntent pi = PendingIntent.getActivity(JobService.this,0,i,0);
123
124 Notification notification = new NotificationCompat.Builder(JobService.this)
125 .setTicker(resources.getString(R.string.new_pictures_title))
126 .setSmallIcon(android.R.drawable.ic_menu_report_image)
127 .setContentTitle(resources.getString(R.string.new_pictures_title))
128 .setContentText(resources.getString(R.string.new_pictures_text))
129 .setContentIntent(pi)
130 .setAutoCancel(true)
131 .build();
132
133 NotificationManagerCompat notificationManager = NotificationManagerCompat.from(JobService.this);
134 notificationManager.notify(0,notification);
135 }
136 //將第一條結果存入SharedPreferences
137 QueryPreferences.setLastResultId(JobService.this,resultId);
138 }
139 }
140 }
PhotoGalleryFragment類:
onOptionsSelected()方法:
@Override
public boolean onOptionsItemSelected(MenuItem item){
switch (item.getItemId()){
case R.id.menu_item_clear:
QueryPreferences.setStoredQuery(getActivity(),null);
updateItems();
return true;
case R.id.menu_item_toggle_polling:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
boolean shouldStartAlarm = JobService.isHasBeenScheduled(getActivity()); //啟動服務
JobService.setServiceAlarm(getActivity(),shouldStartAlarm);
getActivity().invalidateOptionsMenu();
}else{
boolean shouldStartAlarm = !PollService.isServiceAlarmOn(getActivity());
PollService.setServiceAlarm(getActivity(),shouldStartAlarm);
getActivity().invalidateOptionsMenu(); //刷新菜單項
}
return true;
default:
return super.onOptionsItemSelected(item);
}
onCreateOptionsMenu()方法:
public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater){
super.onCreateOptionsMenu(menu,menuInflater);
menuInflater.inflate(R.menu.fragment_photo_gallery,menu);
MenuItem searchItem = menu.findItem(R.id.menu_item_search); //將MenuItem取出並保存在searchItem變量中。
mSearchView = (SearchView)searchItem.getActionView(); //取出SearchView對象。
//設置監聽器
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {//提交搜索查詢時。這個方法執行。
Log.d(TAG, "onQueryTextSubmit: "+ s);
QueryPreferences.setStoredQuery(getActivity(),s); //存儲用戶提交的查詢信息。
updateItems();
hintSoftInputAndSearchField(); //隱藏鍵盤的方法
return true;
}
@Override
public boolean onQueryTextChange(String s) { //搜索框的文字有變化時,這個方法執行。
Log.d(TAG, "onQueryTextChange: " + s);
return false;
}
});
MenuItem toggleItem = menu.findItem(R.id.menu_item_toggle_polling);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
if(JobService.isHasBeenScheduled(getActivity())){
toggleItem.setTitle(R.string.stop_polling);
}else {
toggleItem.setTitle(R.string.start_polling);
}
}else{
if (PollService.isServiceAlarmOn(getActivity())) {
toggleItem.setTitle(R.string.stop_polling);
} else {
toggleItem.setTitle(R.string.start_polling);
}
}
mSearchView.setOnSearchClickListener(new View.OnClickListener() { //設置點擊按鈕時,顯示之前搜索過的值
@Override
public void onClick(View v) {
String query = QueryPreferences.getStoredQuery(getActivity());
mSearchView.setQuery(query,false);
}
});
}
安卓權威編程指南 挑戰練習(第26章 在 Lollipop 設備上使用 JobService)