Android切近實戰(zhàn)(八)

天冷了,老夫要把伙食搞上去,這不最近在軟件園二樓吃,伙食15塊,杠杠的。

創(chuàng)新互聯(lián)公司是一家專注于成都做網(wǎng)站、網(wǎng)站建設(shè)與策劃設(shè)計,橋西網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)十余年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:橋西等地區(qū)。橋西做網(wǎng)站價格咨詢:18982081108

Android切近實戰(zhàn)(八)

Android切近實戰(zhàn)(八)

美包包,不說了,進入正題。今天老夫要講的是讀取聯(lián)系人,其實我做這個的初衷是想做一個短信攔截,電話攔截的功能。

我們先看一下界面,還是不錯的,挺絢麗的。

Android切近實戰(zhàn)(八)

OK,我們一看就知道,這又是一個ListView。目前的功能是當(dāng)你在復(fù)選框打鉤,點擊后面的撥號就會將電話打出去。如果不打鉤,電話則不會撥出去。OK,我們先看看頁面布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="match_parent" android:layout_height="match_parent"
	android:orientation="vertical">
	<ListView android:id="@+id/contactListView" 
		android:descendantFocusability="blocksDescendants"
		android:layout_width="fill_parent"
		android:layout_height="fill_parent"
		android:divider="@color/teal"
		android:dividerHeight="1dp">
	</ListView>
	<LinearLayout 
		android:orientation="horizontal"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content">
		<Button android:id="@+id/btnSelAll"
			android:text="@string/btnSelAll"
			android:textColor="@color/teal"
			android:textSize="14dp"
			android:textStyle="bold"
			android:layout_weight="1"
			android:layout_width="fill_parent"
			android:layout_height="fill_parent"></Button>
		<Button android:id="@+id/btnInverseSel"
			android:text="@string/btnSelInverse"
			android:textColor="@color/teal"
			android:layout_marginLeft="1dp"
			android:layout_weight="1"
			android:textSize="14dp"
			android:textStyle="bold"
			android:layout_width="fill_parent"
			android:layout_height="fill_parent"></Button>
		<Button android:id="@+id/btnSet"
			android:text="@string/btnSet"
			android:layout_weight="1"
			android:textColor="@color/teal"
			android:layout_marginLeft="1dp"
			android:textSize="14dp"
			android:textStyle="bold"
			android:layout_width="fill_parent"
			android:layout_height="fill_parent"></Button>
	</LinearLayout>
</LinearLayout>

我們再看看ListView要加載的模版

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent" android:layout_height="wrap_content"
	android:id="@+id/contactTemplate">
	<TableLayout android:id="@+id/tabContatMain"
		android:layout_width="fill_parent" android:layout_height="wrap_content"
		android:stretchColumns="2" android:shrinkColumns="2" android:padding="3dip">
		<TableRow>
			<CheckBox android:id="@+id/chkContactUser" 
				android:layout_gravity="center_vertical"></CheckBox>
			<ImageView android:id="@+id/imgContactPhoto"
				android:layout_gravity="center_vertical" 
				android:scaleType="fitCenter"></ImageView>
			<TextView android:id="@+id/txtContactName"
				android:layout_marginLeft="10dp" 
				android:layout_gravity="center_vertical"
				android:textColor="@color/teal1"></TextView>
			<TextView android:id="@+id/txtContactTelNumber"
				android:layout_marginLeft="4dp" 
				android:gravity="right"
				android:layout_gravity="center_vertical" 
				android:textColor="@color/yellow"></TextView>
			<Button android:id="@+id/btnDail" 
				android:text="@string/btnDail"
				android:textSize="10dp"
				android:layout_marginLeft="10dp" 
				android:width="60dp"
				android:drawableRight="@drawable/dail"
				android:layout_gravity="center_vertical" 
				android:textColor="@color/purplered"></Button>
		</TableRow>
	</TableLayout>
</LinearLayout>

依然是TableLayout布局,我們設(shè)置它的收縮列為第二列,伸展列也是第二列。這樣如果第二列不夠顯示則會收縮。OK,我們看一下后臺代碼

public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.punchinalarm);
		
		owner = this;
		btnSelAll = (Button) this.findViewById(R.id.btnSelAll);
		btnSelInverse = (Button) this.findViewById(R.id.btnInverseSel);
		btnSet = (Button) this.findViewById(R.id.btnSet);
		contactUserListView = (ListView) this
				.findViewById(R.id.contactListView);
		
		dataList = new ArrayList<Map<String, Object>>();
		this.InitData();
	}

在OnCreate方法中,我們初始化數(shù)據(jù)。

