android高德macs,Xamarin.Forms读取并展示Android和iOS通讯录 - TerminalMACS客户端

using Acr.UserDialogs;

using Android;

using Android.App;

using Android.Content;

using Android.Content.PM;

using Android.Database;

using Android.Provider;

using Android.Runtime;

using Android.Support.V4.App;

using Plugin.CurrentActivity;

using System ;

using System .Collections.Generic;

using System .IO;

using System .Linq;

using System .Threading;

using System .Threading.Tasks;

using TerminalMACS.Clients.App.Models;

using TerminalMACS.Clients.App.Services;

namespace TerminalMACS.Clients.App.Droid.Services

{

///

/// 通讯录获取服务

///

public class ContactsService : IContactsService

{

const string ThumbnailPrefix = "thumb" ;

bool stopLoad = false ;

static TaskCompletionSource< bool > contactPermissionTcs;

public string TAG

{

get

{

return "MainActivity" ;

}

}

bool _isLoading = false ;

public bool IsLoading => _isLoading;

//权限请求状态码

public const int RequestContacts = 1239 ;

///

/// 获取通讯录需要的请求权限

///

static string [ ] PermissionsContact = {

Manifest.Permission.ReadContacts

} ;

public event EventHandler OnContactLoaded;

///

/// 异步请求通讯录权限

///

async void RequestContactsPermissions ( )

{

//检查是否可以弹出申请读、写通讯录权限

if ( ActivityCompat. ShouldShowRequestPermissionRationale ( CrossCurrentActivity.Current.Activity, Manifest.Permission.ReadContacts )

|| ActivityCompat. ShouldShowRequestPermissionRationale ( CrossCurrentActivity.Current.Activity, Manifest.Permission.WriteContacts ) )

{

// 如果未授予许可,请向用户提供其他理由用户将从使用权限的附加上下文中受益。

// 例如,如果请求先前被拒绝。

await UserDialogs.Instance. AlertAsync ( "通讯录权限" , "此操作需要“通讯录”权限" , "确定" ) ;

}

else

{

// 尚未授予通讯录权限。直接请求这些权限。

ActivityCompat. RequestPermissions ( CrossCurrentActivity.Current.Activity, PermissionsContact, RequestContacts ) ;

}

}

///

/// 收到用户响应请求权限操作后的结果

///

///

///

///

public static void OnRequestPermissionsResult ( int requestCode, string [ ] permissions, [ GeneratedEnum ] Android.Content.PM.Permission [ ] grantResults )

{

if ( requestCode == RequestContacts )

{

// 我们请求了多个通讯录权限,因此需要检查相关的所有权限

if ( PermissionUtil. VerifyPermissions ( grantResults ) )

{

// 已授予所有必需的权限,显示联系人片段。

contactPermissionTcs. TrySetResult ( true ) ;

}

else

{

contactPermissionTcs. TrySetResult ( false ) ;

}

}

}

///

/// 异步请求权限

///

///

public async Task< bool > RequestPermissionAsync ( )

{

contactPermissionTcs = new TaskCompletionSource< bool > ( ) ;

// 验证是否已授予所有必需的通讯录权限。

if ( Android.Support.V4.Content.ContextCompat. CheckSelfPermission ( CrossCurrentActivity.Current.Activity, Manifest.Permission.ReadContacts ) != ( int ) Permission.Granted

|| Android.Support.V4.Content.ContextCompat. CheckSelfPermission ( CrossCurrentActivity.Current.Activity, Manifest.Permission.WriteContacts ) != ( int ) Permission.Granted )

{

// 尚未授予通讯录权限。

RequestContactsPermissions ( ) ;

}

else

{

// 已授予通讯录权限。

contactPermissionTcs. TrySetResult ( true ) ;

}

return await contactPermissionTcs.Task;

}

///

/// 异步请求通讯录,此方法由界面真正调用

///

///

///

public async Task> RetrieveContactsAsync ( CancellationToken? cancelToken = null )

{

stopLoad = false ;

if ( !cancelToken.HasValue )

cancelToken = CancellationToken.None;

// 我们创建了一个十进制的TaskCompletionSource

var taskCompletionSource = new TaskCompletionSource> ( ) ;

// 在cancellationToken中注册lambda

cancelToken.Value. Register ( ( ) =>

{

// 我们收到一条取消消息,取消TaskCompletionSource.Task

stopLoad = true ;

taskCompletionSource. TrySetCanceled ( ) ;

} ) ;

_isLoading = true ;

var task = LoadContactsAsync ( ) ;

// 等待两个任务中的第一个任务完成

var completedTask = await Task. WhenAny ( task, taskCompletionSource.Task ) ;

_isLoading = false ;

return await completedTask;

}

///

/// 异步加载通讯录,具体的通讯录读取方法

///

///

async Task> LoadContactsAsync ( )

{

IList contacts = new List ( ) ;

var hasPermission = await RequestPermissionAsync ( ) ;

if ( !hasPermission )

{

return contacts;

}

var uri = ContactsContract.Contacts.ContentUri;

var ctx = Application.Context;

await Task. Run ( ( ) =>

{

// 暂时只请求通讯录Id、DisplayName、PhotoThumbnailUri,可以扩展

var cursor = ctx.ApplicationContext.ContentResolver. Query ( uri, new string [ ]

{

ContactsContract.Contacts.InterfaceConsts.Id,

ContactsContract.Contacts.InterfaceConsts.DisplayName,

ContactsContract.Contacts.InterfaceConsts.PhotoThumbnailUri

} , null , null , $ "{ContactsContract.Contacts.InterfaceConsts.DisplayName} ASC" ) ;

if ( cursor.Count > 0 )

{

while ( cursor. MoveToNext ( ) )

{

var contact = CreateContact ( cursor, ctx ) ;

if ( ! string . IsNullOrWhiteSpace ( contact.Name ) )

{

// 读取出一条,即通知界面展示

OnContactLoaded?. Invoke ( this , new ContactEventArgs ( contact ) ) ;

contacts. Add ( contact ) ;

}

if ( stopLoad )

break ;

}

}

} ) ;

return contacts;

}

///

/// 读取一条通讯录数据

///

///

///

///

Contact CreateContact ( ICursor cursor, Context ctx )

{

var contactId = GetString ( cursor, ContactsContract.Contacts.InterfaceConsts.Id ) ;

var numbers = GetNumbers ( ctx, contactId ) ;

var emails = GetEmails ( ctx, contactId ) ;

var uri = GetString ( cursor, ContactsContract.Contacts.InterfaceConsts.PhotoThumbnailUri ) ;

string path = null ;

if ( ! string . IsNullOrEmpty ( uri ) )

{

try

{

using ( var stream = Android.App.Application.Context.ContentResolver. OpenInputStream ( Android.Net.Uri. Parse ( uri ) ) )

{

path = Path. Combine ( Path. GetTempPath ( ) , $ "{ThumbnailPrefix}-{Guid.NewGuid}" ) ;

using ( var fstream = new FileStream ( path, FileMode.Create ) )

{

stream. CopyTo ( fstream ) ;

fstream. Close ( ) ;

}

stream. Close ( ) ;

}

}

catch ( Exception ex )

{

System .Diagnostics.Debug. WriteLine ( ex ) ;

}

}

var contact = new Contact

{

Name = GetString ( cursor, ContactsContract.Contacts.InterfaceConsts.DisplayName ) ,

Emails = emails,

Image = path,

PhoneNumbers = numbers,

} ;

return contact;

}

///

/// 读取联系人电话号码

///

///

///

///

string [ ] GetNumbers ( Context ctx, string contactId )

{

var key = ContactsContract.CommonDataKinds.Phone.Number;

var cursor = ctx.ApplicationContext.ContentResolver. Query (

ContactsContract.CommonDataKinds.Phone.ContentUri,

null ,

ContactsContract.CommonDataKinds.Phone.InterfaceConsts.ContactId + " = ?" ,

new [ ] { contactId } ,

null

) ;

return ReadCursorItems ( cursor, key ) ?. ToArray ( ) ;

}

///

/// 读取联系人邮箱地址

///

///

///

///

string [ ] GetEmails ( Context ctx, string contactId )

{

var key = ContactsContract.CommonDataKinds.Email.InterfaceConsts.Data;

var cursor = ctx.ApplicationContext.ContentResolver. Query (

ContactsContract.CommonDataKinds.Email.ContentUri,

null ,

ContactsContract.CommonDataKinds.Email.InterfaceConsts.ContactId + " = ?" ,

new [ ] { contactId } ,

null ) ;

return ReadCursorItems ( cursor, key ) ?. ToArray ( ) ;

}

IEnumerable< string > ReadCursorItems ( ICursor cursor, string key )

{

while ( cursor. MoveToNext ( ) )

{

var value = GetString ( cursor, key ) ;

yield return value;

}

cursor. Close ( ) ;

}

string GetString ( ICursor cursor, string key )

{

return cursor. GetString ( cursor. GetColumnIndex ( key ) ) ;

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值