Presentation is loading. Please wait.

Presentation is loading. Please wait.

第5章 Android服务(Service)

Similar presentations


Presentation on theme: "第5章 Android服务(Service)"— Presentation transcript:

1 第5章 Android服务(Service)
QQ号: QQ群: (Android编程-清华版) (公共版) 网络资源:

2 主要内容

3 5.1 Service概述 5.1.1 Service介绍 Service是android 系统中的一种组件,它跟Activity的级别差不多,它们都是从Context派生出来的,但是它不能自己运行,只能在后台运行,并且可以和其它组件进行交互。它需要通过某一个Activity或者其他Context对象来调用。 文本

4 5.1.2 启动Service的两种方式 在Android系统中,常采用以下两种方式启动Service.
(1)通过Context的startService()启动service后,访问者与service之间没有关联,该service将一直在后台执行,即使调用startservice的进程结束了,service仍然还存在,直到有进程调用stopService(),或者service自己停止(stopSelf)。这种情况下,service与访问者之间无法进行通信,数据交换,往往用于执行单一操作,并且没有返回结果。例如通过网络上传,下载文件,操作一旦完成,服务应该自动销毁。 (2)通过Context的bindService()绑定Service,绑定后Service就和调用bindService的组件同生共死了。也就是说当调用bindService()的组件销毁了,那么它绑定的Service也要跟着被结束,当然期间也可以调用unbindservice()让Service提前结束。 注意: 一个服务可以与多个组件绑定,只有当所有的组件都与之解绑后,该服务才会被销毁。

5 5.1.2 启动Service的两种方式 以上两种方法可以混合使用,即一个Service既可以启动也可以绑定,只需要同时实现onStartedCommand()(用于启动)和onBind()(用于绑定)方法,那么只有调用stopService(),并且调用unbindService()方法后,该Service才会被销毁。 注意:服务运行在它所在进程的主线程,服务并没有创建它自己的线程,也没有运行在一个独立的进程上(单独指定的除外),这意味着,如果你的服务做一些消耗CPU或者阻塞的操作,你应该在服务中创建一个新的线程去处理。通过使用独立的线程,你就会降低程序出现ANR(Application No Response程序没有响应)的风险,程序的主线程仍然可以保持与用户的交互。

6 5.1.3 Service中常用方法 与开发其它Android组件类似,开发Service组件需要先开发一个Service子类,该类需继承系统提供的Service类,系统中Service类包含的方法主要有: abstract IBinder onBind(Intent intent):该方法是一个抽象方法,所有Service子类必须实现该方法。该方法将返回一个IBinder对象,应用程序可通过该对象与Service组件通信; void onCreate():当Service第一次被创建时,将立即回调该方法; void onDestroy():当Service被关闭之前,将回调该方法; void onStartCommand(Intent intent,int flags,int startId):每次客户端调用startService(Intent intent)方法启动该Service时都会回调onStartCommand()方法; boolean onUnbind(Intent intent):当该Service上绑定的所有客户端都断开连接时将会回调该方法。

7 5.1.3 Service中常用方法 开发Service组件需要先开发一个Service子类,然后在AndroidManifest.xml文件中配置该Service,配置时可通过<intent-filter…/>元素指定它可被哪些Intent启动。 在AndroidManifest.xml文件中配置Service: <service android:name=“.MyService”> <intent-filter> <action android:name=“iet.jxufe.cn.android.MyService”/> </intent-filter> </service> Action中的值一定要与程序中创建的Intent的Action的值一致,程序就是根据Action的值来查找相应的Service从而启动它。

8 5.1.2 Service中常用方法简介 通过Context的startService()启动Service后,访问者与Service之间没有关联,该Service将一直在后台执行,即使调用startService()的进程结束了,Service仍然还存在,直到有进程调用stopService(),或者Service自己自杀(stopSelf())。这种情况下,Service与访问者之间无法进行通信、数据交换。 通过Context的bindService()绑定Service后,Service就和 调用bindService()的组件同生共死了,也就是说当调用 bindService()的组件销毁了,那么它绑定的Service也要跟着被结束。