private void InitData() {
		String phoneUserName = null;
		String phoneNumber = null;
		Long contactId = null;
		Long photoId = null;
		Map<String, Object> dataMap = null;

		ContentResolver resolver = this.getApplicationContext()
				.getContentResolver();

		/*
		 * 獲取Sim卡聯(lián)系人 Uri uri = Uri.parse("content://icc/adn");
		 */
		Cursor phoneCursor = resolver.query(Phone.CONTENT_URI,
				PHONE_PROJECTION, null, null, null);

		if (phoneCursor != null) {
			while (phoneCursor.moveToNext()) {
				dataMap = new HashMap<String, Object>();
				phoneUserName = phoneCursor.getString(0);
				phoneNumber = phoneCursor.getString(1);
				photoId = phoneCursor.getLong(2);
				contactId = phoneCursor.getLong(3);

				if (phoneNumber == null || phoneNumber.trim().length() < 11) {
					continue;
				}

				Bitmap contactPhoto = null;
				if (photoId > 0) {
					Uri uri = ContentUris.withAppendedId(
							ContactsContract.Contacts.CONTENT_URI, contactId);
					InputStream input = ContactsContract.Contacts
							.openContactPhotoInputStream(resolver, uri);
					contactPhoto = BitmapFactory.decodeStream(input);
				} else {
					contactPhoto = BitmapFactory.decodeResource(getResources(),
							R.drawable.usersmall);
				}

				dataMap.put("UserName", phoneUserName);
				dataMap.put("UserPhoneNumber", phoneNumber);
				dataMap.put("UserPhoto", contactPhoto);
				dataList.add(dataMap);
			}

			if (dataList != null && dataList.size() > 0) {
				customAdapter simpleAdapter = new customAdapter(this, dataList,
						R.layout.contactdetailtemplate, new String[] {
								"UserPhoto", "UserName", "UserPhoneNumber" },
						new int[] { R.id.chkContactUser, R.id.imgContactPhoto,
								R.id.txtContactName, R.id.txtContactTelNumber,
								R.id.btnDail });

				this.contactUserListView.setAdapter(simpleAdapter);
			}
		}
	}

我們知道外界的程序通過ContentResolver接口可以訪問ContentProvider提供的數(shù)據(jù),在Activity當(dāng)中通過getContentResolver()可以得到當(dāng)前應(yīng)用的 ContentResolver實例。因為通訊錄和短消息都可以通過接口訪問,所以我們就可以通過getContentResolver訪問SIM卡和手機中的聯(lián)系人信息。

我們主要到下面的這句

Cursor phoneCursor = resolver.query(Phone.CONTENT_URI,
				PHONE_PROJECTION, null, null, null);

通過接口查詢,我們會得到一個Cursor。通過查看Cursor的定義,我們發(fā)現(xiàn)它是個抽象類

public abstract interface android.database.Cursor

我們發(fā)現(xiàn)它提供了一些方法,如下

Android切近實戰(zhàn)(八)

由此可見,它是一個既可以前進又可以后退的無向游標(biāo),類似于SqlServer中的游標(biāo)。這樣的話我們不論是讀取聯(lián)系人信息,還是讀取短消息,都可以隨時定位游標(biāo)。

在上面我們看到Query的幾個參數(shù),Phone.Content_URI,獲取聯(lián)系人的時候需要去這個URI去取數(shù)據(jù)。其實這里的Phone.Content_URI的值是content://com.android.contacts/contacts。它的定義如下

 public static final android.net.Uri CONTENT_URI;

ok,我們拿到聯(lián)系人之后,我們進行循環(huán),游標(biāo)下移,拿出所有的有電話號碼的聯(lián)系人的數(shù)據(jù)。因為我們傳入的PHONE_PROJECTION的順序是姓名,電話號碼,照片ID,以及一個ContactID。所以我們看到取數(shù)據(jù)的順序如下

phoneUserName = phoneCursor.getString(0);
				phoneNumber = phoneCursor.getString(1);
				photoId = phoneCursor.getLong(2);
				contactId = phoneCursor.getLong(3);

拿到PhotoID之后,我們判斷是否大于0,如果大于0,我們會獲取用戶圖像。

獲取用戶圖像的時候,先通過下面的代碼將URI和參數(shù)連接起來

ContentUris.withAppendedId(
							ContactsContract.Contacts.CONTENT_URI, contactId)

其實這個類似于Get方式的API,比如ContactUser/100,意思是獲取編號為100的人的信息。

OK,URI構(gòu)造好之后,我們獲取圖像

InputStream input = ContactsContract.Contacts
							.openContactPhotoInputStream(resolver, uri);
					contactPhoto = BitmapFactory.decodeStream(input);

最后加入List<Map<String,Object>>,對ListView運用適配器。

