安卓手机如何打开微信摄像头权限

人气:324 ℃/2023-01-03 04:09:02

安卓手机如何打开微信摄像头权限呢?现在就来给朋友们详细介绍一下。

第一步:首先我们需要通过手机菜单栏进入到“设置”功能选项,也就是那个灰色齿轮的图标,点击进入就行了。

第二步:当你进到设置功能以后往下拉动,就可以看见一个“安全”的选择项,点击进入即可。

第三步:在安全的设置功能界面中可以看见一个“应用权限”选择,点击进入。

第四步:进入到应用权限之后找到摄像头的权限选择,因为不同牌子的手机可能名称不同,总之有摄像头这三个字的就是了。

第五步:因为我们是要设置微信的摄像头权限,所以需要挑选“手机微信”来进行设置。

第六步:最终在微信摄像头那里启用“允许”,按钮变绿了就表示你的微信摄像头权限已经开启。

安卓手机如何打开.M文件

Android摸索记录--获取android联系人

既然要做提醒、通知类的app,首先想尝试的就是支持自己手机通讯录的生日提醒。

这里说的android联系人,指的是存储在安卓手机google账户下面的联系人,而不是存储在本机或者某个国产手机系统的联系人。

android联系人概况

联系人的数据大致分为16类,分别是

存储地址

所有 android 联系信息都保存在 SQLite 数据库中。 数据库文件位于 /data/data/com.android.providers.contacts/databases/contacts2.db。 我们可以使用 android模拟器上查看上述数据库文件。 如果无法打开上述文件夹,请在 dos 或 shell 窗口中运行 adb root shell 命令。

adb devicesadb shellsusqlite3 /data/data/com.android.providers.contactsdatabases/contacts2.db

select * from sqlite_master where type="table"; // 我们可以先查看这个数据库里面有哪些表,太多了select * from sqlite_master where type="table" and name = "data"; // 查看data表的结构

我们可以看到当时这个表是这么创建的

CREATE TABLE data ( _id INTEGER PRIMARY KEY AUTOINCREMENT, package_id INTEGER REFERENCES package(_id), mimetype_id INTEGER REFERENCES mimetype(_id) NOT NULL, raw_contact_id INTEGER REFERENCES raw_contacts(_id) NOT NULL, hash_id TEXT, is_read_only INTEGER NOT NULL DEFAULT 0, is_primary INTEGER NOT NULL DEFAULT 0, is_super_primary INTEGER NOT NULL DEFAULT 0, data_version INTEGER NOT NULL DEFAULT 0, data1 TEXT,data2 TEXT,data3 TEXT,data4 TEXT,data5 TEXT,data6 TEXT,data7 TEXT,data8 TEXT,data9 TEXT,data10 TEXT,data11 TEXT,data12 TEXT,data13 TEXT,data14 TEXT,data15 TEXT, data_sync1 TEXT, data_sync2 TEXT, data_sync3 TEXT, data_sync4 TEXT, carrier_presence INTEGER NOT NULL DEFAULT 0, preferred_phone_account_component_name TEXT, preferred_phone_account_id TEXT)

其中有data1 ~ data15,data_sync1 ~ data_sync4

其实对于我们常用的就是mimetype_id、raw_contact_id 、data1 、data2、data3,数据的类型就是mimetype_id,数据的内容就是data1,而data2、data3则是用来辅助data1,如果mimetype_id对应的是电话号码这组数据,data1就是电话号码,而data2就是电话类型(比如手机,座机)、data3就是自定义的电话类型(比如data2中的分类都不满足,你自定义的紧急电话类型) 数据库中的几个我们能用的表都是依靠相同的raw_contact_id 连接起来的。

select * from sqlite_master where type="table" and name = "mimetypes"; // 查看data表的结构

该表是这么创建的

CREATE TABLE mimetypes ( _id INTEGER PRIMARY KEY AUTOINCREMENT, mimetype TEXT NOT NULL)

举个例子

select _id, raw_contact_id,mimetype_id, data1, data2, data3 from data order by _id desc limit 20;

红框中的1267就是一个raw_contact_id ,可以看到这里的6条记录都是我们Test这个联系人的数据: 第一行mimetype_id为5,可以看出是手机号码 第四行mimetype_id为7,可以看出是名字 第六行mimetype_id为13,可以看出是事件,这里存档是日期,根据后面的data2为3可以区分出是生日。 其它的几个是空的,对应的可以根据上面的mimetypes找到对应的含义。

实战

知道了数据的存储结构了,我们就可以开始查询了

我们可用一个fragment来展示联系人列表数据,fragment同时继承接口LoaderManager.LoaderCallbacks<cursor>

