Android后台运行定时器,方便我们执行定位跟踪等任务需求。 下面简要说明实现Android后台定时器的要点, 文章末尾可以下载到工程代码,可直接编译执行。
AndroidManifest.xml 文件内容如下:
其中关键的代码是赋予项目 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;
}
}
};
}
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 类里进行接收,并处理。
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 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();
}
}
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);
}
}