关山初度尘未洗,策马扬鞭再奋蹄!这篇文章主要讲述安卓权威编程指南 挑战练习(第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 25private static final String TAG = "PollService"; 26 27private PollTask mCurrentTask; 28 29@Override 30public boolean onStartJob(JobParameters parms){ //服务启动后执行 31mCurrentTask = new PollTask(); 32mCurrentTask.execute(parms); //开启AsyncTask 33return true; 34} 35 36@Override 37public boolean onStopJob(JobParameters params) { 38if(mCurrentTask != null){ 39mCurrentTask.cancel(true); 40} 41return false; 42} 43 44 45public static void setServiceAlarm(Context context,Boolean shouldStartAlarm){ //Fragment中启动服务需要调用的方法.用于在Fragment启动JobService 46final int JOB_ID = 1; 47JobScheduler scheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); 48if(shouldStartAlarm){ 49scheduler.cancel(JOB_ID); 50}else{ 51JobInfo 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(); 56scheduler.schedule(jobInfo); 57} 58 59} 60 61//判断是否已经计划好了任务 62public static boolean isHasBeenScheduled(Context context){ 63 64final int JOB_ID = 1; 65 66JobScheduler scheduler = (JobScheduler)context.getSystemService(JOB_SCHEDULER_SERVICE); 67 68boolean hasBeenScheduled = false; 69 70for (JobInfo jobInfo : scheduler.getAllPendingJobs()) { 71if (jobInfo.getId() == JOB_ID) { 72hasBeenScheduled = true; 73} 74} 75 76return hasBeenScheduled; 77} 78 79public JobService(){ 80super(); 81} 82 83 84//用于执行 85private class PollTask extends AsyncTask< JobParameters,Void ,List< GalleryItem> > { 86//在doInBackground()方法中获取到最新的结果集。 87@Override 88protected List< GalleryItem> doInBackground(JobParameters... params) { 89JobParameters jobParams = params[0]; 90 91//不需要手动判断网络连接状态了 92 93String query = QueryPreferences.getStoredQuery(JobService.this); //获取查询值 94 95List< GalleryItem> items; 96 97//获取最新结果集 98if(query == null){ 99items = new FlickrFetcher().fetchRecentPhotos(); 100}else{ 101items = new FlickrFetcher().searchPhotos(query); 102} 103 104jobFinished(jobParams,false); 105 106return items; //将items返回出去, onPostExcute()方法会接受到 107} 108 109@Override 110protected void onPostExecute(List< GalleryItem> items) { 111String lastResultId = QueryPreferences.getLastResultId(JobService.this); 112//获取第一条结果 113String resultId = items.get(0).getId(); 114//确认是否不同于上一次结果ID ,不同的话弹出Notification。 115if(resultId.equals(lastResultId)){ 116Log.i(TAG, "Got a old result" + resultId); 117}else{ 118Log.i(TAG, "Got a new result" + resultId); 119 120Resources resources = getResources(); 121Intent i = PhotoGalleryActivity.newIntent(JobService.this); 122PendingIntent pi = PendingIntent.getActivity(JobService.this,0,i,0); 123 124Notification 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 133NotificationManagerCompat notificationManager = NotificationManagerCompat.from(JobService.this); 134notificationManager.notify(0,notification); 135} 136//将第一条结果存入SharedPreferences 137QueryPreferences.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); }
【安卓权威编程指南 挑战练习(第26章 在 Lollipop 设备上使用 JobService)】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); } }); }
推荐阅读
- 安卓权威编程指南-笔记(第24章 Looper Handler 和 HandlerThread)
- 安卓权威编程指南 挑战练习 24章 预加载以及缓存
- 10个最佳反向图像搜索引擎和应用程序推荐合集
- 10大最佳免费和付费音乐下载软件推荐合集(哪个最好用())
- Android和iPhone的10个最佳表情符号应用程序(免费下载??)
- 你应该尝试的10个PC最佳GBA模拟器推荐合集(你喜欢哪个())
- 12款PC体验高强度战斗的最佳策略游戏推荐合集(哪些最好())
- 27款无界游戏的最佳上古卷轴V(天际模组推荐合集)
- 文明5冒险的20个最令人惊叹的模组推荐合集(哪个最好())