7月 242015
 

  在Android4.0之前,服务是可以在开机时自动运行的,但是在Android4.0以后,为了安全起见,防止一些非法的后台服务在开机后自动运行,用户必须打开一个Activity后才可以启动服务。

  那么我们想想,如果我们不是做一些非法的操作是否可以有其他的变通方法解决这个问题呢。

  如果是要更新桌面小组件的数据,那么我们可以在小组件服务创建时启动数据更新服务,如下:

 *
Android4.0之前设置服务开机自启动的方法

  首先AndroidManifest.xml中加入

  创建用于接收RECEIVE_BOOT_COMPLETED广播的BroadcastReceiver类

  在AndroidManifest.xml中声明这个receiver类

  BOOT_COMPLETED:当系统启动完成时发送这个广播
  QUICKBOOT_POWERON:HTC的一些手机有快速启动,这个action是针对快速启动情况的
  ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:这个action是针对程序安装到sd卡的时候,sd卡上的应用加载完成时发送此广播

7月 232015
 

话不多说,先上代码:

首先在AndroidManifest.xml中申请WakeLock权限

然后在你需要保持系统一直运行的地方写下面的代码:

原理:

PowerManager,手机的电源管理相关组件。 WakeLock,用于程序控制是否一直保持手机运行状态组件。WakeLock的保持运行共包括四个类型,最好使用比较低的级别,以降低手机电池的使用量。

Flag值 CPU 屏幕 键盘
PARTIAL_WAKE_LOCK On* Off Off
SCREEN_DIM_WAKE_LOCK On Dim Off
SCREEN_BRIGHT_WAKE_LOCK On Bright Off
FULL_WAKE_LOCK On Bright Bright

所有的类型CPU都是保持运行,屏幕和键盘分为关闭、暗光、亮光三个级别,我们经常用的应该是PARTIAL_WAKE_LOCK,保持CPU运行就行了。

在服务类中的使用

对于编写的android服务,在手机锁屏休眠后,服务也可能会停止运行,我们可以使用此方法让服务保持运行,但代码写法和上面稍有不同。如下:

http://svn1.bcoder.com

 

6月 092014
 

Windows服务作为Windows提供的一种特殊应用程序,拥有下面优点:

1. 随系统启动而启动,不需要用户手动执行,适合做后台检测程序等
2. 不用登录系统即可运行
3. 在后台运行,不与Windows桌面相互影响
4. 拥有System权限,在任务管理器中无法结束运行

Windows不建议在服务程序中与桌面有交互,在Windows Xp及以前的版本Windows服务和用户桌面还运行在一个session下,所以服务程序还可以比较轻松的与桌面进行交互。但是自Windows Vista及以后的系统中,服务程序是运行于session0中,而第一个启动的用户则运行于session1中,要想在服务中显示桌面或者与桌面程序交互要使用很复杂的技术,甚至用CreateProcess和ShellExecute启动的应用程序都无法在用户桌面中显示。

一、在Delphi中创建Windows服务程序

Delphi中提供了创建Windows服务的程序框架,生成Windows服务工程的具体方法如下,点击菜单File->New->Other,在里面寻找Service Application项目,点击OK按钮生成即可。这里会生成一个带界面的TService1类。选中TService1界面,下面介绍一下TService的相关属性和事件。

TService属性:

  • AllowPause: 是否允许暂停
  • AllowStop: 是否允许停止
  • Dependencies: 设置该服务与其他服务的依赖关系
  • DisplayName: 在Windows服务管理器中显示的名称(注意:不是服务名)
  • Name: 服务名称,使用/install参数安装时安装的服务名为此属性值
  • Interactive: 是否要与桌面进行交互
  • StartType: 服务的启动方式
  • ServiceStartName: 设定用于启动服务的用户名

TService事件:

1. procedure TService1.ServiceStart(Sender: TService; var Started: Boolean);
在该服务启动的时候调用OnStart事件,参数Started的默认为True,所以不用在该事件中再设置Started := True; 在此事件中如果判断某些条件不允许服务运行,则可以将Started置为False,这样服务将会不再启动。
2. procedure TService1.ServiceStop(Sender: TService; var Stopped: Boolean);
在该服务被停止的时候调用OnStop事件,Stopped的默认为True,在此事件中如果判断某些条件不允许服务停止则可将Stopped置为False来防止服务被停止。
3. procedure TService1.ServiceExecute(Sender: TService);
服务的主体执行部分,需要将服务的主要功能实现代码放在此事件中,此过程执行完毕后服务将会自动停止,所以一般在此事件中要写类似如下代码:

4.procedure TService1.ServicePause(Sender: TService; var Paused: Boolean);
在服务被暂停时调用的事件,Paused的含义类似ServiceStart事件中的Started.
5. procedure TService1.ServiceContinue(Sender: TService; var Continued: Boolean);
服务被暂停后重新启动继续执行时调用的事件,Continued的含义类似ServiceStart事件中的Started

经过简单的点击后,一个最基本的Windows服务程序已经编写完成了,编译工程,将会生成一个exe程序,本例中生成一个ServiceTest.exe。
打开命令行窗口,将目录定位到工程的输出目录,输入ServiceTest.exe /install并执行,刚才编写的服务就安装到系统中了。
卸载服务时使用ServiceTest.exe /unstall
可以在命令行后面加/silent参数,使其不弹出安装、卸载成功的提示框。
注意:使用/install这种方式安装时,服务的名字是服务窗口的类名,不是DisplayName,服务管理器中显示的是DisplayName
也可使用Windows自带的sc命令来创建或者删除服务,创建的示例代码如下:

二、一些很有用的管理服务的函数

调用方法:

{启动服务} StartServices(服务名);
{停止服务} StopServices(服务名);
{新建服务} CreateServices(服务名,exe文件路径);
{删除服务} DeleteServices(服务名);
{获取服务状态} string:=QueryServiceStatu(服务名);

注意这里的服务名是Service类的名称,不是DisplayName

三、Delphi中编写Windows服务的注意事项

1. 尽量避免使用ShowMessage等直接进行调试,容易造成服务无法响应等问题。
2. 停止服务时提示”Windows无法停止 xxx 服务(位于 本地计算机 上)” ,则可能是OnStop事件结束时将Stopped设置成了False或者OnExecute事件不能结束或者OnExecute与界面进行了不正确的交互。
3. Windows Vista及上版本的系统中不再支持服务中显示窗口,所以在这些版本的系统上,如果需要显示窗口,则要另外创建一个窗口程序,并与之用消息通讯以显示窗口。

四、一些有用的链接

Subverting Vista UAC in Both 32 and 64 bit Architectures
http://www.codeproject.com/Articles/35773/Subverting-Vista-UAC-in-Both-and-bit-Archite

如何在Windows Service里面运行程序
http://blog.sina.com.cn/s/blog_5f8817250100vooy.html

8月 082012
 

1、为什么要使用service?

在我们开发的应用中,有的时候需要做一些长期运行的任务,比如下载文件、音乐播放器、闹钟或者邮件程序等。由于Android系统会根据系统资源使用情况自动清理闲置的后台程序,所以普通的Activity程序在运行一段时间后就有可能被系统清理掉,不能达到长期运行的效果。而包含service的进程属于优先权比较高的(关于进程的生命周期相关知识请点击这里查看)不容易被系统清理掉,所以对那些应用来说,选择service是必要的。

2、创建一个Service

在工程节点或者包节点上右键,选择”New->Class”,输入包名,类名称,SuperClass输入或者选择android.app.Service,点击ok,创建一个服务类成功,创建完成后初始化代码如下:

创建完成后还无法使用此服务,需要在AndroidManifestXml中声明该服务类,示例如下:

3、服务类的一些重要方法

getApplication()

Return the application that owns this service.
onBind(Intent intent)

Return the communication channel to the service.
onConfigurationChanged(Configuration newConfig)

Called by the system when the device configuration changes while your component is running.
onCreate()

Called by the system when the service is first created.
onDestroy()

Called by the system to notify a Service that it is no longer used and is being removed.
onLowMemory()

This is called when the overall system is running low on memory, and actively running processes should trim their memory usage.
onRebind(Intent intent)

Called when new clients have connected to the service, after it had previously been notified that all had disconnected in itsonUnbind(Intent).
onStart(Intent intent, int startId)

This method was deprecated in API level 5. Implement onStartCommand(Intent, int, int) instead.
onStartCommand(Intent intent, int flags, int startId)

Called by the system every time a client explicitly starts the service by calling startService(Intent), providing the arguments it supplied and a unique integer token representing the start request.
onTaskRemoved(Intent rootIntent)

This is called if the service is currently running and the user has removed a task that comes from the service’s application.
onTrimMemory(int level)

Called when the operating system has determined that it is a good time for a process to trim unneeded memory from its process.
onUnbind(Intent intent)

Called when all clients have disconnected from a particular interface published by the service.
startForeground(int id, Notification notification)

Make this service run in the foreground, supplying the ongoing notification to be shown to the user while in this state.
stopForeground(boolean removeNotification)

Remove this service from foreground state, allowing it to be killed if more memory is needed.
stopSelf()

Stop the service, if it was previously started.
stopSelf(int startId)

Old version of stopSelfResult(int) that doesn’t return a result.
stopSelfResult(int startId)

Stop the service if the most recent time it was started was startId.

4、Service的调用方法

Service可能通过两种方法启动,一种是通过startService另外一种是通过bindService

1) startServie的声明如下:public abstract ComponentName startService (Intent service)

参数说明:service是你要启动的服务对象,通过Intent构造,你可以在Intent对象中加入其他需要的参数,以在服务中使用。执行此函数后,如果服务未启动则系统会创建此服务并执行,如果执行此函数时服务已经在运行,则服务会继续执行。

每次调用startService时都会触发服务内的android.app.Service.onStartCommand方法,此机制提供一个方便的方法通过Intent参数传入一些需要的参数,以避免必须再使用BindService才能实现的功能。

终止由startService启动的服务方法:一种是可以在服务内部调用stopSelf()来停止服务,另一种是在调用startService的context中通过调用stopService来终止

2) bindService声明如下:public abstract boolean bindService (Intent service, ServiceConnection conn, int flags)

参数说明:
service: 是要绑定的服务的实例标识,
conn: 用于接收成功绑定或者结束绑定时的通知,在连接时可以接收service返回的对象,
flags: 为绑定选项,可能为0, BIND_AUTO_CREATE, BIND_DEBUG_UNBIND, BIND_NOT_FOREGROUND, BIND_ABOVE_CLIENT, BIND_ALLOW_OOM_MANAGEMENT, BIND_WAIVE_PRIORITY.

对于由startService启动的服务,也可以使用此函数进行绑定。如果服务没有启动,可以设置flags为BIND_AUTO_CREATE,这样执行此函数时服务会被自动创建。

只有当调用该服务存在的时候系统才认为该服务有必须继续执行代码,比如当调用该服务的Activity停止或者销毁后它绑定的服务也会停止工作。所以在执行长期操作的时候不要在bindService中执行,即不要在Service的onbind函数中启动相应的定时器,否则当activity结束后,该定时器也会不再执行工作,而应该先用startService启动服务,并在服务的onStartCommand中执行定时器操作。

 

注意:

1、在使用一个service前必须在AndroidManifest.xml中定义该服务类名称,如:<service android:name=”Em8CheckerService”></service>