9 案例:FirstService 定义的Service子类必须实现onBind()方法,然后还需在AndroidManifest.xml文件中对该Service子类进行配置,配置时可通过<intent-filter...>元素指定它可被哪些Intent启动。下面具体来创建一个Service子类并对它进行配置,代码如下。 程序清单:/FirstService/src/iet/jxufe/cn/android/MyService.java public class MyService extends Service { private static final String TAG = "MyService"; public IBinder onBind(Intent arg0) { Log.i(TAG, "MyService onBind invoked!"); return myBinder; } public void onCreate() { Log.i(TAG, "MyService onCreate invoked!"); super.onCreate(); } public void onDestroy() { Log.i(TAG, "MyService onDestroy invoked!"); super.onDestroy(); quit=true; } public int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG, "MyService onStartCommand invoked!"); return super.onStartCommand(intent, flags, startId); } →自定义服务类 →重写OnBind方法 →重写OnCreate方法 →重写OnDestory方法 →重写OnStartCommand方法

10 案例:FirstService 在上述代码中,创建了自定义的MyService类,该类继承了Android.app.Service类,并重写了onBind(),onCreate(),onStartCommand(),onDestory等方法,在每个方法中,通过LOG语句测试和查看该方法是否被调用。 定义完Service之后,还需在项目的AndroidManifest.xml文件中配置该Service,增加配置片段如下。 <service android:name=".MyService"> <intent-filter > <action android:name="iet.jxufe.cn.android.MyService"/> </intent-filter> </service>

11 案例:FirstService 虽然目前MyService已经创建并注册了,但系统仍然不会启动MyService,要想启动这个服务。必须显示地调用startService()方法。如果想停止服务,需要显示地调用stopService()方法,下面代码中,使用Activity作为Service的启动者,分别定义了启动Service和关闭Service两个按钮,并为它们添加了事件处理。 程序清单:/FirstService/src/iet/jxufe/cn/android/MainActivity.java public class MainActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); start=(Button)findViewById(R.id.start); stop=(Button)findViewById(R.id.stop); final Intent intent=new Intent(); intent.setAction("iet.jxufe.cn.android.MyService"); start.setOnClickListener(new OnClickListener() { public void onClick(View v) { startService(intent); } }); stop.setOnClickListener(new OnClickListener() { stopService(intent); } }); } }

12 案例:FirstService 运行本节的例子后,第一次单击【启动Service】按钮后,在DDMS视图下的LogCat视图有如下图所示的输出。 然后单击【关闭Service】按钮,LogCat视图有如下图所示的输出。 下面按如下的单击顺序,重新测试一下本例。 【启动Service】→【启动Service】→【启动Service】→【停止Service】 测试完程序,查看LogCat控制台输出信息如下图所示。系统只在第一次单击【启动Service】按钮时调用onCreate()和onStartCommand()方法,再单击该按钮 时,系统只会调用onStartCommand()方法,而不会重复调用onCreate()方法。

13 5.1.4 绑定Service过程 Context的bindService()方法的完整方法签名为:bindService(Intent service,ServiceConnection conn, int flags),该方法的三个参数解释如下: service:该参数表示与服务类相关联的Intent对象,用于指定所绑定的Service应该符合哪些条件; conn:该参数是一个ServiceConnection对象,该对象用于监听访问者与Service之间的连接情况。当访问者与Service之间连接成功时,将回调该ServiceConnection对象的onServiceConnected(ComponentName name,IBinder service)方法;当访问者与Service之间断开连接时将回调该ServiceConnection对象的onServiceDisconnected(ComponentName name)方法。 flags:指定绑定时是否自动创建Service(如果Service还未创建)。该参数可指定BIND_AUTO_CREATE(自动创建)。

14 5.1.4 绑定Service过程 当开发Service类时,该Service类必须提供一个onBind()方法,在绑定本地Service的情况下,onBind()方法所返回的IBinder对象将会传给ServiceConnection对象里onServiceConnected(ComponentName name,IBinder service)方法的service参数,这样访问者就可以通过IBinder对象与Service进行通信。 实际开发时通常会采用继承Binder(IBinder的实现类)的方式实现自己的IBinder对象。

