編輯:關於Android編程
一、簡介
本節演示如何在安卓系統中通過用戶配置文件(user profile)讀取和更新該手機的所有聯系人信息,以及如何導航到用戶配置文件中的這些聯系人。
二、基本概念
1、什麼是 User Profile
用戶配置文件(user profile)保存的是機主信息以及該手機中所有聯系人的信息。
假定手機所有者的名字為“Mao mao yu”,那麼,user profile保存的就是“Mao mao yu”的通訊錄(即機主所有聯系人的姓名、電話、郵箱、……等信息)。在Android 4中,這個保存聯系人信息的應用程序稱為“People app”,而在Android 5.0及更高版本中,這個應用程序又改稱為“Contacts app” 。
Android 6.0(API 23)模擬器已經包含了【通訊錄】功能,利用它可直接手工添加手機所有者姓名及其聯系人,如下圖所示:
單擊【通訊錄】中的某個聯系人,例如單擊機主的名字(或者其他聯系人的名字),就可以在顯示的界面中修改這個人的姓名、電話、郵箱、住址等信息,或者添加新聯系人,這個功能大家在手機上用的太熟了,這裡就不多說了。
我們這一節的目標就是學習如何在自己的應用程序中通過代碼去添加或修改這個用戶配置文件(user profile)中的信息,而不是用它自身提供的功能去編輯。
2、權限要求
要在你的程序中讀和寫手機所有聯系人的數據,你的應用程序必須具有Read_Contacts和Write_Contacts權限。另外,要讀取和編輯用戶配置文件(user profile),你的應用程序必須具有Read_Profile和Write_Profile權限。
或者說,必須具有下面的權限才能讀寫通訊錄和機主的用戶配置文件:
READ_CONTACTS
READ_PROFILE
WRITE_CONTACTS
WRITE_PROFILE
實際上,你手機上下載的各類應用程序,只要有對應的權限,都可以獲取和修改你的通訊錄(一般手機用戶都不是搞計算機的,因此也不太關心什麼權限不權限,直接按下一步點下去,結果是默認都給這些程序賦予了完全的讀寫權限)。或者說,只要你給這些應用程序賦予了對應的讀寫權限,那麼你的通訊錄實際上就沒有一點安全可言了,這些程序想什麼時候獲取就可以什麼時候獲取(洩露出去真是太簡單了),這也是為什麼有那麼多免費的手機應用拼命讓你去下載和使用的原因。
下圖是在VS2015中設置Read_Contacts和Read_Profile的辦法(通過單擊主菜單【項目】下的【屬性】彈出此界面):
按照同樣的辦法,可繼續設置WRITE_CONTACTS和WRITE_PROFILE權限。
3、獲取通訊錄信息(Reading Profile Data)
安卓早期的版本是通過ContactContracts.Contacts類來獲取手機上所有聯系人的列表信息的。從Android 4開始又提供了一個新的ContactsContact.Profile類,該類提供了對設備所有者用戶配置文件(user profile)的訪問,利用它即可獲取和修改所有聯系人的名稱、電話號碼等數據。
向 ContactsContact.Profile.ContentUri 發出查詢即可讀取配置文件的數據。例如,下面的代碼讀取該用戶配置文件的顯示名稱:
var uri = ContactsContract.Contacts.ContentUri; string[] projection = { ContactsContract.Contacts.InterfaceConsts.DisplayName }; var cursor = ContentResolver.Query(uri, projection, null, null, null); if (cursor.MoveToFirst ()) { Console.WriteLine(cursor.GetString (cursor.GetColumnIndex (projection [0]))); }
4、更新聯系人信息(Update the User's Profile)
應用程序只要有對應的讀寫權限,就可以像其他普通的應用程序一樣與用戶配置文件(user profile)中的數據進行交互。例如,調用ContentResolver.Update方法可更新配置文件中的顯示名稱,該方法通過ContactsContract.Profile.ContentRawContactsUri屬性檢索Uri,如下面的代碼所示:
var values = new ContentValues (); values.Put (ContactsContract.Contacts.InterfaceConsts.DisplayName, "Mao mao yu"); ContentResolver.Update (ContactsContract.Profile.ContentRawContactsUri,values, null, null);
注意:不能顯式創建用戶配置文件(user's profiile),否則將出現異常。
接下來,可創建一個ReadBackName方法,如下面的代碼所示。調用此方法可驗證添加到用戶配置文件的名稱是否確實被更新了。在這個方法中,首先獲取用戶的配置文件的 URI 並配置投影,從此配置文件中僅僅讀取一列 (用戶的顯示名稱)。為了訪問用戶的配置文件數據,接下來創建了一個游標對象。如果成功地初始化游標,則它被移動到用戶配置文件中的第一項。在此位置 (用戶顯示名稱) 的第一列中讀取名稱並將其打印到控制台。如果這些操作成功,ReadBackName 返回 true;否則返回 false。
bool ReadBackName() { Android.Net.Uri uri = ContactsContract.Profile.ContentUri; string[] projection = { ContactsContract.Contacts.InterfaceConsts.DisplayName }; var cursor = ContentResolver.Query(uri, projection, null, null, null); if (cursor != null) { if (cursor.MoveToFirst()) { Console.WriteLine(cursor.GetString(cursor.GetColumnIndex(projection[0]))); return true; } } return false; }
添加一個ViewProfile方法,該方法會自動調用Contacts App顯示user profile中的信息:
void ViewProfile () { Intent intent = new Intent (Intent.ActionView, ContactsContract.Profile.ContentUri); StartActivity (intent); }
注意:僅在Android 4及更高版本中才可以使用手機所有者的用戶配置文件。另外,在用戶配置文件可以更新之前,必須先手動創建聯系人。
關於ContactContracts.Profile 的更多信息,請參見 ContactsContract.Profile 類。
三、示例—ch1204ReadContacts
本示例演示如何獲取通訊錄中的聯系人。
1、運行截圖
單擊【讀取通訊錄】按鈕,即得到下面右側的截圖。
單擊【修改機主信息】按鈕,即得到下面的修改界面:
下圖是在Android 4.4.2(API 19)下運行的結果:
2、主要設計步驟
(1)設置權限
在VS2015開發環境下,選擇主菜單的【項目】à【ContactsDemo屬性】,在彈出的窗口中勾選下面的權限:
READ_CONTACTS
READ_PROFILE
WRITE_CONTACTS
WRITE_PROFILE
或者在【解決方案資源管理器】中,鼠標雙擊項目的【Properties】進入設置界面,然後勾選上面的選項。
設置完畢後,在AndroidManifest.xml文件中就會自動添加下面的代碼:
<uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.READ_PROFILE" /> <uses-permission android:name="android.permission.WRITE_CONTACTS" /> <uses-permission android:name="android.permission.WRITE_PROFILE" />
(2)添加改ch1204_Main.axml文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:background="@android:color/background_light" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:text="讀取通訊錄" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/btnRead" /> <Button android:text="修改機主信息" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/btnUpdate" /> </LinearLayout>
(3)添加ch1204_ContactListItem.axml文件
在Resources/layout/下添加該文件。
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="15dip" />
(4)添加ch1204ReadContactActivity.cs文件
using System.Collections.Generic; using Android.App; using Android.Content; using Android.OS; using Android.Widget; using Android.Provider; namespace MyDemos.SrcDemos { [Activity(Label = "【例12-4】讀取和更新通訊錄")] public class ch1204ReadContactActivity : ListActivity { protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); var uri = ContactsContract.Contacts.ContentUri; string[] projection = { ContactsContract.Contacts.InterfaceConsts.Id, ContactsContract.Contacts.InterfaceConsts.DisplayName }; var cursor = ContentResolver.Query(uri, projection, null, null, null); var contactList = new List<string>(); if (cursor.MoveToFirst()) { do { contactList.Add(cursor.GetString(cursor.GetColumnIndex(projection[1]))); } while (cursor.MoveToNext()); } cuesor.Close(); ListAdapter = new ArrayAdapter<string>(this, Resource.Layout.ch1204_ContactListItem, contactList); } } }
注意該類繼承自ListActivity,不是繼承自Activity。
(5)添加ch1204ReadContactsMain.cs文件
using Android.App; using Android.Content; using Android.OS; using Android.Widget; using Android.Provider; namespace MyDemos.SrcDemos { [Activity(Label = "【例12-4】讀取和更新通訊錄")] public class ch1204ReadContactsMain : Activity { protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); SetContentView(Resource.Layout.ch1204_Main); var btnRead = FindViewById<Button>(Resource.Id.btnRead); btnRead.Click += delegate { StartActivity(typeof(ch1204ReadContactActivity)); }; var btnUpdate = FindViewById<Button>(Resource.Id.btnUpdate); btnUpdate.Click += delegate { NameOwner(); if (ReadBackName()) { Intent intent = new Intent(Intent.ActionView, ContactsContract.Profile.ContentUri); StartActivity(intent); } }; } /// <summary> /// 定義手機機主的名字 /// </summary> void NameOwner() { ContentValues values = new ContentValues(); //將“Rainmj”插入到已存在的user profile中 values.Put(ContactsContract.Contacts.InterfaceConsts.DisplayName, "Rainmj"); //更新user profile ContentResolver.Update(ContactsContract.Profile.ContentRawContactsUri, values, null, null); } /// <summary> /// 檢查“更新user profile”是否成功 /// </summary> /// <returns></returns> bool ReadBackName() { //獲取user profile的Uri Android.Net.Uri uri = ContactsContract.Profile.ContentUri; //配置投影,指定准備從user profile中讀取的列 string[] projection = { ContactsContract.Contacts.InterfaceConsts.DisplayName }; var cursor = ContentResolver.Query(uri, projection, null, null, null); if (cursor != null) { if (cursor.MoveToFirst()) { cursor.Close(); //Console.WriteLine(cursor.GetString(cursor.GetColumnIndex(projection[0]))); return true; } } return false; } } }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。
readme:1、這個demo中沒有對多次點擊同一個聲音文件做詳細處理,偶爾會有崩潰,用的時候需要注意。2、按住錄音按鈕錄音過程中,只對豎直方向處理了一下,水平方向沒寫;
/** * @param path 文件保存路徑 * @param data 保存數據 * */ public static void writeImage
在上篇文章給大家介紹深入淺析Android Fragment(上篇),包括一些基本的用法和各種API,如果還想深入學習請繼續關注本篇文章。本篇將介紹上篇提到的:如何管理F
The APK file does not exist on disk.Error while Installing APK解決方案:Android Studio獲取SH