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

时间: 2024-07-30 10:19:40

Android后台执行的定时器实现的相关文章

Android后台运行的定时器实现

Android后台运行定时器,方便我们执行定位跟踪等任务需求. 下面简要说明实现Android后台定时器的要点, 文章末尾可以下载到工程代码,可直接编译执行. AndroidManifest.xml 文件内容如下: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"

android: 后台执行的定时任务

Android 中的定时任务一般有两种实现方式,一种是使用 Java API 里提供的 Timer 类, 一种是使用 Android 的 Alarm 机制.这两种方式在多数情况下都能实现类似的效果,但 Timer 有一个明显的短板,它并不太适用于那些需要长期在后台运行的定时任务.我们都知道,为 了能让电池更加耐用,每种手机都会有自己的休眠策略,Android 手机就会在长时间不操作 的情况下自动让 CPU 进入到睡眠状态,这就有可能导致 Timer 中的定时任务无法正常运行. 而 Alarm 机

android 后台服务定时通知

最近有个项目的要求是在程序退出之后,任然可以每天定时发通知,我们可以想下,其实就是后台开一个服务,然后时间到了就发下通知. 1.首先我们需要用到Service类. 先上代码在慢慢解释 1 package com.example.androidnotification; 2 3 import java.util.Timer; 4 import java.util.TimerTask; 5 import android.app.Notification; 6 import android.app.N

Android后台杀死系列之一:FragmentActivity及PhoneWindow后台杀死处理机制

App在后台久置后,再次从桌面或最近的任务列表唤醒时经常会发生崩溃,这往往是App在后台被系统杀死,再次恢复的时候遇到了问题,而在使用FragmentActivity+Fragment的时候会更加频繁.比如,如果Fragment没有提供默认构造方法,就会在重建的时候因为反射创建Fragment失败而崩溃,再比如,在onCreate里面new 一个FragmentDialog,并且show,被后台杀死后,再次唤醒的时候,就会show两个对话框,这是为什么?其实这就涉及了后台杀死及恢复的机制,其中涉

android后台信息推送调研

android后台信息推送调研 前言 我们已经开发了一个应用,这里称为A应用,类似于天气weather那种.现在的任务就是如果这些A应用有新版本了,或者天气出现比较恶劣的状况,要及时在手机上进行消息的推送,提示有新的应用可以更新了,和天气将要变遭了,提醒用户需要注意的情况.及需要实现消息推送机制. 推送方式基础知识 要获取服务器上不定时更新的信息,一般来说有两种方法:第一种是客户端使用Pull(拉)的方式,就是隔一段时间就去服务器上获取一下信息,看是否有更新的信息出现.第二种就是 服务器使用Pu

android后台服务的基本用法

了解了安卓多线程编程的技术之后,作为安卓的四大组件之一,是十分重要的. 定义一个服务 首先看一下如何在项目中定义一个服务, public class MyService extends Service { @Override public void onCreate() { super.onCreate(); Log.d("myservice","oncreate"); } @Override public int onStartCommand(Intent int

Android初级教程启动定时器详解

本案例知识是:后台执行定时任务. Alarm机制: 一.创建LongRunningService类 package com.example.servicebestpractice; import java.util.Date; import android.app.AlarmManager; import android.app.PendingIntent; import android.app.Service; import android.content.Intent; import and

在Android开发中,定时器一般有以下3种实现方法

在Android开发中,定时器一般有以下3种实现方法: 原文地址http://www.360doc.com/content/12/0619/13/87000_219180978.shtml 一.采用Handler与线程的sleep(long)方法二.采用Handler的postDelayed(Runnable, long)方法三.采用Handler与timer及TimerTask结合的方法 下面逐一介绍: 一.采用Handle与线程的sleep(long)方法 Handler主要用来处理接受到的

android手机执行shell脚本

注意: 1.手机必须root 2.shell脚本需要有执行权限 流程: 1.编写shell脚本 #!/system/bin/sh i=1 while [ $i -le 100 ] do let i++ sleep 2 input swipe 100 950 200 300 150 done 解释:每隔2秒滑屏一次,一共滑动100次(这个脚本比较简单,明白流程后可自行优化) 2.把shell脚本传到/data/目录(/system目录也可以) adb push  D:\test_apk\test.