15 5.1.4 绑定Service案例 在上一个案例中,添加两个按钮,一个用于绑定服务,一个用于解绑,然后分别为其添加事件处理。在绑定服务时,需要传递一个ServiceConnection对象,所以先创建该对象,代码如下。 程序清单:/FirstService/src/iet/jxufe/cn/android/MainActivity.java private ServiceConnection conn=new ServiceConnection() { public void onServiceDisconnected(ComponentName name) { Log.i(TAG,"MainActivity onServiceDisconnected invoked!"); } public void onServiceConnected(ComponentName name, IBinder service) { Log.i(TAG,"MainActivity onServiceConnected invoked!"); myBinder=(MyBinder)service; };

16 5.1.4 (绑定Service案例) 然后在MyService中添加两个与绑定Service相关的方法,onUnBind()和onRebind(),与其他方法类似,只是在方法体重打印出该方法被调用了信息,代码如下。 程序清单:/FirstService/src/iet/jxufe/cn/android/MyService.java public boolean onUnbind(Intent intent) { Log.i(TAG, "MyService onUnbind invoked!"); return super.onUnbind(intent); } public void onRebind(Intent intent) { Log.i(TAG, "MyService onRebind invoked!"); super.onRebind(intent);

17 5.1.4 (绑定Service案例) 最后在MainActivity中为绑定Service和解绑Service按钮添加事件处理,代码如下。
程序清单:/FirstService/src/iet/jxufe/cn/android/MainActivity.java public class MainActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bind=(Button)findViewById(R.id.bind); unbind=(Button)findViewById(R.id.unbind); final Intent intent=new Intent(); intent.setAction("iet.jxufe.cn.android.MyService"); bind.setOnClickListener(new OnClickListener() { public void onClick(View v) { bindService(intent, conn,Service.BIND_AUTO_CREATE); } }); unbind.setOnClickListener(new OnClickListener() { unbindService(conn);

18 5.1.4 (绑定Service案例) 程序执行后,单击绑定Service按钮,LogCat控制台打印信息如下图所示,首先调用onCreate()方法,然后调用onBind()方法。 程序执行后,单击解绑Service按钮,LogCat控制台打印信息如下图所示,首先调用onUnbind()方法,然后调用onDestory()方法。 程序运行后,单击绑定Service按钮,然后退出程序,LogCat控制台打印信息如下图。可以看出,程序退出后,Service会自动退出。

19 5.1.4 (绑定Service案例) 当单击绑定Service按钮后,再重复多次单击绑定Service按钮,查看控制台打印信息,发现程序并不会多次调用onBind()方法。 采用绑定服务的另一个优势是组件可以与Service之间进行通信,传递数据。这主要是通过IBinder对象进行的,因此需在Service中创建一个IBinder对象,然后让其作为onBind()方法的返回值返回,对数据的操作是放在IBinder对象中的。修改我们的MyService类,添加一个内部类MyBinder,同时在onCreate()方法中启动一个线程,模拟后台服务,该线程主要是做数据递增操作,在MyBinder类中,提供一个方法,可以获取当前递增的值(count的值),具体代码如下。 程序清单:/FirstService/src/iet/jxufe/cn/android/MyService.java

20 5.1.4 (绑定Service案例) public class MyService extends Service {
private static final String TAG = "MyService"; private int count=0; private boolean quit=false; private MyBinder myBinder=new MyBinder(); public class MyBinder extends Binder { public MyBinder() { Log.i(TAG, "MyBinder Constructure invoked!"); } public int getCount() { return count; } } public IBinder onBind(Intent arg0) { Log.i(TAG, "MyService onBind invoked!"); return myBinder; } public void onCreate() { Log.i(TAG, "MyService onCreate invoked!"); super.onCreate(); →线程中循环是否停止的标志 →创建自定义的MyBinder对象 →MyBinder的构造方法,观察什么时候创建 →MyBinder中提供的获取数据的方法 →重写onBind()方法, 返回创建的对象

21 5.1.4 (绑定Service案例) new Thread(){ public void run(){ while(!quit){
try{ Thread.sleep(500); count++; System.out.println(); }catch (Exception e) { e.printStackTrace(); } }.start(); public void onDestroy() { Log.i(TAG, "MyService onDestroy invoked!"); super.onDestroy(); quit=true; →判断是否继续执行循环 →休眠0.5秒 →数据递增 →改变循环是否退出的标志,否则子线程一直在循环

22 5.1.4 (绑定Service案例) 接着在MainActivity中添加一个获取数据的按钮,获取数据的前提是要绑定Service,所以先绑定Service,在ServiceConnection()对象的onServiceConnected()方法中,获取绑定Service时,返回的IBinder对象,然后将该对象强制类型转换成MyBinder对象,最后利用MyBinder对象获取服务中的数据信息。 首先改写创建ServiceConnection对象的方法,关键代码如下。 程序清单:/FirstService/src/iet/jxufe/cn/android/MainActivity.java private ServiceConnection conn=new ServiceConnection() { public void onServiceDisconnected(ComponentName name) { Log.i(TAG,"MainActivity onServiceDisconnected invoked!"); } public void onServiceConnected(ComponentName name, IBinder service) { Log.i(TAG,"MainActivity onServiceConnected invoked!"); myBinder=(MyBinder)service; }; →将传递的参数强制类型装换成MyBinder对象

23 5.1.4 (绑定Service案例) 然后,为获取数据按钮添加事件处理方法,关键代码如下。
程序清单:/FirstService/src/iet/jxufe/cn/android/MainActivity.java getData.setOnClickListener(new OnClickListener() { public void onClick(View v) { Toast.makeText(MainActivity.this, "Count="+myBinder.getCount(), Toast.LENGTH_LONG).show(); } }); →以消息的形式,显示获取的数据 此时,单击绑定服务后,LogCat控制台打印信息如下图,首先创建MyBinder对象,因为该对象是作为MyService的成员变量进行创建的,完成MyService的初始化工作,然后再调用onCreate()方法,再调用onBind()方法,该方法返回一个IBinder对象,因为IBinder对象不为空,表示有服务连接,所以会调用ServiceConnection借口的onServiceConnected()方法,并将调用IBinder对象它的第二个参数。

24 案例总结 1、通过Context的startService()方法启动和停止Service
2、通过Context的bindService()方法绑定和解除绑定 3、两种方式混合使用

25 案例总结 问题与讨论 两种方式混合使用时,方法的执行顺序是怎么样的? 1、先启动后绑定 2、先绑定后启动

26 案例总结 1)先启动Service,然后绑定Service。测试步骤:【启动Service】→【绑定Service】→【启动Service】→【停止Service】→【绑定Service】→【解绑Service】。 总结:调用顺序如下:onCreate()→[onStartCommand()1到N次] →onBind()→ onServiceConnected()→onUnbind() [→onServiceConnected()→onRebind()0到N次]→onDestroy()。 控制台信息如下图所示。

27 案例总结 2)先绑定Service,后启动Service。测试步骤:【绑定Service】→【启动Service】→【绑定Service】→【解绑Service】→【启动Service】→【停止Service】。 总结:调用顺序如下:onCreate()→onBind()→onServiceConnected() →[onStartCommand() 1到N次]→onUnBind[→onServiceConnected() →onRebind()0到N次→onUnBind]→onDestroy()。 控制台信息如下图所示。

28 案例总结 注意: (1)未启动Service而直接停止Service不起作用,但未绑定Service而先解绑Service则程序出错,强制退出; (2)若该Service处于绑定状态下,该Service不会被停止即单击停止按钮不起作用,当单击解绑Service按钮时,它会先解除绑定随后直接销毁; (3)若在解除之前,没有单击停止Service,则只解绑而不会销毁。

29 5.1.5 Service的生命周期 每当Service被创建时会回调onCreate()方法,每次Service被启动时都会回调onStartCommand()方法,多次启动一个已有的Service组件将不会再回调onCreate()方法,但每次启动时都会回调onStartCommand()方法。 绑定服务的执行过程: 执行单击事件方法根据Intent找到相应的Service类,并初始化该类调用Service的onCreate()方法调用该类的onBind()方法调用onServiceConnected()方法。 多次单击绑定服务按钮,并不会重复执行绑定方法。一旦解绑,调用onunBind()方法,然后自动销毁。

30 5.2 跨进程调用Service AIDL:Android Interface Definition Language
AIDL是一种接口定义语言,用于约束两个进程间通信规则,供编译器生成代码,实现Android设备上的两个进程间通信(IPC)。 进程之间的通信信息,首先会被转换成AIDL协议消息,然后发送给对方,对方收到AIDL协议消息后再转换成相应的对象。 由于进程之间的通信信息需要双向转换,所以android采用代理类在背后实现了信息的双向转换,代理类由android编译器生成,对开发人员来说是透明的。

31 5.2.1 什么是AIDL服务 客户端访问Service时,Android并不是直接返回Service对象给客户端,Service只是将一个回调对象(IBinder对象)通过onBind()方法回调给客户端。 与绑定本地Service不同的是,本地Service的onBind()方法会直接把IBinder对象本身传给客户端的ServiceConnection的onServiceConnected方法的第二个参数。但远程Service的onBind()方法只是将IBinder对象的代理传给客户端的ServiceConnection的onServiceConnected方法的第二个参数。当客户端获取了远程的Service的IBinder对象的代理之后,接下来可通过该IBinder对象去回调远程Service的属性或方法。

32 5.2.2 建立AIDL文件 AIDL文件创建和java借口定义相类似,但在编写AIDL文件时,需注意: 1.接口名和aidl文件名相同;
2.接口和方法前不用加访问权限修饰符public,private等,也不能用final,static; 3.Aidl默认支持的类型包话java基本类型(int、long、boolean等)和(String、List、Map、CharSequence),使用这些类型时不需要import声明。对于List和Map中的元素类型必须是Aidl支持的类型。如果使用自定义类型作为参数或返回值,自定义类型必须实现Parcelable接口。 4.自定义类型和AIDL生成的其它接口类型在aidl描述文件中,应该显式import,即便在该类和定义的包在同一个包中。 5.在aidl文件中所有非Java基本类型参数必须加上in、out、inout标记,以指明参数是输入参数、输出参数还是输入输出参数。 6.Java原始类型默认的标记为in,不能为其它标记。

33 5.2.2 建立AIDL文件 定义好AIDL接口之后(如Song.aidl),ADT工具会自动在gen目录下生成相应的包,并生成一个song.java接口,在该接口里包含一个Stub内部类,该内部类实现了IBender,Song两个接口,这个Stub类将会作为远Service的回调类。由于它实现了IBinder接口,因此可作为Service的onBind()方法的返回值。 程序清单:/AIDLServer/src/iet/jxufe/cn/android/Song.aidl package iet.jxufe.cn.android; interface Song{ String getName(); String getAuthor(); }

34 5.2.2 建立AIDL文件 AIDL使用时需注意: AIDL定义接口的源代码必须以.aidl结尾;
AIDL接口中用到数据类型,除了基本类型、String、List、Map、CharSequence之外,其他类型全部都需要导包,即使它们在同一个包中也需要导包。 定义好AIDL接口之后(如Song.aidl),ADT工具会自动在gen目录下生成相应的包,并生成一个Song.java接口,在该接口里包含一个Stub内部类,该内部类实现了IBinder、Song两个接口,这个Stub类将会作为远程Service的回调类。它内部能实现一些功能。 开发客户端的第一步就是将Service端的AIDL接口文件复制到客户端应用中,复制到客户端后ADT工具会为AIDL接口生成相应的Java接口类。

35 5.2.3 建立AIDL服务端 远程Service的编写和本地Service很相似,只是远程Service中onBind()方法返回的IBinder对象不同,该Service代码如下。 程序清单:/AIDLServer/src/iet/jxufe/cn/android/AIDLServer.java public class AIDLServer extends Service { private String[] names=new String[]{"老男孩","春天里","在路上"}; private String[] authors=new String[]{"筷子兄弟","汪峰","刘欢"}; private String name,author; private SongBinder songBinder; private Timer timer=new Timer(); public class SongBinder extends Stub { public String getName() throws RemoteException { return name; } public String getAuthor() throws RemoteException { return author;

36 5.2.3 建立AIDL服务端 远程Service的编写和本地Service很相似,只是远程Service中onBind()方法返回的IBinder对象不同,该Service代码如下。 程序清单:/AIDLServer/src/iet/jxufe/cn/android/AIDLServer.java public IBinder onBind(Intent intent) { return songBinder; } public void onCreate() { songBinder=new SongBinder(); timer.schedule(new TimerTask() { public void run() { int rand=(int)(Math.random()*3); name=names[rand]; author=authors[rand]; System.out.println(rand); } }, 0,1000); public void onDestroy() { super.onDestroy(); timer.cancel(); } }

37 5.2.3 建立AIDL服务端 通过上面的程序可以看出,在远程Service中定义了一个SongBinder类,且该类继承Stub类,而Stub类继承了Binder类,并实现了Song接口,Binder类实现了IBinder接口。因此,与本地Service相比,开发远程Service要多定义一个AIDL接口。另外,程序中onBind()方法返回SongBinder类的对象实例,以便客户端获得服务对象,SongBinder对象的创建放在onCreate()方法中,因为onBind()方法在onCreate()方法之后被调用,因此onBind()方法的返回值不会为空。 接下来在AndroidManifest.xml文件中配置该Service类,配置Service类的代码如下: 程序清单:/AIDLServer/AndroidManifest.xml <service android:name=".AIDLServer"> <intent-filter> <action android:name="iet.jxufe.cn.android.AIDLServer"/> </intent-filter> </service>

38 5.2.4 建立AIDL客户端 客户端绑定远程Service与绑定本地Service的区别不大, 同样只需要三步:
1、创建ServiceConnection对象; 2、以ServiceConnection对象作为参数,调用Context的bindService()方法绑定远程Service。 3、将返回的IBinder对象的代理类转换成IBinder对象,从而调用Service中的相应方法。

39 5.2.4 建立AIDL客户端案例 通过一个按钮来获取远程Service的状态,并显示在两个文本框中。

40 5.2.4 建立AIDL客户端案例 public class MainActivity extends Activity {
程序清单:/AIDLClient/src/iet/jxufe/cn/android/client/MainActivity.java public class MainActivity extends Activity { private Button getData; private EditText name,author; private Song songBinder; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getData=(Button)findViewById(R.id.getData); name=(EditText)findViewById(R.id.name); author=(EditText)findViewById(R.id.author); final Intent intent=new Intent(); intent.setAction("iet.jxufe.cn.android.AIDLServer"); bindService(intent, conn, Service.BIND_AUTO_CREATE); getData.setOnClickListener(new OnClickListener() { public void onClick(View v) { try{ name.setText(songBinder.getName()); author.setText(songBinder.getAuthor()); } →用于获取其他进程数据的按钮 →显示获取的数据的文本编辑框 →用户交互的IBinder对象 →根据ID找到相应控件 →根据ID找到相应控件 →根据ID找到相应控件 →创建一个Intent对象 →设置Intent的特征 →绑定Service →添加单击事件处理 →显示获取的数据

41 5.2.4 建立AIDL客户端案例 catch(Exception ex){ ex.printStackTrace(); } });
private ServiceConnection conn=new ServiceConnection() { public void onServiceDisconnected(ComponentName name) { songBinder=null; public void onServiceConnected(ComponentName name, IBinder service) { songBinder=Song.Stub.asInterface(service); }; protected void onDestroy() { super.onDestroy(); unbindService(conn); →创建ServiceConnection对象 →将代理类转换成IBinder对象 →销毁时解绑Service →解绑Service

42 5.3 调用系统服务 在Android系统中提供了很多内置服务类,通过它们提供的系列方法,可以获取系统相关信息。
发送短信需要调用系统的短信服务,主要用到SmsManager管理类,该类可以实现短信的管理功能,通过sendXxxMessage()方法进行短信的发送操作,例如sendTextMessage()方法用于发送文本信息 PendingIntent是对Intent的包装,一般通过调用Pendingintent的getActivity()、getService() 等静态方法来获取PendingIntent对象。与Intent对象不同的是:PendingIntent通常会传给其他应用组件,从而由其他应用程序来执行PendingIntent所包装的“Intent”。

43 5.3 调用系统服务案例 以下程序提供两个文本框,分别输入收信人的号码和发送的短信内容,通过点击“发送短信”按钮即可将短信发送出去。
程序清单:/SendMessage/res/layout/activity_main.xml <LinearLayout xmlns:android=" xmlns:tools=" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="20dp" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="18sp" <EditText android:inputType="number"/>

44 5.3 调用系统服务案例 以下程序提供两个文本框,分别输入收信人的号码和发送的短信内容,通过点击“发送短信”按钮即可将短信发送出去。
程序清单:/SendMessage/res/layout/activity_main.xml <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="18sp" <EditText android:minLines="3"/> <Button android:layout_width="wrap_content" </LinearLayout>

45 5.3 调用系统服务案例 以下程序提供两个文本框,分别输入收信人的号码和发送的短信内容,通过点击“发送短信”按钮即可将短信发送出去。
程序清单:/SendMessage/res/layout/activity_main.xml public class MainActivity extends Activity { EditText num, mess; Button btn; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn = (Button) findViewById(R.id.btn); num = (EditText) findViewById(R.id.num); mess = (EditText) findViewById(R.id.Mess); btn.setOnClickListener(new OnClickListener() { public void onClick(View v) { String mobile=num.getText().toString(); String content=mess.getText().toString(); SmsManager smsManager = SmsManager.getDefault();

46 5.3 调用系统服务案例 以下程序提供两个文本框,分别输入收信人的号码和发送的短信内容,通过点击“发送短信”按钮即可将短信发送出去。
程序清单:/SendMessage/res/layout/activity_main.xml PendingIntent sentIntent = PendingIntent.getActivity( MainActivity.this, 0, new Intent(), 0); List<String> msgs = smsManager.divideMessage(content); for (String msg : msgs) { smsManager.sendTextMessage(mobile, null, msg sentIntent,null); } Toast.makeText(MainActivity.this, "短信发送完成!", Toast.LENGTH_SHORT).show(); });

47


Download ppt "第5章 Android服务(Service)"

Similar presentations


Ads by Google