class customAdapter extends BaseAdapter {
		private List<Map<String, Object>> dataList;
		private LayoutInflater mInflater;
		private Context context;
		private String[] keyString;
		private int[] valueViewID;
		Holder holder;

		public customAdapter(Context context,
				List<Map<String, Object>> dataList, int resource,
				String[] from, int[] to) {
			this.dataList = dataList;
			this.context = context;
			mInflater = (LayoutInflater) this.context
					.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			keyString = new String[from.length];
			valueViewID = new int[to.length];
			System.arraycopy(from, 0, keyString, 0, from.length);
			System.arraycopy(to, 0, valueViewID, 0, to.length);
		}

		@Override
		public int getCount() {
			return dataList.size();
		}

		@Override
		public Object getItem(int position) {
			return dataList.get(position);
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		public void removeItem(int position) {
			dataList.remove(position);
			this.notifyDataSetChanged();
		}

		public View getView(int position, View convertView, ViewGroup parent) {

			if (convertView != null) {
				holder = (Holder) convertView.getTag();
			} else {
				convertView = mInflater.inflate(R.layout.contactdetailtemplate,
						null);
				holder = new Holder();
				holder.chkContactUser = (CheckBox) convertView
						.findViewById(valueViewID[0]);
				holder.imgUserPhoto = (ImageView) convertView
						.findViewById(valueViewID[1]);
				holder.labUserName = (TextView) convertView
						.findViewById(valueViewID[2]);
				holder.labPhoneNumber = (TextView) convertView
						.findViewById(valueViewID[3]);
				holder.btnDail = (Button) convertView
						.findViewById(valueViewID[4]);

				convertView.setTag(holder);
			}

			Map<String, Object> appInfo = dataList.get(position);
			if (appInfo != null) {
				String userName = appInfo.get(keyString[1]).toString();
				String userPhoneNumber = appInfo.get(keyString[2]) == null ? ""
						: appInfo.get(keyString[2]).toString();
				Bitmap userPhoto = (Bitmap) appInfo.get(keyString[0]);

				holder.labUserName.setText(userName);
				holder.labPhoneNumber.setText(userPhoneNumber);
				holder.imgUserPhoto.setImageBitmap(userPhoto);
				holder.btnDail.setOnClickListener(new ViewButtonListener(
						position, holder.chkContactUser));
			}
			return convertView;
		}
	}

	class Holder {
		public TextView labUserName;
		public TextView labPhoneNumber;
		public ImageView imgUserPhoto;
		public Button btnDail;
		public CheckBox chkContactUser;
	}

這里,其實很簡單,我們就是拿到控件,然后根據(jù)Position,拿到List中的某行數(shù)據(jù),然后賦值。

最后我們看看按鈕的Click事件,我們傳入了Position和每行的CheckBox。

class ViewButtonListener implements OnClickListener {
		private int position;
		Object phoneNumber;
		CheckBox chkContactUser;

		ViewButtonListener(int position,CheckBox chkContactUser) {
			this.position = position;
			this.phoneNumber = dataList.get(position).get("UserPhoneNumber");
			this.chkContactUser= chkContactUser;
		}

		@Override
		public void onClick(View view) {
			int vid = view.getId();
			if (vid == R.id.btnDail&&chkContactUser.isChecked()) {
				Intent dialIntent = new Intent(Intent.ACTION_CALL, Uri
						.parse("tel:" + phoneNumber));
				startActivity(dialIntent);
			}
		}
	}

在OnClick中,我們判斷如果是撥號按鈕并且列頭的CheckBox是勾選的,則會撥號,否則不會撥號。OK,最后我們希望在按回退鍵的時候,彈出是否退出的提示

Android切近實戰(zhàn)(八)

ok,代碼如下

public boolean onKeyDown(int keyCode, KeyEvent event) {
		if ((keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0)) {
			dialog();
			return true;
		}
		return true;
	}

	protected void dialog() {
		AlertDialog.Builder builder = new Builder(punchinalarm.this);
		builder.setMessage("確定要退出嗎?");
		builder.setTitle("提示");
		builder.setPositiveButton("確認(rèn)", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
				android.os.Process.killProcess(android.os.Process.myPid());
			}
		});
		builder.setNegativeButton("取消",
				new android.content.DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
					}
				});
		builder.create().show();
	}

最后,哥們的博客是貨真價實,小米3測試機。

Android切近實戰(zhàn)(八)Android切近實戰(zhàn)(八)

新聞標(biāo)題:Android切近實戰(zhàn)(八)
分享網(wǎng)址:http://bm7419.com/article8/igocip.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設(shè)計、微信小程序網(wǎng)站策劃、網(wǎng)站設(shè)計、軟件開發(fā)用戶體驗

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)