安卓基础学习_ Service
2013-11-25 23:32
375 查看
Android中服务类似windows中的服务,服务一般没有用户界面操作,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序。服务的开发比较简单,如下: 第一步:继承Service类 public class SMSService extends Service{} 第二步:在清单文件中的<application>节点里对服务进行配置 <service android:name=”.SMSService” 服务不能自己运行,需要通过调用Context.startService()或Context.bindService方法启动服务。这两个方法都可以启动服务,但是它们的使用场合不同。 使用startService()方法启动服务,访问者与服务之间没有关联,即使访问者退出了,服务仍然运行。 使用bindService()方法启动服务,访问者和服务绑定在了一起,访问者一旦退出,服务也就终止,大有“不求同时生,但求同时死”的特点。 采用Context.startService()方法启动服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。 一、本地服务 通过startService()和stopService()启动服务。适用于服务与访问者直接没有交互的情况。如果服务和访问者直接需要方法调用或参数传递,则需要使用bindService()和bindService()方法启动关闭服务。 采用Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onBind()方法。这个时候访问者和服务绑定在了一起。如果访问者要与服务进行通信,那么onBind()方法必须返回Ibinder对象。如果访问者退出了,系统就会先调用服务的onUnbind()方法,接着调用onDestroy()方法。如果调用bindService()方法前服务已经被绑定,多次调用bindService()方法并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()方法并不会多次调用)。如果访问者希望与正在绑定的服务解除绑定,可以调用unBindService()方法,调用该方法也会导致系统调用服务的onUnbind()->onDestroy()方法。
public class MainActivity extends Activity { private EditText studentno; private ServiceConnection conn = new StudentServiceConnection(); private IStundent iStundent; private TextView resultView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); resultView = (TextView) this.findViewById(R.id.resultView); studentno = (EditText) this.findViewById(R.id.studentno); Button button = (Button) this.findViewById(R.id.button); button.setOnClickListener(new ButtonClickListener()); Intent service = new Intent(this, StudentService.class); bindService(service, conn, BIND_AUTO_CREATE); } private class StudentServiceConnection implements ServiceConnection { public void onServiceConnected(ComponentName name, IBinder service) { iStundent = (IStundent)service; } public void onServiceDisconnected(ComponentName name) { iStundent = null; } } @Override protected void onDestroy() { unbindService(conn); super.onDestroy(); } private finalclass ButtonClickListener implements View.OnClickListener { public void onClick(View v) { String no = studentno.getText().toString(); String name = iStundent.queryStudent(Integer.valueOf(no)); resultView.setText(name); } } } public interface IStundent { public String queryStudent(int no); } public class StudentService extends Service { private String[] names = {"张飞","李小龙","赵薇"}; private IBinder binder = new StundentBinder(); public String query(int no){ if(no>0 && no<4){ return names[no - 1]; } return null; } public IBinder onBind(Intent intent) { return binder; } private class StundentBinder extends Binder implements Istundent{ public String queryStudent(int no) { return query(no); } } } 二、远程服务 使用AIDL(Android Interface Definition Language)和远程服务实现进程通信 要构建远程服务,执行以下步骤: (1).编写一个AIDL文件来向客户端定义接口。包名与Android项目同。 (2).将AIDL文件添加到Eclipse项目的src目录下。编译器将在gen下自动生成java接口。 (3).实现一个服务并从onBind()方法返回所生成的接口。 (4).将服务配置添加到AndroidManifest.xml文件中。 AIDL语法: (1).AIDL定义接口的源代码必须以.aidl结尾; (2).AIDL接口中用到的数据类型,除了基本类型,String,List,Map,CharSequence之外,其他类型全部都需要导包,即使在同一个包中也需要导包。 StudentQuery.aidl文件(在服务端和客户端都须包含该文件) //AIDL interface StudentQuery { String queryStudent(int number); } 在gen目录下会自动生成StudentQuery.java文件 Service类 public class StudentQueryService extends Service { private String[] names = {"张飞", "李静", "赵薇"}; private IBinder binder = new StudentQueryBinder(); @Override public IBinder onBind(Intent intent) { return binder; } private String query(int number){ if(number > 0 && number < 4){ return names[number - 1]; } return null; } private final class StudentQueryBinder extends StudentQuery.Stub{ public String queryStudent(int number) throws RemoteException { return query(number); } } } //配置文件,隐式意图 <service android:name=".StudentQueryService"> <intent-filter > <action android:name="com.zouyong.student.query"/> </intent-filter> </service> 客户端代码: //采用隐式意图绑定服务 Intent service = new Intent("com.zouyong.student.query"); bindService(service, conn, BIND_AUTO_CREATE); private StudentQuery studentQuery; private StudentConnection conn = new StudentConnection(); public void queryStudent(View v) { String number = numberText.getText().toString(); int num = Integer.valueOf(number); try { resultView.setText(studentQuery.queryStudent(num)); } catch (RemoteException e) { e.printStackTrace(); } } protected void onDestroy() { unbindService(conn); super.onDestroy(); } private final class StudentConnection implements ServiceConnection { public void onServiceConnected(ComponentName name, IBinder service){
// StudentQuery.Stub.asInterface系统生成方法 studentQuery = StudentQuery.Stub.asInterface(service); } public void onServiceDisconnected(ComponentName name) { studentQuery = null; } } 传递复杂数据的AIDL Service(传递的数据类型是自定义类型,需要序列化) Person.aidl文件 parcelable Person; Person.java public class Person implements Parcelable { private Integer id; private String name; private String pass; public Person(){} public Person(Integer id, String name, String pass) { super(); this.id = id; this.name = name; this.pass = pass; } .........//省略setter和getter方法 @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((pass == null) ? 0 : pass.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Person other = (Person) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (pass == null) { if (other.pass != null) return false; } else if (!pass.equals(other.pass)) return false; return true; } // 实现Parcelable接口必须实现的方法 @Override public int describeContents() { return 0; } // 实现Parcelable接口必须实现的方法 @Override public void writeToParcel(Parcel dest, int flags) { //把该对象所包含的数据写到Parcel dest.writeInt(id); dest.writeString(name); dest.writeString(pass); } // 添加一个静态成员,名为CREATOR,该对象实现了Parcelable.Creator接口 public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() //① { @Override public Person createFromParcel(Parcel source) { // 从Parcel中读取数据,返回Person对象 return new Person(source.readInt() , source.readString() , source.readString()); } @Override public Person[] newArray(int size) { return new Person[size]; } }; } Pet.aidl文件 parcelable Pet; Pet.java public class Pet implements Parcelable { private String name; private double weight; public Pet() { } public Pet(String name, double weight) { super(); this.name = name; this.weight = weight; } ........//省略Setter和Getter方法 @Override public int describeContents() { return 0; } /* (non-Javadoc) * @see android.os.Parcelable#writeToParcel(android.os.Parcel, int) */ @Override public void writeToParcel(Parcel dest, int flags) { //把该对象所包含的数据写到Parcel dest.writeString(name); dest.writeDouble(weight); } // 添加一个静态成员,名为CREATOR,该对象实现了Parcelable.Creator接口 public static final Parcelable.Creator<Pet> CREATOR = new Parcelable.Creator<Pet>() { @Override public Pet createFromParcel(Parcel source) { // 从Parcel中读取数据,返回Person对象 return new Pet(source.readString() , source.readDouble()); } @Override public Pet[] newArray(int size) { return new Pet[size]; } }; @Override public String toString() { return "Pet [name=" + name + ", weight=" + weight + "]"; } } IPet.aidl package org.crazyit.service; import org.crazyit.service.Pet; import org.crazyit.service.Person; interface IPet { // 定义一个Person对象作为传入参数 List<Pet> getPets(in Person owner); //in:参数传递方式 } ComplexService.java 服务类 public class ComplexService extends Service { private PetBinder petBinder; private static Map<Person , List<Pet>> pets = new HashMap<Person , List<Pet>>(); static { // 初始化pets Map集合 ArrayList<Pet> list1 = new ArrayList<Pet>(); list1.add(new Pet("旺财" , 4.3)); list1.add(new Pet("来福" , 5.1)); pets.put(new Person(1, "sun" , "sun") , list1); ArrayList<Pet> list2 = new ArrayList<Pet>(); list2.add(new Pet("kitty" , 2.3)); list2.add(new Pet("garfield" , 3.1)); pets.put(new Person(2, "bai" , "bai") , list2); } // 继承Stub,也就是实现额IPet接口,并实现了IBinder接口 public class PetBinder extends Stub { @Override public List<Pet> getPets(Person owner) throws RemoteException { // 返回Service内部的数据 return pets.get(owner); } } @Override public void onCreate() { super.onCreate(); petBinder = new PetBinder(); } @Override public IBinder onBind(Intent arg0) { /* 返回catBinder对象 * 在绑定本地Service的情况下,该catBinder对象会直接 * 传给客户端的ServiceConnection对象 * 的onServiceConnected方法的第二个参数; * 在绑定远程Service的情况下,只将catBinder对象的代理 * 传给客户端的ServiceConnection对象 * 的onServiceConnected方法的第二个参数; */ return petBinder; //① } @Override public void onDestroy() { } } ComplexClient.java 客户端 public class ComplexClient extends Activity { private IPet petService; private Button get; EditText personView; ListView showView; private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name , IBinder service) { // 获取远程Service的onBind方法返回的对象的代理 petService = IPet.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { petService = null; } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); personView = (EditText) findViewById(R.id.person); showView = (ListView) findViewById(R.id.show); get = (Button) findViewById(R.id.get); // 创建所需绑定的Service的Intent Intent intent = new Intent(); intent.setAction("org.crazyit.aidl.action.COMPLEX_SERVICE"); // 绑定远程Service bindService(intent, conn, Service.BIND_AUTO_CREATE); get.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { try { String personName = personView.getText().toString(); // 调用远程Service的方法 List<Pet> pets = petService.getPets(new Person(1, personName, personName)); //① // 将程序返回的List包装成ArrayAdapter ArrayAdapter<Pet> adapter = new ArrayAdapter<Pet>( ComplexClient.this, android.R.layout.simple_list_item_1, pets); showView.setAdapter(adapter); } catch (RemoteException e) { e.printStackTrace(); } } }); } @Override public void onDestroy() { super.onDestroy(); // 解除绑定 this.unbindService(conn); } } 注:在客户端中需要把IPet.aidl, Person.java ,Person.aidl, Pet.java ,Pet.aidl复制过去。 三、IntentService IntentService具有如下特征: (1).IntentService会创建单独的worker来处理所有的Intent请求; (2).IntentService会创建单独的worker线程来处理onHandleIntent()方法实现的代码,无须处理多线程问题; (3).当所有请求处理完成后,会自动停止,无须调用stopSelf()方法来停止Service; (4).为Service的onBind()方法提供了默认的实现,默认实现的onBind()方法返回null; (5).为Service的onStartCommand()方法提供了默认实现,该实现会将请求Intent添加到队列中。 IntentService 实际上是Looper,Handler,Service 的集合体,他不仅有服务的功能,还有处理和循环消息的功能. 不管是何种Service,它默认都是在应用程序的主线程(亦即UI线程)中运行的。所以,如果你的Service将要运行非常耗时或者可能被阻塞的操作时,你的应用程序将会被挂起,甚至会出现ANR错误。为了避免这一问题,你应该在Service中重新启动一个新的线程来进行这些操作。现有两种方法: 1.直接在Service的onStartCommand()方法中重启一个线程来执行 2.使用IntentService 四、服务生命周期 服务的生命周期跟启动服务的方法有关: 1.当采用Context.startService()方法启动服务,与之有关的生命周期方法: onCreate()->onStartCommand()->onDestroy() onCreate():服务被创建时调用,只会被调用一次,无论调用多少次startService()或bindService()方法,服务也只被创建一次。 onStartCommand():只有采用Context.startService()方法启动服务时才会回调该方法。在服务开始运行时被调用,多次调用startService()方法尽管不会多次创建服务,但onStart()会被多次调用。 onDestroy():该方法在服务被终止时调用. 2.当采用Context.bindService()方法启动服务,与之有关的生命周期方法: onCreate()->onBind()->onUnbind()->onDestroy() onBind()::只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务绑定时被调用,当调用者与服务已经绑定,多次调用Context.bindService()方法不会导致该方法被多次调用。 onUnbind()方法:只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务解除绑定时被调用。 3.如果先采用startService()方法启动服务,然后调用bindService()方法绑定服务,再调用unbindService()方法解除绑定,最后调用bindService()方法再次绑定到服务,触发的生命周期方法如下: onCreate()->onStartCommand()->onBind()->onUnbind()[重载后的方法需返回true]->onRebind(); 五、 系统服务 电话管理器(TelephoneyManager) 短信管理器(SmsManager) 音频管理器(AudioManager) 振动器(Vibrator) 手机闹钟服务(AlarmManager) 壁纸管理(WallpaperManager) 获取网络和SIM卡信息 public class TelephonyStatus extends Activity { ListView showView; // 声明代表状态名的数组 String[] statusNames; // 声明代表手机状态的集合 ArrayList<String> statusValues = new ArrayList<String>(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 获取系统的TelephonyManager对象 TelephonyManager tManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); // 获取各种状态名称的数组 statusNames = getResources().getStringArray(R.array.statusNames); // 获取代表SIM卡状态的数组 String[] simState = getResources() .getStringArray(R.array.simState); // 获取代表电话网络类型的数组 String[] phoneType = getResources().getStringArray( R.array.phoneType); // 获取设备编号 statusValues.add(tManager.getDeviceId()); // 获取系统平台的版本 statusValues.add(tManager.getDeviceSoftwareVersion() != null ? tManager.getDeviceSoftwareVersion() : "未知"); // 获取网络运营商代号 statusValues.add(tManager.getNetworkOperator()); // 获取网络运营商名称 statusValues.add(tManager.getNetworkOperatorName()); // 获取手机网络类型 statusValues.add(phoneType[tManager.getPhoneType()]); // 获取设备所在位置 statusValues.add(tManager.getCellLocation() != null ? tManager .getCellLocation().toString() : "未知位置"); // 获取SIM卡的国别 statusValues.add(tManager.getSimCountryIso()); // 获取SIM卡序列号 statusValues.add(tManager.getSimSerialNumber()); // 获取SIM卡状态 statusValues.add(simState[tManager.getSimState()]); // 获得ListView对象 showView = (ListView) findViewById(R.id.show); ArrayList<Map<String, String>> status = new ArrayList<Map<String, String>>(); // 遍历statusValues集合,将statusNames、statusValues // 的数据封装到List<Map<String , String>>集合中 for (int i = 0; i < statusValues.size(); i++) { HashMap<String, String> map = new HashMap<String, String>(); map.put("name", statusNames[i]); map.put("value", statusValues.get(i)); status.add(map); } // 使用SimpleAdapter封装List数据 SimpleAdapter adapter = new SimpleAdapter(this, status, R.layout.line, new String[] { "name", "value" } , new int[] { R.id.name, R.id.value }); // 为ListView设置Adapter showView.setAdapter(adapter); } } 监听手机来电 public class MonitorPhone extends Activity { TelephonyManager tManager; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 取得TelephonyManager对象 tManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); // 创建一个通话状态监听器 PhoneStateListener listener = new PhoneStateListener() { @Override public void onCallStateChanged(int state, String number) { switch (state) { // 无任何状态 case TelephonyManager.CALL_STATE_IDLE: break; case TelephonyManager.CALL_STATE_OFFHOOK: break; // 来电铃响时 case TelephonyManager.CALL_STATE_RINGING: OutputStream os = null; try { os = openFileOutput("phoneList", MODE_APPEND); } catch (FileNotFoundException e) { e.printStackTrace(); } PrintStream ps = new PrintStream(os); // 将来电号码记录到文件中 ps.println(new Date() + " 来电:" + number); ps.close(); break; default: break; } super.onCallStateChanged(state, number); } }; // 监听电话通话状态的改变 tManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE); } } 黑名单来电自动挂断 需要调用系统远程AIDL Service,需要将com.android.internal.telephony包下的Itelephony.aidl和android.telephony包下的NeighboringCellInfo.aidl复制到项目下。 public class BlockMain extends Activity { // 记录黑名单的List ArrayList<String> blockList = new ArrayList<String>(); TelephonyManager tManager; // 监听通话状态的监听器 CustomPhoneCallListener cpListener; public class CustomPhoneCallListener extends PhoneStateListener { @Override public void onCallStateChanged(int state, String number) { switch (state) { case TelephonyManager.CALL_STATE_IDLE: break; case TelephonyManager.CALL_STATE_OFFHOOK: break; // 当电话呼入时 case TelephonyManager.CALL_STATE_RINGING: // 如果该号码属于黑名单 if (isBlock(number)) { System.out.println("~~~挂断电话~~~"); try { Method method = Class.forName( "android.os.ServiceManager") .getMethod("getService" , String.class); // 获取远程TELEPHONY_SERVICE的IBinder对象的代理 IBinder binder = (IBinder) method.invoke(null, new Object[] { TELEPHONY_SERVICE }); // 将IBinder对象的代理转换为ITelephony对象 ITelephony telephony = ITelephony.Stub .asInterface(binder); // 挂断电话 telephony.endCall(); } catch (Exception e) { e.printStackTrace(); } } break; } super.onCallStateChanged(state, number); } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 获取系统的TelephonyManager管理器 tManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); cpListener = new CustomPhoneCallListener(); // 通过TelephonyManager监听通话状态的改变 tManager.listen(cpListener , PhoneStateListener.LISTEN_CALL_STATE); // 获取程序的按钮,并为它的单击事件绑定监听器 findViewById(R.id.managerBlock).setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { // 查询联系人的电话号码 final Cursor cursor = getContentResolver() .query(ContactsContract.CommonDataKinds .Phone.CONTENT_URI, null, null, null, null); BaseAdapter adapter = new BaseAdapter() { @Override public int getCount() { return cursor.getCount(); } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { cursor.moveToPosition(position); CheckBox rb = new CheckBox(BlockMain.this); // 获取联系人的电话号码,并去掉中间的中划线、空格 String number = cursor .getString(cursor.getColumnIndex( ContactsContract.CommonDataKinds .Phone.NUMBER)) .replace("-", "") .replace(" ", ""); rb.setText(number); // 如果该号码已经被加入黑名单、默认勾选该号码 if (isBlock(number)) { rb.setChecked(true); } return rb; } }; // 加载list.xml布局文件对应的View View selectView = getLayoutInflater().inflate( R.layout.list, null); // 获取selectView中的名为list的ListView组件 final ListView listView = (ListView) selectView .findViewById(R.id.list); listView.setAdapter(adapter); new AlertDialog.Builder(BlockMain.this) .setView(selectView) .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick( DialogInterface dialog, int which) { // 清空blockList集合 blockList.clear(); // 遍历listView组件的每个列表项 for (int i = 0; i < listView .getCount(); i++) { CheckBox checkBox = (CheckBox) listView.getChildAt(i); // 如果该列表项被勾选 if (checkBox.isChecked()) { // 添加该列表项的电话号码 blockList.add(checkBox .getText().toString()); } } System.out.println(blockList); } }).show(); } }); } // 判断某个电话号码是否在黑名单之内 public boolean isBlock(String phone) { System.out.println("呼入号码:" + phone); System.out.println("--------" + blockList); for (String s1 : blockList) { if (s1.equals(phone)) { return true; } } return false; } } 发送短信 private final class sendSMSListener implements View.OnClickListener { public void onClick(View v) { String number=mobilenumber.getText().toString(); String content=smscontent.getText().toString(); SmsManager smsManager=SmsManager.getDefault(); ArrayList<String> message=smsManager.divideMessage(content); for(String sms:message) { smsManager.sendTextMessage(number, null, sms, null, null); } Toast.makeText(getApplicationContext(), "Send success", Toast.LENGTH_LONG).show(); } } <uses-permission android:name="android.permission.SEND_SMS"/> 群发短信 public class GroupSend extends Activity { EditText numbers, content; Button select, send; SmsManager sManager; // 记录需要群发的号码列表 ArrayList<String> sendList = new ArrayList<String>(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); sManager = SmsManager.getDefault(); // 获取界面上的文本框、按钮组件 numbers = (EditText) findViewById(R.id.numbers); content = (EditText) findViewById(R.id.content); select = (Button) findViewById(R.id.select); send = (Button) findViewById(R.id.send); // 为send按钮的单击事件绑定监听器 send.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { for (String number : sendList) { // 创建一个PendingIntent对象 PendingIntent pi = PendingIntent.getActivity( GroupSend.this, 0, new Intent(), 0); // 发送短信 sManager.sendTextMessage(number, null, content .getText().toString(), pi, null); } // 提示短信群发完成 Toast.makeText(GroupSend.this, "短信群发完成" , Toast.LENGTH_SHORT).show(); } }); // 为select按钮的单击事件绑定监听器 select.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // 查询联系人的电话号码 final Cursor cursor = getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null); BaseAdapter adapter = new BaseAdapter() { @Override public int getCount() { return cursor.getCount(); } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { cursor.moveToPosition(position); CheckBox rb = new CheckBox(GroupSend.this); // 获取联系人的电话号码,并去掉中间的中划线、空格 String number = cursor .getString(cursor.getColumnIndex(ContactsContract .CommonDataKinds.Phone.NUMBER)) .replace("-", "") .replace(" " , ""); rb.setText(number); // 如果该号码已经被加入发送人名单、默认勾选该号码 if (isChecked(number)) { rb.setChecked(true); } return rb; } }; // 加载list.xml布局文件对应的View View selectView = getLayoutInflater().inflate( R.layout.list, null); // 获取selectView中的名为list的ListView组件 final ListView listView = (ListView) selectView .findViewById(R.id.list); listView.setAdapter(adapter); new AlertDialog.Builder(GroupSend.this) .setView(selectView) .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // 清空sendList集合 sendList.clear(); // 遍历listView组件的每个列表项 for (int i = 0; i < listView.getCount(); i++) { CheckBox checkBox = (CheckBox) listView .getChildAt(i); // 如果该列表项被勾选 if (checkBox.isChecked()) { // 添加该列表项的电话号码 sendList.add(checkBox.getText() .toString()); } } numbers.setText(sendList.toString()); } }).show(); } }); } // 判断某个电话号码是否已在群发范围内 public boolean isChecked(String phone) { for (String s1 : sendList) { if (s1.equals(phone)) { return true; } } return false; } } 音乐播放器 public class AudioTest extends Activity { Button play, up, down; ToggleButton mute; AudioManager aManager; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 获取系统的音频服务 aManager = (AudioManager) getSystemService( Service.AUDIO_SERVICE); // 获取界面中3个按钮和一个ToggleButton控件 play = (Button) findViewById(R.id.play); up = (Button) findViewById(R.id.up); down = (Button) findViewById(R.id.down); mute = (ToggleButton) findViewById(R.id.mute); // 为play按钮的单击事件绑定监听器 play.setOnClickListener(new OnClickListener() { @Override public void onClick(View source) { // 初始化MediaPlayer对象,准备播放音乐 MediaPlayer mPlayer = MediaPlayer.create( AudioTest.this, R.raw.earth); // 设置循环播放 mPlayer.setLooping(true); // 开始播放 mPlayer.start(); } }); up.setOnClickListener(new OnClickListener() { @Override public void onClick(View source) { // 指定调节音乐的音频,增大音量,而且显示音量图形示意 aManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI); } }); down.setOnClickListener(new OnClickListener() { @Override public void onClick(View source) { // 指定调节音乐的音频,降低音量,而且显示音量图形示意 aManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_LOWER, AudioManager.FLAG_SHOW_UI); } }); mute.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton source, boolean isChecked) { // 指定调节音乐的音频,根据isChecked确定是否需要静音 aManager.setStreamMute(AudioManager.STREAM_MUSIC, isChecked); } }); } } 控制手机振动 public class VibratorTest extends Activity { Vibrator vibrator; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 获取系统的Vibrator服务 vibrator = (Vibrator) getSystemService( Service.VIBRATOR_SERVICE); } // 重写onTouchEvent方法,当用户触碰触摸屏时触发该方法 @Override public boolean onTouchEvent(MotionEvent event) { Toast.makeText(this, "手机振动" , Toast.LENGTH_LONG).show(); // 控制手机震动2秒 vibrator.vibrate(2000); return super.onTouchEvent(event); } } 定时自动切换壁纸 public class AlarmChangeWallpaper extends Activity { // 定义AlarmManager对象 AlarmManager aManager; Button start, stop; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); start = (Button) findViewById(R.id.start); stop = (Button) findViewById(R.id.stop); aManager = (AlarmManager) getSystemService( Service.ALARM_SERVICE); // 指定启动ChangeService组件 Intent intent = new Intent(AlarmChangeWallpaper.this, ChangeService.class); // 创建PendingIntent对象 final PendingIntent pi = PendingIntent.getService( AlarmChangeWallpaper.this, 0, intent, 0); start.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // 设置每隔5秒执行pi代表的组件一次 aManager.setRepeating(AlarmManager.RTC_WAKEUP , 0, 5000, pi); start.setEnabled(false); stop.setEnabled(true); Toast.makeText(AlarmChangeWallpaper.this , "壁纸定时更换启动成功啦", Toast.LENGTH_SHORT).show(); } }); stop.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { start.setEnabled(true); stop.setEnabled(false); // 取消对pi的调度 aManager.cancel(pi); } }); } } public class ChangeService extends Service { // 定义定时更换的壁纸资源 int[] wallpapers = new int[]{ R.drawable.shuangta, R.drawable.lijiang, R.drawable.qiao, R.drawable.shui }; // 定义系统的壁纸管理服务 WallpaperManager wManager; // 定义当前所显示的壁纸 int current = 0; @Override public int onStartCommand(Intent intent, int flags, int startId) { // 如果到了最后一张,系统重新开始 if(current >= 4) current = 0; try { // 改变壁纸 wManager.setResource(wallpapers[current++]); } catch (Exception e) { e.printStackTrace(); } return START_STICKY; } @Override public void onCreate() { super.onCreate(); // 初始化WallpaperManager wManager = WallpaperManager.getInstance(this); } @Override public IBinder onBind(Intent intent) { return null; } } 闹钟 public class AlarmActivity extends Activity { MediaPlayer alarmMusic; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 加载指定音乐,并为之创建MediaPlayer对象 alarmMusic = MediaPlayer.create(this, R.raw.alarm); alarmMusic.setLooping(true); // 播放音乐 alarmMusic.start(); // 创建一个对话框 new AlertDialog.Builder(AlarmActivity.this).setTitle("闹钟") .setMessage("闹钟响了,Go!Go!Go!") .setPositiveButton("确定", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // 停止音乐 alarmMusic.stop(); // 结束该Activity AlarmActivity.this.finish(); } }).show(); } } public class AlarmTest extends Activity { Button setTime; AlarmManager aManager; Calendar currentTime = Calendar.getInstance(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 获取程序界面的按钮 setTime = (Button) findViewById(R.id.setTime); // 获取AlarmManager对象 aManager = (AlarmManager) getSystemService( Service.ALARM_SERVICE); // 为“设置闹铃”按钮绑定监听器。 setTime.setOnClickListener(new OnClickListener() { @Override public void onClick(View source) { Calendar currentTime = Calendar.getInstance(); // 创建一个TimePickerDialog实例,并把它显示出来。 new TimePickerDialog(AlarmTest.this, 0, // 绑定监听器 new TimePickerDialog.OnTimeSetListener() { @Override public void onTimeSet(TimePicker tp, int hourOfDay, int minute) { // 指定启动AlarmActivity组件 Intent intent = new Intent(AlarmTest.this, AlarmActivity.class); // 创建PendingIntent对象 PendingIntent pi = PendingIntent.getActivity( AlarmTest.this, 0, intent, 0); Calendar c = Calendar.getInstance(); // 根据用户选择时间来设置Calendar对象 c.set(Calendar.HOUR, hourOfDay); c.set(Calendar.MINUTE, minute); // 设置AlarmManager将在Calendar对应的时间启动指定组件 aManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pi); // 显示闹铃设置成功的提示信息 Toast.makeText(AlarmTest.this, "闹铃设置成功啦" , Toast.LENGTH_SHORT).show(); } }, currentTime.get(Calendar.HOUR_OF_DAY), currentTime .get(Calendar.MINUTE), false).show(); } }); } }
相关文章推荐
- 【转】关于线段树
- Python class 初始化参数为 list 等 可变类型时遇到的问题
- 产品经理(PM)简介
- 隋炀帝的大业
- DRBD--监控篇
- Javascipt 学习笔记
- shell if-elif-elif-fi
- 详细讲解如何用Cocos2dx3.0alpha0搭建跨平台项目,并通过cygwin部署android项目,并在eclipse打开。
- Linux 下编译Android-VLC开源播放器详解(附源码下载)
- 行转列,列转行,decode,case... when ... then ..
- Matlab基本函数-grid、box函数
- qt聊天总结及收获
- SQLite数据库创建及增删改查
- 管理培训生简介
- Mysql MRG_MyISAM引擎分表法
- Magento调试技巧之查看当前页面缓存过的block
- 程序员编程艺术:第一章、左旋转字符串
- Sample 3.1:limits.cpp
- 最新httpclient4.3 两种请求的两种方式
- 最简单却又不容易的内容罗列