如何在BeeWare中访问手机通讯录并实现一键拨号功能?
在BeeWare中实现通讯录读取与拨号功能
一、BeeWare原生实现方案
BeeWare的Toga框架没有直接封装通讯录和拨号的系统API,但可以通过Android平台的原生模块直接调用系统能力:
1. 读取通讯录
首先在项目的AndroidManifest.xml里添加读取权限:
<uses-permission android:name="android.permission.READ_CONTACTS" />
然后在Python代码中请求权限并拉取联系人数据:
from android import Android def fetch_contacts(): droid = Android() # 请求通讯录读取权限 droid.requestPermission("android.permission.READ_CONTACTS") # 查询联系人的姓名和手机号 raw_contacts = droid.queryContent( "content://contacts/people", ["display_name", "phone_number"] ).result # 过滤掉无手机号的联系人,整理成Python列表 cleaned_contacts = [] for item in raw_contacts: if item.get("phone_number"): cleaned_contacts.append({ "name": item["display_name"], "phone": item["phone_number"] }) return cleaned_contacts
2. 触发拨号功能
同样用Android模块调用系统拨号界面:
def initiate_call(phone_number): from android import Android droid = Android() # 打开系统拨号界面(需用户确认后拨打) droid.startActivity("android.intent.action.DIAL", data=f"tel:{phone_number}")
要是想直接拨打电话(跳过确认界面),得添加
CALL_PHONE权限,把ACTION_DIAL改成ACTION_CALL,不过高版本Android需要用户手动授予特殊权限。
二、Java扩展与Python交互方案
如果原生模块满足不了需求,可以写Java工具类集成到BeeWare项目,再通过Python调用:
1. 编写Java工具类
在BeeWare Android项目的android/app/src/main/java/com/yourproject/路径下创建ContactHelper.java(替换成你的项目包名):
package com.yourproject; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.provider.ContactsContract; import android.database.Cursor; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class ContactHelper { private Context appContext; public ContactHelper(Context context) { this.appContext = context; } // 获取所有带手机号的联系人 public List<Map<String, String>> getContacts() { List<Map<String, String>> contactList = new ArrayList<>(); Cursor cursor = appContext.getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, new String[]{ ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER }, null, null, null ); if (cursor != null) { while (cursor.moveToNext()) { String name = cursor.getString(0); String phone = cursor.getString(1); Map<String, String> contact = new HashMap<>(); contact.put("name", name); contact.put("phone", phone); contactList.add(contact); } cursor.close(); } return contactList; } // 调用系统拨号 public void makeCall(String phoneNumber) { Intent dialIntent = new Intent(Intent.ACTION_DIAL); dialIntent.setData(Uri.parse("tel:" + phoneNumber)); appContext.startActivity(dialIntent); } }
2. Python中调用Java代码
BeeWare默认集成了pyjnius,可以直接调用Java类:
from jnius import autoclass from android import AndroidActivity def get_contacts_from_java(): # 获取当前App的Activity上下文 MainActivity = autoclass("org.beeware.android.MainActivity") current_activity = MainActivity.mActivity # 实例化Java工具类 ContactHelper = autoclass("com.yourproject.ContactHelper") helper = ContactHelper(current_activity) # 调用Java方法获取联系人 java_contacts = helper.getContacts() # 转换为Python可处理的列表 py_contacts = [] for idx in range(java_contacts.size()): contact_map = java_contacts.get(idx) py_contacts.append({ "name": contact_map.get("name"), "phone": contact_map.get("phone") }) return py_contacts def call_via_java(phone_number): MainActivity = autoclass("org.beeware.android.MainActivity") current_activity = MainActivity.mActivity ContactHelper = autoclass("com.yourproject.ContactHelper") helper = ContactHelper(current_activity) helper.makeCall(phone_number)
3. 配置权限
别忘了在AndroidManifest.xml里添加权限:
<uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.CALL_PHONE" />
内容的提问来源于stack exchange,提问作者Amir Mohammad Dehghan
相关产品推荐
相关产品推荐

