Android后台执行的定时器实现
Android后台运行定时器,方便我们运行定位跟踪等任务需求。 以下简要说明实现Android后台定时器的要点, 文章末尾能够下载到project代码,可直接编译运行。
AndroidManifest.xml 文件内容例如以下:
<? xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.routing.videocamera"
android:versionCode="1"
android:versionName="1.0" > <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="16" /> <application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.routing.videocamera.Video"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:enabled="true" android:name=".TimerService" />
<receiver android:name=".AutoReceiver" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</receiver> </application> </manifest>
当中关键的代码是赋予项目 RECEIVE_BOOT_COMPLETED 权限 :
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Video.java 文件的内容例如以下 :
package com.routing.videocamera; public class Video extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video); Intent intent=new Intent(this,AutoReceiver.class);
intent.setAction("VIDEO_TIMER");
PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, 0);
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), 10*1000, sender); Button btnStart = (Button)findViewById(R.id.buttonSave);
btnStart.setOnClickListener(clickListener); Context ctx = Video.this;
SharedPreferences sp = ctx.getSharedPreferences("VIDEO", MODE_PRIVATE);
//存入数据 Editor editor = sp.edit(); String serverAddr = sp.getString("ServerAddr", "NULL");
String cameraName = sp.getString("CameraName", "NULL");
int cameraID = sp.getInt("CameraID", 0);
int cameraPort = sp.getInt("CameraPort", 0); EditText editServerAddr = (EditText)findViewById(R.id.editServerAddr);
editServerAddr.setText(serverAddr); EditText editCameraName = (EditText)findViewById(R.id.editCameraName);
editCameraName.setText(cameraName); EditText editCameraID = (EditText)findViewById(R.id.editCameraID);
editCameraID.setText(Integer.toString(cameraID)); EditText editCameraPort = (EditText)findViewById(R.id.editCameraPort);
editCameraPort.setText(Integer.toString(cameraPort)); } private void saveSetting ()
{
EditText editServerAddr = (EditText)findViewById(R.id.editServerAddr);
String serverAddr = editServerAddr.getText().toString(); EditText editCameraName = (EditText)findViewById(R.id.editCameraName);
String cameraName = editCameraName.getText().toString(); EditText editCameraID = (EditText)findViewById(R.id.editCameraID);
int cameraID = Integer.parseInt(editCameraID.getText().toString()); EditText editCameraPort = (EditText)findViewById(R.id.editCameraPort);
int cameraPort = Integer.parseInt(editCameraPort.getText().toString()); //获取SharedPreferences对象
Context ctx = Video.this;
SharedPreferences sp = ctx.getSharedPreferences("VIDEO", MODE_PRIVATE);
//存入数据
Editor editor = sp.edit();
if (serverAddr != "")
editor.putString("ServerAddr", serverAddr);
if (cameraName != "")
editor.putString("CameraName", cameraName); editor.putInt("CameraID", cameraID); editor.putInt("CameraPort", cameraPort); editor.commit(); } @Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_video, menu);
return true;
} private OnClickListener clickListener = new OnClickListener()
{ @Override
public void onClick(View v)
{
int ret = 0;
switch(v.getId())
{
case R.id.buttonSave:
saveSetting ();
break; } }
}; }
该文件关键的代码是OnCreate函数中的以下4行代码 :
intent.setAction("VIDEO_TIMER");
PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, 0);
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), 10*1000, sender);
intent.setAction("VIDEO_TIMER") 设置系统向应用程序发送的消息类型为 VIDEO_TIMER。
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), 10*1000, sender); 该行代码让系统多久发送一次消息,我这里设置的是10秒发送一次VIDEO_TIMER消息。
发送出去的消息, 会在 class AutoReceiver extends BroadcastReceiver 类里进行接收,并处理。
以下是 TimerService.java 文件 :
package com.routing.videocamera; public class TimerService extends Service
{
public void onCreate() { super.onCreate();
Log.v("TimerService", "OnCreate");
} private static String mUrl;
public void onStart(Intent intent, int startId) { Log.v("TimerService", "onStart"); Context ctx = TimerService.this;
//Context ctx = context;
SharedPreferences sp = ctx.getSharedPreferences("VIDEO", MODE_PRIVATE);
//存入数据 String serverAddr = sp.getString("ServerAddr", "");
String cameraName = sp.getString("CameraName", "");
int cameraID = sp.getInt("CameraID", 0);
int cameraPort = sp.getInt("CameraPort", 0); if (serverAddr == "" || cameraName == "" || cameraID == 0 || cameraPort == 0 || serverAddr == "NULL" || cameraName == "NULL")
return; String Url = serverAddr + "/cameramgr.php? " + "CameraName=" + cameraName + "&CameraID=" + cameraID + "&CameraPort=" + cameraPort;
Log.v("FFMPEG URL=", Url); mUrl = Url; new Thread()
{
@Override
public void run()
{
HttpParams httpParams;
// 创建 HttpParams 以用来设置 HTTP 參数(这一部分没必要的)
httpParams = new BasicHttpParams();
// 设置连接超时和 Socket 超时,以及 Socket 缓存大小
HttpConnectionParams.setConnectionTimeout(httpParams, 20 * 1000);
HttpConnectionParams.setSoTimeout(httpParams, 20 * 1000);
HttpConnectionParams.setSocketBufferSize(httpParams, 8192);
// 设置重定向,缺省为 true
HttpClientParams.setRedirecting(httpParams, true);
// 设置 user agent
String userAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2) Gecko/20100115 Firefox/3.6";
HttpProtocolParams.setUserAgent(httpParams, userAgent);
// 创建一个 HttpClient 实例
// 注意 HttpClient httpClient = new HttpClient(); 是Commons HttpClient
// 中的使用方法,在 Android 1.5 中我们须要使用 Apache 的缺省实现 DefaultHttpClient
HttpClient httpClient = new DefaultHttpClient(httpParams); //String s = this.getName();
HttpGet httpRequest = new HttpGet(mUrl);
String strResult = "doGetError";
try { HttpResponse httpResponse = httpClient.execute(httpRequest); if (httpResponse.getStatusLine().getStatusCode() == 200)
{ strResult = EntityUtils.toString(httpResponse.getEntity());
}
else
{
strResult = "Error Response: " + httpResponse.getStatusLine().toString();
}
}
catch (ClientProtocolException e)
{
strResult = e.getMessage().toString();
e.printStackTrace();
}
catch (IOException e)
{
strResult = e.getMessage().toString();
e.printStackTrace();
}
catch (Exception e)
{
strResult = e.getMessage().toString();
e.printStackTrace();
}
Log.v("strResult", strResult);
}
}.start (); } public String doPost(String url, List<NameValuePair> params)
{
/* 建立HTTPPost对象 */
HttpPost httpRequest = new HttpPost(url);
String strResult = "doPostError";
try {
/* 加入请求參数到请求对象 */
httpRequest.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
/* 发送请求并等待响应 */ HttpParams httpParams;
// 创建 HttpParams 以用来设置 HTTP 參数(这一部分没必要的)
httpParams = new BasicHttpParams();
// 设置连接超时和 Socket 超时。以及 Socket 缓存大小
HttpConnectionParams.setConnectionTimeout(httpParams, 20 * 1000);
HttpConnectionParams.setSoTimeout(httpParams, 20 * 1000);
HttpConnectionParams.setSocketBufferSize(httpParams, 8192);
// 设置重定向,缺省为 true
HttpClientParams.setRedirecting(httpParams, true);
// 设置 user agent
String userAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2) Gecko/20100115 Firefox/3.6";
HttpProtocolParams.setUserAgent(httpParams, userAgent); HttpClient httpClient = new DefaultHttpClient(httpParams);
HttpResponse httpResponse = httpClient.execute(httpRequest);
/* 若状态码为200 ok */
if (httpResponse.getStatusLine().getStatusCode() == 200)
{
/* 读返回数据 */
strResult = EntityUtils.toString(httpResponse.getEntity());
}
else
{
strResult = "Error Response: " + httpResponse.getStatusLine().toString();
}
}
catch (ClientProtocolException e)
{
strResult = e.getMessage().toString();
e.printStackTrace();
}
catch (IOException e)
{
strResult = e.getMessage().toString();
e.printStackTrace();
}
catch (Exception e)
{
strResult = e.getMessage().toString();
e.printStackTrace();
}
Log.v("strResult", strResult);
return strResult;
} public void onDestroy() { super.onDestroy();
Log.v("TimerService", "onDestroy");
} public IBinder onBind(Intent intent) {
return null;
} public static String inStream2String(InputStream inputStream)
{
InputStreamReader inputStreamReader = null;
try
{
inputStreamReader = new InputStreamReader(inputStream, "utf8");
}
catch (UnsupportedEncodingException e1)
{
e1.printStackTrace();
}
BufferedReader reader = new BufferedReader(inputStreamReader);
StringBuffer sb = new StringBuffer("");
String line;
try
{
while ((line = reader.readLine()) != null)
{
sb.append(line);
sb.append("\n");
}
}
catch (IOException e)
{
e.printStackTrace();
}
return sb.toString();
} }
该文件是定时器运行的代码,没什么特别的。
以下是 AutoReceiver.java 文件 :
package com.routing.videocamera; public class AutoReceiver extends BroadcastReceiver
{
/*要接收的intent源*/
//static final String ACTION = "android.intent.action.BOOT_COMPLETED";
private static final int MODE_PRIVATE = 0;
@Override
public void onReceive(Context context, Intent intent)
{ if (intent.getAction().equals("VIDEO_TIMER"))
{
Intent Intentservice = new Intent(context, TimerService.class); // 要启动的Activity
Intentservice.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startService(Intentservice); }
} public static String inStream2String(InputStream inputStream)
{
InputStreamReader inputStreamReader = null;
try
{
inputStreamReader = new InputStreamReader(inputStream, "utf8");
}
catch (UnsupportedEncodingException e1)
{
e1.printStackTrace();
}
BufferedReader reader = new BufferedReader(inputStreamReader);
StringBuffer sb = new StringBuffer("");
String line;
try
{
while ((line = reader.readLine()) != null)
{
sb.append(line);
sb.append("\n");
}
}
catch (IOException e)
{
e.printStackTrace();
}
return sb.toString();
} public void KeepAlive()
{
new Thread()
{
public void run()
{
HttpClient client = new DefaultHttpClient(); HttpGet get = new HttpGet("http://www.baidu.com");
HttpResponse response; try {
response = client.execute(get);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
{
InputStream is = response.getEntity().getContent();
String result = inStream2String(is);
//Assert.assertEquals(result, "GET_SUCCESS");
//Toast.makeText(Video.this, "Http Get Success:", Toast.LENGTH_LONG).show();
Log.v("FFMPEG-----= ", result);
}
else
{
//Toast.makeText(Video.this, "Http Get Fail", Toast.LENGTH_LONG).show(); }
}
catch (ClientProtocolException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
//super.run();
}
}.start();
} }
该文件的关键函数是onReceive函数,在这里接收到系统发送出来的 VIDEO_TIMER 消息,然后我们启动一个新任务来运行 TimerService 的代码 :
public void onReceive(Context context, Intent intent)
{ if (intent.getAction().equals("VIDEO_TIMER"))
{
Intent Intentservice = new Intent(context, TimerService.class); // 要启动的Activity
Intentservice.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startService(Intentservice); }
}
完整源码下载地址 :http://download.csdn.net/download/langeldep/7845831
Android后台执行的定时器实现的更多相关文章
- android: 后台执行的定时任务
Android 中的定时任务一般有两种实现方式,一种是使用 Java API 里提供的 Timer 类, 一种是使用 Android 的 Alarm 机制.这两种方式在多数情况下都能实现类似的效果,但 ...
- Android应用开发按下返回键退向后台执行
转载请注明来源:http://blog.csdn.net/kjunchen/article/details/50429694 Android应用开发按下返回键退向后台执行 我们日常使用的非常多Andr ...
- php中怎么实现后台执行?
http://www.cnblogs.com/zdz8207/p/3765567.html php中实现后台执行的方法: ignore_user_abort(true); // 后台运行set_tim ...
- 在Android开发中,定时器一般有以下3种实现方法
在Android开发中,定时器一般有以下3种实现方法: 原文地址http://www.360doc.com/content/12/0619/13/87000_219180978.shtml 一.采用H ...
- android 后台服务定时通知
最近有个项目的要求是在程序退出之后,任然可以每天定时发通知,我们可以想下,其实就是后台开一个服务,然后时间到了就发下通知. 1.首先我们需要用到Service类. 先上代码在慢慢解释 package ...
- Android初级教程启动定时器详解
本案例知识是:后台执行定时任务. Alarm机制: 一.创建LongRunningService类 package com.example.servicebestpractice; import ja ...
- 全面盘点当前Android后台保活方案的真实运行效果(截止2019年前)
本文原作者“minminaya”,作者网站:minminaya.cn,为了提升文章品质,即时通讯网对内容作了幅修订和改动,感谢原作者. 1.引言 对于IM应用和消息推送服务的开发者来说,在Androi ...
- Android后台处理最佳实践(Best Practices for Background Jobs)
本课将告诉你如何通过后台加载来加速应用启动和降低应用耗电. 后台跑服务 除非你做了特殊指定,否则在应用中的大部分前台操作都是在一个特殊的UI线程里面进行的.这有可能会导致一些问题,因为长时间运行的操作 ...
- iOS和Android后台机制对比
转自:http://blog.csdn.net/zsch591488385/article/details/27232881 一.iOS的“伪后台”程序 首先,先了解一下ios 中所谓的「后台进程」到 ...
随机推荐
- 蓝桥杯之K好数
如果一个自然数N的K进制表示中任意的相邻的两位都不是相邻的数字,那么我们就说这个数是K好数.求L位K进制数中K好数的数目.例如K = 4,L = 2的时候,所有K好数为11.13.20.22.30.3 ...
- 呵呵哒,LNMP下通过fread方式下载文件时,中文名称文件找不到文件
哎,整整折腾一个下午. 本来好好的,thinkphp 自动的uniq方式保存的文件名,非要使用原文件名,真心蛋疼~~ 然后就只好写个脚本 把原来的所有文件都重新命名一下 - - 然后把数据库对应字段也 ...
- Halcon算子翻译——assign
名称 assign-为控制变量分配一个新的值 用法 assign( : : Input : Result) 描述 为控制变量分配一个新的值. 在全文编辑器中,只需用:=就可以进行赋值,例如: u : ...
- C#递归查询
一.sql --构造测试数据: 只作演示用 CREATE TABLE [dbo].[Tim_LinqTable]( [Id] int PRIMARY KEY IDENTITY(1,1) NOT NUL ...
- 《项目架构那点儿事》——浅析web层struts2的构建
[前言]所谓快速开发,实质上为了节省项目的开支成本,减少程序员的开发时 间,固然就形成了种种二次封装的框架,也就是造轮子,然后我们的程序就按照这个轮子去画瓢,这里我就把公司这几次开发系统的框架源码贴出 ...
- 教你如何实现微信小程序与.net core应用服务端的无状态身份验证
随着.net core2的发布,越来越多人使用.net core2开发各种应用服务端,下面我就结合自己最近开发的一款小程序,给大家分享下,怎么使用小程序登录后,小程序与服务端交互的权限控制. .net ...
- Ext3和Ext4文件系统区别
inode http://www.cnblogs.com/itech/archive/2012/05/15/2502284.html Ex3使用15个inode查询数据块,前12个为直接数据块,直接指 ...
- 解决弹出蒙层滑动穿透问题-vue
最近开发过程中遇到一些小问题(似乎问题总是那么多),但一直没什么时间去优化与解决.程序员不能被业务绑架,有时间还是花点在代码上
- vim编辑器介绍及其常用命令
vim简单的介绍 Vim 编辑器是一个模式编辑器 . 这意味着在不同状态下编辑器有不同的行为模式 . 两个基本的模式是 Normal 模式和 Insert 模式 ,还有可视模式. 在 Normal 模 ...
- asp.net web api 构建api帮助文档
1 概要 创建ASP.NET Web Api 时模板自带Help Pages框架. 2 问题 1)使用VS创建Web Api项目时,模板将Help Pages框架自动集成到其中,使得Web Api项目 ...