挑战练习15.6 又一个隐式intent
相较于发送消息,愤怒的用户可能更倾向于直接责问陋习嫌疑人。新增一个按钮,允许用户直接拨打陋习嫌疑人的电话。
要完成这个挑战,首先需要联系人数据库中的手机号码。这需要查询ContactsContract数据库中的CommonDataKinds.Phone表。如何查询,请查看它们的参考文档。
小提示:你应该使用android.permission.READ_CONTACTS权限。利用这个权限,可以查询到ContactsContract.Contacts._ID。然后再使用联系人ID查询CommonDataKinds.Phone表。
搞定了电话号码,就可以使用电话URI创建一个隐式intent:
Uri number = Uri.parse("tel:5551234");
与打电话相关的Intent操作有两种:Intent.ACTION_DIAL和Intent.ACTION_CALL。ACTION_CALL直接调出手机应用并拨打来自intent的电话号码;而ACTION_DIAL则拨好电话号码,然后等用户发起通话。
推荐使用ACTION_DIAL操作。这样的话,用户就有了冷静下来改变主意的机会。这种贴心的设计应该会受到欢迎的。
1.首先在AndroidManifest.xml文件里面添加android.permission.READ_CONTACTS 允许程序读取用户联系人数据
1 <uses-permission android:name="android.permission.READ_CONTACTS"/>
2.在fragment_crime.xml里面添加一个新的按钮用于打电话。
1 <Button 2 android:id="@+id/call_suspect" 3 android:layout_width="match_parent" 4 android:layout_height="wrap_content" 5 android:text="Call Suspect"/>
3.为了持久性存储电话号码,在crime类里面添加新属性以及getter方法和setter方法便于电话号码的保存和赋值。
private String mPhone; public String getmPhone() { return mPhone; } public void setmPhone(String mPhone) { this.mPhone = mPhone; }
4.在CrimeDbSchema里面的内部类Cols里面添加新的字段表示电话
1 public static final String PHONE = "phone";
5.在CrimeBaseHelper的onCreate创建表时添加创建新的列表示电话(记得把模拟器或者手机里面旧的应用卸载了再重新运行安装,不然会报错,旧的表没有新添加的列)
1 @Override 2 public void onCreate(SQLiteDatabase db) { 3 db.execSQL("create table " + CrimeTable.NAME + "(" + 4 " _id integer primary key autoincrement, " + 5 CrimeTable.Cols.UUID + ", " + 6 CrimeTable.Cols.TITLE + ", " + 7 CrimeTable.Cols.DATE + ", " + 8 CrimeTable.Cols.SOLVED + ", " + 9 CrimeTable.Cols.SUSPECT +", " + 10 CrimeTable.Cols.PHONE + 11 ")" 12 ); 13 }
6.修改CrimeCursorWrapper类中的getCrime()方法。
1 public Crime getCrime() { 2 String uuidString = getString(getColumnIndex(CrimeTable.Cols.UUID)); 3 String title = getString(getColumnIndex(CrimeTable.Cols.TITLE)); 4 long date = getLong(getColumnIndex(CrimeTable.Cols.DATE)); 5 int isSolved = getInt(getColumnIndex(CrimeTable.Cols.SOLVED)); 6 String suspect = getString(getColumnIndex(CrimeTable.Cols.SUSPECT)); 7 String phone = getString(getColumnIndex(CrimeTable.Cols.PHONE)); 8 9 Crime crime = new Crime(UUID.fromString(uuidString)); 10 crime.setmTitle(title); 11 crime.setmDate(new Date(date)); 12 crime.setmSolved(isSolved != 0); 13 crime.setSuspect(suspect); 14 crime.setmPhone(phone); 15 16 return crime; 17 }
7.修改CrimeLab类中的getContentValues()方法。
1 private static ContentValues getContentValues(Crime crime) { 2 ContentValues values = new ContentValues(); 3 values.put(CrimeTable.Cols.UUID, crime.getmId().toString()); 4 values.put(CrimeTable.Cols.TITLE, crime.getmTitle()); 5 values.put(CrimeTable.Cols.DATE, crime.getmDate().getTime()); 6 values.put(CrimeTable.Cols.SOLVED, crime.ismSolved() ? 1 : 0); 7 values.put(CrimeTable.Cols.SUSPECT, crime.getSuspect()); 8 values.put(CrimeTable.Cols.PHONE,crime.getmPhone()); 9 10 return values; 11 }
8.在CrimeFragment里面添加全局变量打电话按钮。
1 private Button mCallButton;
9.在CrimeFragment的onCreateView方法里面数据绑定按钮并且添加打电话按钮的点击事件和添加一个if判断当电话不为空时赋值给打电话按钮的文本属性。
1 mCallButton = (Button) v.findViewById(R.id.call_suspect); 2 mCallButton.setOnClickListener(new View.OnClickListener() { 3 @Override 4 public void onClick(View v) { 5 Intent i = new Intent(Intent.ACTION_DIAL); 6 Uri phone = Uri.parse("tel:"+mCrime.getmPhone()); 7 i.setData(phone); 8 startActivity(i); 9 } 10 }); 11 if (mCrime.getmPhone() != null) { 12 mCallButton.setText(mCrime.getmPhone()); 13 }
10.在CrimeFragment里面修改onActivityResult()方法(代码挺长,要修改的地方为高亮处)
1 @Override 2 public void onActivityResult(int requestCode, int resultCode, Intent data) { 3 if (resultCode != Activity.RESULT_OK) { 4 return; 5 } 6 /* 7 Date date = (Date) data.getSerializableExtra(DatePickerFragment.EXTRA_DATE); 8 mCrime.setmDate(date); 9 */ 10 if (requestCode == REQUEST_DATE) { 11 //因为TimePicker不显示年月日,所以不用专门使用updateTime更新TimePicker 12 updateDate(); 13 } 14 else if (requestCode == REQUEST_TIME) { 15 updateTime(); 16 updateDate(); 17 } 18 else if(requestCode ==REQUEST_CONTACT &&data !=null) { 19 Uri contactUri = data.getData(); 20 //这里增加了一个ContactsContract.Contacts._ID 目的是为了得到目标联系人ID 21 String[] queryFields = new String[]{ContactsContract.Contacts.DISPLAY_NAME,ContactsContract.Contacts._ID}; 22 Cursor c = getActivity().getContentResolver().query(contactUri, queryFields, null, null, null); 23 try { 24 if (c.getCount() == 0) { 25 return; 26 } 27 c.moveToFirst(); 28 String suspect = c.getString(0); 29 mCrime.setSuspect(suspect); 30 mSuspectButton.setText(suspect); 31 32 String contactId = c.getString(1); 33 Cursor phone = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, 34 ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId, null, null); 35 if (phone.moveToNext()) { 36 String mPhone = phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); 37 mCrime.setmPhone(mPhone); 38 mCallButton.setText("call:" + mPhone); 39 } 40 } finally { 41 c.close(); 42 } 43 } 44 }
11.运行效果: