安卓基础学习_ Service

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();
			}
		});
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值