精华内容
下载资源
问答
  • 安卓蓝牙通信

    千次阅读 2014-07-08 11:03:05
    安卓蓝牙通信代码(付工程下载链接,安卓4.1测试通过)
    
    
    package com.example.bluetoothtest;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.util.ArrayList;
    import java.util.UUID;
    
    import android.app.Activity;
    import android.bluetooth.BluetoothAdapter;
    import android.bluetooth.BluetoothDevice;
    import android.bluetooth.BluetoothServerSocket;
    import android.bluetooth.BluetoothSocket;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;
    import android.widget.Toast;
    /***
     * 
     * @author 张章
     *
     */
    public class MainActivity extends Activity {
     
    	TextView t1,t2,t3;
    	EditText et;
    	Button but,but2,but3,but4,but5,but6,but7,but8,but9;
    	
    	ArrayList<BluetoothDevice>deList=new ArrayList<BluetoothDevice>();
    	//连接后获取输出流
    	OutputStream outputStream;
    	BluetoothAdapter bluetooth;
    	String uuid="a60f35f0-b93a-11de-8a39-08002009c666";//服务端蓝牙设备的UUID
    	Handler handler=new Handler(){
    		@Override
    		public void handleMessage(Message msg) {
    			super.handleMessage(msg);
    			if(msg.what==-1){
    				Toast.makeText(getApplicationContext(), "等待用户连接。。。。", 1).show();
    			}
    			if(msg.what==-2){
    				Toast.makeText(getApplicationContext(), "已与用户连接。。。。", 1).show();
    			}
    			if(msg.what==-3){
    				Toast.makeText(getApplicationContext(), "等待服务端接受。。。。", 1).show();
    			}
    			if(msg.what==-4){
    				Toast.makeText(getApplicationContext(), "服务端已接受。。。。", 1).show();
    			}
    			if(msg.what==1){
    				
    				Toast.makeText(getApplicationContext(), "接收"+(String)msg.obj, 1).show();
    			}
    			if(msg.what==2){
    				
    				Toast.makeText(getApplicationContext(), "发送 "+(String)msg.obj, 1).show();
    			}
    		}
    	};
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		t1=(TextView) findViewById(R.id.t1);
    		t2=(TextView) findViewById(R.id.t2);
    		t3=(TextView) findViewById(R.id.t3);
    		et=(EditText) findViewById(R.id.et);
    		but=(Button) findViewById(R.id.but);
    		but2=(Button) findViewById(R.id.but2);
    		but3=(Button) findViewById(R.id.but3);
    		but4=(Button) findViewById(R.id.but4);
    		but5=(Button) findViewById(R.id.but5);
    		but6=(Button) findViewById(R.id.but6);
    		but7=(Button) findViewById(R.id.but7);
    		but8=(Button) findViewById(R.id.but8);
    		but9=(Button) findViewById(R.id.but9);
    	    //安卓手机可能有多个蓝牙适配器,目前只能使用默认蓝牙适配器,通过该方法可以获取到默认适配器
    		bluetooth=BluetoothAdapter.getDefaultAdapter();
    		//启用和禁用BluetoothAdapter是耗时的异步操作,需注册Receiver监听状态变化
    		registerReceiver(new MyReceiver(), new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
    		//调用startDiscovery()方法可以开启设备扫描,注册该Receiver可以收到扫描状态变化(开始扫描还是结束扫描)
    		registerReceiver(new SearchReceiver(), new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED));
    		registerReceiver(new SearchReceiver(), new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED));
    		//调用startDiscovery()方法可以开启设备扫描,注册该Receiver可以收到扫描到的设备
    		//通过(BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
    		//可以获得扫描到的设备
    		registerReceiver(new SearchDeviceReceiver(), new IntentFilter(BluetoothDevice.ACTION_FOUND)); 
    		but.setOnClickListener(new View.OnClickListener() {
    			@Override
    			public void onClick(View arg0) {
    				if(bluetooth.setName(et.getText().toString())){
    					Toast.makeText(getApplicationContext(), "设置成功", 1).show();
    				}else
    					Toast.makeText(getApplicationContext(), "设置失败", 1).show();
    			}
    		});
    		//加入	<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>权限
    		//后可以直接使用enable()方法启动本机蓝牙适配器,并且可以修改蓝牙友好名称
    		but2.setOnClickListener(new View.OnClickListener() {
    			@Override
    			public void onClick(View arg0) {
    				bluetooth.enable();
    			}
    		});
    		//使用下面语句可以弹出对话框提示是否开启,onActivityResult()方法可获取用户选项
    		but3.setOnClickListener(new View.OnClickListener() {
    			@Override
    			public void onClick(View arg0) {
    				startActivityForResult(new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE),1);
    			}
    		});
    		but4.setOnClickListener(new View.OnClickListener() {
    			@Override
    			public void onClick(View arg0) {
    				if(bluetooth.isEnabled()){
    					t1.setText("地址"+bluetooth.getAddress());
    					t2.setText("名称"+bluetooth.getName());
    					t3.setText("可见性"+bluetooth.getScanMode());
    				}else
    					Toast.makeText(getApplicationContext(), "蓝牙不可用", 1).show();	
    			}
    		});
    		//修改本机蓝牙可见时间
    		but5.setOnClickListener(new View.OnClickListener() {
    			@Override
    			public void onClick(View arg0) {
    				Intent intent=new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
    				intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 1200);
    				startActivityForResult(intent, 2);
    			}
    		});
    		but6.setOnClickListener(new View.OnClickListener() {
    			@Override
    			public void onClick(View arg0) {
    				if(bluetooth.isEnabled()){
    					deList.clear();
    					bluetooth.startDiscovery();
    				}
    			}
    		});
    		but7.setOnClickListener(new View.OnClickListener() {
    			@Override
    			public void onClick(View arg0) {
    				createServer();
    			}
    
    		});
    		
    		but8.setOnClickListener(new View.OnClickListener() {
    			@Override
    			public void onClick(View arg0) {
    				linktoServer();
    			}
    
    		});
    		
    		but9.setOnClickListener(new View.OnClickListener() {
    			@Override
    			public void onClick(View arg0) {
    				send();
    			}
    			
    		});
    		
    	
    		
    	}
    
    	private void linktoServer() {
    		 try {
    			BluetoothDevice bluetoothDevice=deList.get(0);
    			bluetoothDevice.getAddress();
    			final BluetoothSocket bluetoothSocket=bluetoothDevice.createRfcommSocketToServiceRecord(UUID.fromString(uuid));
    			new Thread(){
    				@Override
    				public void run() {
    					try {
    						handler.sendEmptyMessage(-3);
    						bluetoothSocket.connect();
    						handler.sendEmptyMessage(-4);
    						outputStream=bluetoothSocket.getOutputStream();
    						getInfo(bluetoothSocket);
    						
    					} catch (Exception e) {
    						e.printStackTrace();
    					}
    				};
    			}.start();
    			
    		} catch (Exception e) {
    		
    			e.printStackTrace();
    		}
    	}
    	//创建服务端,类似于Socket编程
    	private void createServer()  {
    		try {
    			final BluetoothServerSocket btserver = bluetooth.listenUsingRfcommWithServiceRecord("server", UUID.fromString(uuid));
    			new Thread(){
    				@Override
    				public void run() {
    					
    					try {
    						while(true){
    							handler.sendEmptyMessage(-1);
    							final BluetoothSocket serverSocket = btserver.accept();//阻塞式方法,需开线程
    							handler.sendEmptyMessage(-2);
    							outputStream=serverSocket.getOutputStream();
    							new Thread(){//当有新连接时,交给新线程完成
    								public void run() {
    									getInfo(serverSocket);
    								};
    							}.start();
    						}
    					} catch (Exception e) {
    						// TODO Auto-generated catch block
    						e.printStackTrace();
    					}
    					
    				};
    			}.start();
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    
    	}
    	private void send() {
    		String ss=et.getText().toString().trim();
    		
    		try {
    			BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(outputStream));
    			bw.write(ss);
    			bw.newLine();//注意换行
    			bw.flush();//刷新缓存
    			Message msg=new Message();
    			msg.obj=ss;
    			msg.what=2;
    			handler.sendMessage(msg);
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    	private void getInfo(BluetoothSocket serverSocket) {
    
    		try {
    			InputStream inputStream=serverSocket.getInputStream();
    			BufferedReader br=new BufferedReader(new InputStreamReader(inputStream));
    			while(true){
    				String msg=br.readLine();
    				Message msgs=new Message();
    				msgs.obj=msg;
    				msgs.what=1;
    				handler.sendMessage(msgs);
    				
    			}
    		} catch (IOException e) {
    		}
    	}
    	@Override
    	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    		
    		super.onActivityResult(requestCode, resultCode, data);
    		if(requestCode==1&&resultCode==RESULT_OK){
    			Toast.makeText(getApplicationContext(), "蓝牙已启用(onActivityResult)", 1).show();
    		}
    		if(requestCode==2&&resultCode!=RESULT_CANCELED){
    			Toast.makeText(getApplicationContext(), "蓝牙可见时间已修改"+requestCode+"(onActivityResult)", 1).show();
    		}
    		
    	}
    	
    	private class MyReceiver extends BroadcastReceiver{
    
    		@Override
    		public void onReceive(Context arg0, Intent intent) {
    			int state=intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
    			if(state==BluetoothAdapter.STATE_TURNING_ON)
    				Toast.makeText(getApplicationContext(), "蓝牙正在开启", 1).show();
    			if(state==BluetoothAdapter.STATE_ON)
    				Toast.makeText(getApplicationContext(), "蓝牙已经开启", 1).show();
    			if(state==BluetoothAdapter.STATE_TURNING_OFF)
    				Toast.makeText(getApplicationContext(), "蓝牙正在关闭", 1).show();
    			if(state==BluetoothAdapter.STATE_OFF)
    				Toast.makeText(getApplicationContext(), "蓝牙已关闭", 1).show();
    		}
    		
    	}
    	private class SearchReceiver extends BroadcastReceiver{
    		
    		@Override
    		public void onReceive(Context arg0, Intent intent) {
    			if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(intent.getAction())){
    				Toast.makeText(getApplicationContext(), "启动发现。。。", 1).show();
    			}
    			if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(intent.getAction())){
    				Toast.makeText(getApplicationContext(), "发现结束。。。", 1).show();
    				
    			}
    		}
    		
    	}
    	private class SearchDeviceReceiver extends BroadcastReceiver{
    		
    		@Override
    		public void onReceive(Context arg0, Intent intent) {
    			et.append(intent.getStringExtra(BluetoothDevice.EXTRA_NAME)+"\n");
    			Toast.makeText(getApplicationContext(), intent.getStringExtra(BluetoothDevice.EXTRA_NAME), 1).show();
    			try{
    				deList.add((BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE));
    				Toast.makeText(getApplicationContext(), "发现设备", 1).show();
    			}catch(Exception e){}
    			
    		}
    		
    	}
    
    }
    
    
    
    
    
    布局文件如下
    <pre name="code" class="html"><ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
    	
    	 >
    <LinearLayout 
         android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="vertical"
        >
        <TextView
            android:id="@+id/t1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="t1" />
    
        <TextView
            android:id="@+id/t2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="t2" />
    
        <TextView
            android:id="@+id/t3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="t3" />
    
        <EditText 
             android:id="@+id/et"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            />
        <Button
            android:id="@+id/but"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="设置名称" />
    
        <Button
            android:id="@+id/but2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="自动开启" />
    
        <Button
            android:id="@+id/but3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="提示开启" />
    
        <Button
            android:id="@+id/but4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="获取信息" />
    
        <Button
            android:id="@+id/but5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="修改可见性" />
    
        <Button
            android:id="@+id/but6"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="查找设备" />
    
        <Button
            android:id="@+id/but7"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="创建服务端" />
    
        <Button
            android:id="@+id/but8"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="连接到服务端" />
        <Button
            android:id="@+id/but9"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="发送" />
    
    </LinearLayout>
    </ScrollView>


    
    


    manifest文件

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.bluetoothtest"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="18" />
    
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name="com.example.bluetoothtest.MainActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    	<uses-permission android:name="android.permission.BLUETOOTH"/>
    	<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    </manifest>
    




    注意:安卓手机A,安卓手机B都要安装这款软件,并都点击 提示开启(或自动开启),接着安卓手机A点击  修改可见性  并点击  创建服务端  ,安卓手机B点击查找设备,若找到的第一个设备为安卓手机A,B手机点击   链接到服务端  ,等提示  已经连接   后就可以在文本框中输入文字,然后点击   发送   了

    请安装到手机上使用!


    工程下载地址   http://pan.baidu.com/s/1eQ3nc3o



    展开全文
  • 安卓蓝牙对战demo实例

    2015-10-06 16:17:45
    安卓蓝牙对战demo实例,android源码0分提供下载了哦!
  • 安卓蓝牙固件升级Demo

    2016-11-25 16:32:54
    安卓蓝牙固件升级通过连接服务器,下载升级的bin包或者hex,点击扫描设备连接需要升级的蓝牙设备,点击需要升级就可以。源代码测试几次都可以使用放线下载
  • 安卓蓝牙ble源码

    2016-03-15 13:25:32
    最近做的智能医疗项目,采用的ble蓝牙模块,传此代码共享,随意二次开发,欢迎下载
  • 安卓蓝牙部分源代码

    2012-09-18 16:28:52
    这是一个完整的安卓蓝牙部分的源代码,不会自己下载源代码的拿去
  • 求大神指教安卓蓝牙(最好是4.0的),手机端与带有蓝牙模块的智能硬件端的,流程步骤,希望代码全一点,可以下载,代码有详细注释,看了之前的一些大神写的,注释很少,拜托了!!!!!!!!!
  • 安卓蓝牙控制代码

    2014-05-24 11:48:47
    代码存在一些问题能够编译生成apk文件就是运行就停止,希望大家下载帮忙改改,共同学习,本人是个学生
  • 安卓蓝牙遥控拍照录像可显示屏幕,支持黑莓和安卓,google play上下载的,无广告,2个软件,一个BtCam.apk,一个Remote Shot Live Preview_v1.0.0_apkpure.com.apk,无广告
  • 安卓连接蓝牙打印机进行打印,在前人的基础上进行改动,静默连接(知道打印机的名字,需要自己去改动代码里打印机的名字),自动连接,可在工程内多个地方实现打印,封装性好,亲测成功,积分不知道怎么上涨到44积分了
  • 安卓4.0连接多台设备,依次读取设备里面的数据,可以使用放心下载
  • 编译:奇安信代码卫士团队本周,谷歌修复了安卓蓝牙组件中的一个严重缺陷。如未被修复,则该漏洞可在无需用户交互的情况下遭利用,甚至可被用于自传播蓝牙蠕虫。谷歌已经发布2020年2月安卓安全通告修复了这些漏洞,...
    9b14d6b13a21d1f716bafa73f282df6a.gif

    聚焦源代码安全,网罗国内外最新资讯!

    编译:奇安信代码卫士团队本周,谷歌修复了安卓蓝牙组件中的一个严重缺陷。如未被修复,则该漏洞可在无需用户交互的情况下遭利用,甚至可被用于自传播蓝牙蠕虫。谷歌已经发布2020年2月安卓安全通告修复了这些漏洞,用户可在本周起下载这些修复方案。这个漏洞的编号为 CVE-2020-0022,是由德国网络安全公司 ERNW 发现并报告给谷歌的。

    可被用于创建自传播蓝牙蠕虫

    c30a195bd52f4dea024b6011bbe495e1.png

    研究人员指出,利用该 bug 无需用户交互,所需的只是用户在设备上启用蓝牙。然而,虽然按这种要求操作在过去能够限制攻击面,但今天去无法做到,因为当代安卓操作系统默认启用蓝牙并且很多安卓用户使用蓝牙耳机意味着很多手持设备上均启用了蓝牙服务。攻击要求和目标保持近距离,但对于任何一种蓝牙利用来说即使如此。ERNW 公司的研究人员表示该漏洞可导致攻击者“以蓝牙守护进程的权限静默执行任意代码”。他们表示,“无需用户交互,只需获悉目标设备的蓝牙 MAC 地址即可。对于某些设备而言,蓝牙 MAC 地址可从 WiFi MAC 地址获取。该漏洞可导致个人数据被盗,并可被用于传播恶意软件(近距离蠕虫)”。

    影响安卓9及更早版本

    c30a195bd52f4dea024b6011bbe495e1.png

    该漏洞已在安卓8和9上成功测试,但研究人员认为更早版本也可能易受攻击。CVE-2020-0022并无法在安卓10上运行,它仅能导致蓝牙守护进程崩溃。ERNW 公司团队表示计划不久之后发布相关漏洞技术详情,但同时他们向安卓用户发布警告以及更多的时间来安装2020年2月份发布的安全更新。如果用户出于各种原因无法更新,则可遵照如下简单规则阻止攻击:
    • 只有在要求严格的情况下启用蓝牙

    • 使自己的设备无法被发现。多数设备只有在用户进入蓝牙扫描目录时才是可发现的。尽管如此,某些老旧设备在永久期限内可能会被发现。

    ERNW 团队表示计划发布 PoC 代码复现该 bug,而这很可能会被恶意人员利用。 推荐阅读

    蓝牙被曝 KNOB 新型缺陷,可导致流量遭劫持

    iPhone 蓝牙流量被指在某些情况下泄露用户电话号码

    原文链接https://www.zdnet.com/article/google-fixes-no-user-interaction-bug-in-androids-bluetooth-component/

    题图:Pixabay License

    转载请注明“转自奇安信代码卫士 www.codesafe.cn”。

    b81d6cbec5c6e7586ab0cdb9d4985361.png4ac491ae0ad7ac3732fb6c57b602427b.png

    奇安信代码卫士 (codesafe)

    国内首个专注于软件开发安全的产品线。

     点个“在看”,bounty 不停~                                          

    展开全文
  • 蓝牙电话之PBAP-同步协议分析在前一篇文章《蓝牙电话之PBAP协议分析》中从整体上分析了PBAP协议的内容,本章我们着重分析协议中的精髓——同步电话薄。PBAP协议存在的目的就是将PSE端的源数据同步到PCE,那么就让...

    蓝牙电话之PBAP-同步协议分析

    90243b219f87b544cc4194978ff34b67.png

    在前一篇文章《蓝牙电话之PBAP协议分析》中从整体上分析了PBAP协议的内容,本章我们着重分析协议中的精髓——同步电话薄。PBAP协议存在的目的就是将PSE端的源数据同步到PCE,那么就让我们开启这段旅程吧。

    babc02286cf513c9dd66c28c4d232e28.gif

    每一种协议都会定义相关的功能features,PBAP同步也不另外,协议中主要定义了以下两种功能。

    • Download:此功能用于下载电话簿对象的全部内容
    • Browsing:此功能特别适用于需要滚动浏览电话簿的应用程序

    PSE和PCE两端对这两种功能的支持见下图:

    1d99e2e6c73e984fc11557fd936e7ef5.png

    由于Download功能可以将电话簿对象的全部内容同步到PCE,从而PCE端获取到数据后完全可以通过蓝牙电话等应用程序将数据显示到界面,一样可以达到滚动浏览电话簿信息的目的,所以后面主要以Download为分析点,对Browsing感兴趣的同学,欢迎给我私信一起探讨该功能点如何使用。

    Download这个功能特别适用于PSE端存储的电话簿容量相对较大,PCE设备通常从PSE端下载这些大容量数据并在其本地存储整个电话簿的场景下。PullPhonebook函数就是用来下载自己感兴趣的电话簿对象。

    f802c7624364678793aee0177396d44e.png

    由于PBAP协议是基于OBEX的,所以PullPhonebook函数顾名思义也是采用request-response这种一问一答的形式传输数据。

    请求格式

    822715831b54ddbdf5de599636923f95.png

    同步的电话簿对象名字Name值有如下几种选项:

    2c80e089c32518d695d90e902eaf18ed.png

    回复格式

    4e5cfdb1eaabf38e140f28eb03d9ffb1.png

    回复数据中的vCard对象只应包含使用属性选择器Attribute Selector参数指示的属性,并且应使用格式Format参数指示的格式组装数据。当前蓝牙PBAP协议中的vCard版本只有vCard 2.1和vCard 3.0这两种版本,所以我们在构造数据时选择其中一种vCard版本即可。

    请求回复格式中需要重点讲解的只有一个参数:Application Parameters Header,其数据是由一组不同的tag组成整体的Application Parameters,可选的Tag如下图,比较常用的为红色框图标注出来的这六个tag:

    00549b82240cb9bf67ce7d33c1d024d7.png

    这些tag中PropertySelector用于指示请求的vCard对象中应该包含的属性,PSE根据这些属性来组织回复的Body/End of Body Header中包含的数据,PCE只能使用此头接收所请求的vCard所需内容,PSE不得回复任何其他性能数据,除非PCE有其他要求。

    因为PropertySelector的值是由一个64位的数据组成,所以每一位都代表了一种属性,如果PCE请求的电话簿需要包含对应的数据,就将该数据对应在PropertySelector的二进制位设置为true(1)。具体每一位的含义见下图:

    ececa547f59b7161bdbebf5d7c420678.png

    同步电话簿中的信息时,最主要的关注还是联系人名字、联系人号码、联系人头像这三部分数据。所以要根据自己业务的真实需求来构造PropertySelector值,同步到PCE端相关应用需要的数据。

    由于当前安卓源码还没实现PCE端的相关接口,需要适配自我实现。我这里采用的这套安卓代码是以高通源码为基础,加上功能适配后实现的一套PBAP同步代码,PCE端同步电话簿的流程大概为:获取同步对象的数量 –> 同步该对象。

    接下来以HCI视角简单分析下同步流程:

    1、 同步联系人

    5a9a8a7b94fb700fb60c273ecc7eba45.png

    同步联系人整体上分为两步骤,先获取两种Name下的联系人数量,再根据数量分别同步对应Name下的联系人数据,以下两幅截图选取Name=telecom/pb.vcf为例进行说明,SIM卡的流程类似。

    • 获取联系人数量
    066632c1588b502026f3a15c9206e467.png
    • 同步联系人数据
    7fe3d5a69d98dab12da3bc93040d92a6.png

    2、 同步通话记录

    通话记录有三种类型及对应的vcf文件

    • MISSED:未接来电通话记录——mch.vcf
    • RECEIVED:已接来电通话记录——ich.vcf
    • DIALED:去电通话记录——och.vcf

    但是还有一种类型的vcf文件包含以上三种类型,即cch.vcf,所以可以根据自己的需求选择同步哪种通话记录,我这边实现的是同步全部类型的通话记录(主要是分类型依次去同步通话记录,太麻烦了)

    9477d71c9c35da19084077e10aa45122.png

    PCE端同步获取到电话簿数据后基本上有两种方式来处理数据:

    1. 通过回调方式上报给应用(需要添加相关回调打通APK-API-蓝牙服务这三层的关系)
    2. 存储在安卓系统提供的数据库中,上报应用相关状态,应用再从数据库中取出对应的数据

    实际使用以上两种方式后,自我感觉通过回调方式上报数据速度很快,但数据库的优势是可以将数据已数据库的形式存储,不担心应用或安卓系统crash后导致的数据丢失问题。所以建议大家可以两种方式结合起来共同使用。

    好了,蓝牙电话中关于PBAP协议同步数据的分析就总结到这,感兴趣的小伙伴欢迎私信留言一起讨论

    展开全文
  • Android 蓝牙耳机控制夸进程控制手机翻页,可以控制手机上下滚动,聊qq 微信,看小说 懒人翻页助手。还有一些bug忘见谅,需要源码的留言,我也是新手。下载后去掉zip后缀即可使用。
  • 现象:手机是安卓10,打开蓝牙后,在系统的搜索栏里面可以看到搜索到了很多蓝牙设备。可是打开下载的“蓝牙串口”APP和“蓝牙调试器”APP都搜索不到设备,使用微信小程序也搜索不到。 解决:把手机的定位功能打开就...

    现象:手机是安卓10,打开蓝牙后,在系统的搜索栏里面可以看到搜索到了很多蓝牙设备。可是打开下载的“蓝牙串口”APP和“蓝牙调试器”APP都搜索不到设备,使用微信小程序也搜索不到。

    解决:把手机的定位功能打开就解决了。

    展开全文
  • 此教程实现4个功能:蓝牙连接、蓝牙断开,蓝牙字符文本数据发送,蓝牙字符文本数据接收 适用蓝牙模块:HC05,HC06,BT04,JSY31 通过蓝牙单片机APP实现心率数据,体重数据,温度数据,湿度数据显示。发送数据实现...
  • 蓝牙耳机弹窗安卓可以用吗?你们期待的安卓版软件现已上线,在这里你们可以自由的定制个性的蓝牙弹窗样式和风格,自由设置不同的功能和细节,让你们的拥有炫酷的弹窗显示。【软件功能】锁定后台滑出任务列表并找到...
  • 运行不了的可以在应用商店搜索BLE Sample找到APP 下载下来看效果但是官方Demo又是Service又是广播,跳来跳去,看得人云里雾里,在这里我将它精简了一下,封装成一个类,根据提示调用对应的方法就可以实现扫描蓝牙设备并...
  • 1,资源地址 链接: ... 2,资源使用 2.1,下载资源后解压 ...2.3,打开下载插件源码,找到kn_blue部分其中Kmblue为蓝牙使用部分(安卓通用),包含蓝牙初始化、扫描、连接、打印、关闭、以及查询..
  • 一个安卓蓝牙聊天软件,可以文字聊天、分享图片给好友。不喜勿喷 点击打开下载链接
  • * 在网上下载安卓蓝牙串口app都是基于eclipse的,但往as里边导入时都存在问题。 迫不得已最后我使用的办法还是在as下面新建工程,然后把相关文件导入。不过还是遇到了其他的问题。 * 某个蓝牙相关的函数报错...
  • 以下代码都是可以实际运行的代码,...台式机+蓝牙适配器,失败了。 需要的jar包:barcode.jar 、 bluecove-2.1.1-SNAPSHOT.jar 下载地址:jar包下载地址(积分自动设置5.....) 参考文章:https://blog.csdn.net/...
  • 用于开发安卓手机使用wifi、蓝牙连接小票打印机实现打印,主要用于开发快递行业,实现实时打印不干胶快递单的功能。 此源码为核心源码,技术差的请勿下载。 //蓝牙权限 ...
  • 安卓开发项目之进行蓝牙之间的实时通信,下载解压之后在Android studio 内导入文件即可,这个项目可以在两台安卓手机之间进行实时的通信,但Android studio内置的模拟器是不可以调试使用的,需在真机条件下测试
  • 蓝牙下载联系人.zip

    2020-04-08 19:40:37
    支持 安卓 9.0 蓝牙下载联系人和通话记录 联系人 可以区分 sim 卡和 手机存储 很完善 在 pbap 协议下 可以通过流的方式 迅速下载联系人通话记录数据 很快
  • 软件还可通过蓝牙连接方式与雷达连接,实现预警流动测速雷达! 一、安装说明 1、当你下载完安装文件包后,解压可以得到两个文件,分别是dsa文件夹及DSA.apk。 2、将这两个文件复制到存储卡的根目录下(非常重要)...
  • 最近在做一个安卓应用,其中有一个需求是要求用蓝牙连接打印机实现打印功能。一开始没有一点头绪,网上找了很多资料也找不到有用的数据。所以自己就去研究,最终,功夫不负有心人,顺利的完成了这个功能。下边贴出我...
  • 大二寒假学做蓝牙遥控智能车,也就学了安卓编程,写了这个安卓遥控程序。这是第一版本,用按钮实现控制的,等我把重力感应控制的那个程序做稳定了再开源。  上个图:     主要参考安卓SDK自带的开源例程,...
  • 下载应用闪电秀,让你不再错过来电! 2.动感闪光:告别沉闷的系统来电界面,聚会时也能轻轻松松的在朋友中脱颖而出。 3.专属潮流:为你的亲爱哒定制专属的来电秀吧,我们提供了多种好玩有趣的来电页面, 小黄人、...
  • 把家里的小彩灯改装了一下,变成了用手机蓝牙控制的可调色和调光的小彩灯, 瞬间档次就上去了。...感兴趣的朋友直接发出去做板,回来下载程序进去就能使用。接下来看看这美美的小彩灯吧! PCB板截图:

空空如也

空空如也

1 2 3 4 5 ... 11
收藏数 219
精华内容 87
关键字:

安卓蓝牙下载