lateinit var contactsList: ListView// Defines a variable for the search stringprivate val searchString: String = ""private var lookupKey: String = ""// An adapter that binds the result cursor to the ListViewprivate var cursorAdapter: SimpleCursorAdapter? = nullprivate val detailSelectionArgs = arrayOf<String>("")private val selectionArgs = arrayOf<String>(searchString)// 联系人姓名兼容老版本private val DISPLAY_NAME: String = if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)) { ContactsContract.Contacts.DISPLAY_NAME_PRIMARY} else { ContactsContract.Contacts.DISPLAY_NAME}// 类似于mysql select 对应的数据列private val PROJECTION: Array<out String> = arrayOf( ContactsContract.Contacts._ID, ContactsContract.Contacts.LOOKUP_KEY, DISPLAY_NAME, ContactsContract.Contacts.Data.DATA1)// 类似于mysql的where语句private val SELECTION: String = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) "${ContactsContract.Contacts.DISPLAY_NAME_PRIMARY} LIKE ?" else "${ContactsContract.Contacts.DISPLAY_NAME} LIKE ?"// cursor数据对应列private val FROM_COLUMNS: Array<String> = arrayOf( DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.Contacts._ID)// cursor数据对应列对应的展示位置IDprivate val TO_IDS: IntArray = intArrayOf(R.id.msgTime, R.id.msgTitle, R.id.msgBody)private var DETAIL_SELECTION: String = ContactsContract.Data.LOOKUP_KEY " = ? AND " ContactsContract.Data.MIMETYPE " IN ('" ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE "', '" ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE "', '" ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE "', '" ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE "')"private val DETAIL_PROJECTION: Array<out String> = arrayOf( ContactsContract.Contacts.Data._ID, ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.Contacts.Data.MIMETYPE, ContactsContract.Contacts.Data.DATA1, ContactsContract.Contacts.Data.DATA2, ContactsContract.Contacts.Data.DATA3,)

override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { _binding = FragmentContactListBinding.inflate(inflater, container, false) val root: View = binding.root contactsList = root.findViewById(R.id.contact_list) textView = root.findViewById(R.id.contact_list_text) textView?.text = "loading..." self = this// initDataFromMock(); activity?.also { // Gets a CursorAdapter cursorAdapter = SimpleCursorAdapter( it, R.layout.msg_item, // ListView对应的layout xml文件 null, FROM_COLUMNS, TO_IDS, 0 ) // Sets the adapter for the ListView contactsList.adapter = cursorAdapter } // Initializes the loader LoaderManager.getInstance(this).initLoader(2, null, this) return root }

override fun onCreateLoader(id: Int, args: Bundle?): Loader<Cursor> { /* * Makes search string into pattern and * stores it in the selection array */ loaderFlag = id selectionArgs[0] = "%$searchString%" val mLoader = activity?.let { CursorLoader( it, ContactsContract.Data.CONTENT_URI, PROJECTION, SELECTION, selectionArgs, SORT_ORDER ) } // Starts the query return mLoader ?: throw IllegalStateException() }}override fun onLoadFinished(loader: Loader<Cursor>, cursor: Cursor?) { // Put the result Cursor in the adapter for the ListView cursorAdapter?.swapCursor(cursor) // 用进程打印列表数据 Thread { val userList: ArrayList<User> = arrayListOf(); // 因为列表的查询没有指定搜索条件(searchString为空),查询的是全部数据,那样每个联系会出来好几条数据,可以简单用个hashMap去重下 var userHashMap: HashMap<String, User> = HashMap(); try { while (cursor.moveToNext()) { val contactId = cursor.getString(0) val contactKey = cursor.getString(1) val contactName = cursor.getString(2) var currentInfos: MutableList<String?> = ArrayList() currentInfos.add("contactName = $contactName") var userPhoneList : ArrayList<UserPhone> = arrayListOf(); var userEventList : ArrayList<UserEvent> = arrayListOf(); // 我们可以用类似的方式查询该联系对应的具体数据 val cr: ContentResolver = requireActivity().contentResolver detailSelectionArgs[0] = contactKey!! val curs: Cursor? = cr.query(ContactsContract.Data.CONTENT_URI, DETAIL_PROJECTION, DETAIL_SELECTION, detailSelectionArgs, null) if (curs != null) { while (curs.moveToNext()) { val id: Long = cursor.getLong(0) val name: String = curs.getString(1) // full name val mime: String = curs.getString(2) // type of data (phone / birthday / email) val data: String? = curs.getString(3) // the actual info, e.g. 1-212-555-1234 var type: String? = curs.getString(4); var label: String? = curs.getString(5); var kind = "unknown" when (mime) { ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE -> { kind = "phone" userPhoneList.add(UserPhone(contactKey, data, type, label)) } ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE -> { kind = "event" userEventList.add(UserEvent(contactKey, data, type, label)) } ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE -> kind = "email" ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE -> kind = "note" } if (data != null) { currentInfos!!.add("$kind = $data/$type/$label") } } Log.i("CURRENT", contactName "_" contactId "_" currentInfos.toString()) } val user = User(contactKey, contactId, contactName, userPhoneList, userEventList, null); if (!userHashMap.containsKey(user.key) && userEventList.size > 0) { userHashMap.put(user.key, user); userList.add(User(contactKey, contactId, contactName, userPhoneList, userEventList, null)) } } } catch (e: Exception) { Log.e("ABC", "while error $e") } Log.i("EFG", userList.toString()) if (userList.size > 0) { val userListStr = Gson().toJson(userList); Utils.saveData(requireContext(), "test", "userList", userListStr)// textView?.text = "list: " userList.toString() Log.i("LIST", userList.toString()) } }.start() }

代码有所截取,可能有部分变量什么的遗漏的,但是示意是足够了。

本文启发自 Android Contacts Database Structure Retrieve a list of contacts

推荐

首页/电脑版/网名
© 2026 NiBaKu.Com All Rights Reserved.