Android后台运行的定时器实现

Android后台运行定时器,方便我们执行定位跟踪等任务需求。 下面简要说明实现Android后台定时器的要点, 文章末尾可以下载到工程代码,可直接编译执行。

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-09-29 00:24:07

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

Android后台执行的定时器实现

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

android 后台运行

改写返回键事件监听,使得back键功能类似home键,让Acitivty退至后台时不被系统销毁,代码如下: public boolean onKeyDown(int keyCode, KeyEvent event) { PackageManager pm = getPackageManager(); ResolveInfo homeInfo = pm.resolveActivity(new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGOR

1014-31-首页12-显示weibo未读数--后台运行---定时器

/** *  当app进入后台时调用 */- (void)applicationDidEnterBackground:(UIApplication *)application{    /**     *  app的状态     *  1.死亡状态:没有打开app     *  2.前台运行状态     *  3.后台暂停状态:停止一切动画.定时器.多媒体.联网操作,很难再作其他操作     *  4.后台运行状态     */    // 向操作系统申请后台运行的资格,能维持多久,是不确定的  

Android 应用按返回键退向后台运行

Android应用开发按下返回键退向后台运行 我们日常使用的很多Android应用(如QQ.微信.微博),在应用的主界面按下返回键,应用并没有退出,而是进入后台运行. 那么,开发中是如何实现的呢?我找到了两种方法: 一.监测返回键 1.在Activity中重写onBackPressed()方法. @Override public void onBackPressed() { //此处写退向后台的处理 } 1 2 3 4 1 2 3 4 2.重写onKeyDown()方法(有的应用提示再次点击返回

Android 实现Activity后台运行

有时需要让activity在后台运行,具体实现方法如下: 在AndroidManifest.xml中,activity属性中增加: android:theme="@style/BackgroundOnly"                                    android:configChanges="orientation|keyboardHidden" 增加后如下所示: <activity android:name="Acti

Android 启动后台运行程序(Service)

Android开发中,当需要创建在后台运行的程序的时候,就要使用到Service.Service 可以分为有无限生命和有限生命两种.特别需要注意的是Service跟Activities是不同的(简单来说可以理解为后台与前台的区别),例如,如果需要使用Service的话,需要调用startService(),从而利用startService()去调用Service中的OnCreate()和onStart()方法来启动一个后台的Service.      启动一个Service的过程如下:conte

Android 判断app是否在前台还是在后台运行

Android 判断app是否在前台还是在后台运行,直接看代码,可直接使用. public static boolean isBackground(Context context) { ActivityManager activityManager = (ActivityManager) context .getSystemService(Context.ACTIVITY_SERVICE); List<RunningAppProcessInfo> appProcesses = activity

Android开发教程 不需要关闭后台运行程序

不用在意剩余内存的大小,其实很多人都是把使用其他系统的习惯带过来来了.Android大多应用没有退出的设计其实是有道理的,这和系统对进程的调度机制有关系.如果你知道Java,就能更清楚这机制了.其实和java的垃圾回收机制类似,系统有一个规则来回收内存.进行内存调度有个阀值,只有低于这个值系统才会按一个列表来关闭用户不需要的东西.当然这个值默认设置得很小,所以你会看到内存老在很少的数值徘徊.但事实上他并不影响速度.相反加快了下次启动应用的速度.这本来就是android标榜的优势之一,如果人为去关

android: DOC命令:查看后台运行的activity:

DOC命令:查看后台运行的activity: adb shell dumpsys activity running activity: 模拟器曾经运行过的 activity: