安卓权威编程指南 挑战练习(第26章 在 Lollipop 设备上使用 JobService)

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 //将第一条结果存入SharedPreferences137 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); } }); }

 

 

相关文章