蓝牙2.0 Demo

Manifest文件综述

// 权限说明
uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
uses-permission android:name="android.permission.BLUETOOTH"
uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" 
uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"

存在扫描设备和操作蓝牙设置操作时,需要BLUETOOTH_ADMIN权限和BLUETOOTH权限.
MOUNT_UNMOUNT_FILESYSTEMS允许允许挂载和反挂载文件系统可移动存储.
WRITE_EXTERNAL_STORAGE使得SD卡获得写的权限.

蓝牙存在的问题

蓝牙一直在等待搜索,但是蓝牙列表却不弹出来。
android 6.0之后要用蓝牙还需要添加一个模糊定位的权限android.permission.ACCESS_COARSE_LOCATION(GPS是精确定位)。
在android 6.0(targetSdkVersion小于23)之前,安装新的app时系统会提示应用将要获取某某权限,如果同意安装,系统会默认为应用授予所申请的所有权限,而不同意的话,就不能安装应用;所以如果你以前的APP设置的targetSdkVersion低于23,在运行时是不会崩溃的。而在android 6.0(targetSdkVersion>=23)之后,我们会直接安装,不过当app需要获取不恰当权限的时候我们再决定是确定还是拒绝。

android 6.0权限分类

  • Normal Permissions
  • Normal Permissions一般不涉及用户隐私,是不需要用户授权的.

    ACCESS_LOCATION_EXTRA_COMMANDS
    ACCESS_NETWORK_STATE
    ACCESS_NOTIFICATION_POLICY
    ACCESS_WIFI_STATE
    BLUETOOTH
    BLUETOOTH_ADMIN
    BROADCAST_STICKY
    CHANGE_NETWORK_STATE
    CHANGE_WIFI_MULTICAST_STATE
    CHANGE_WIFI_STATE
    DISABLE_KEYGUARD
    EXPAND_STATUS_BAR
    GET_PACKAGE_SIZE
    INSTALL_SHORTCUT
    INTERNET
    KILL_BACKGROUND_PROCESSES
    MODIFY_AUDIO_SETTINGS
    NFC
    READ_SYNC_SETTINGS
    READ_SYNC_STATS
    RECEIVE_BOOT_COMPLETED
    REORDER_TASKS
    REQUEST_INSTALL_PACKAGES
    SET_ALARM
    SET_TIME_ZONE
    SET_WALLPAPER
    SET_WALLPAPER_HINTS
    TRANSMIT_IR
    UNINSTALL_SHORTCUT
    USE_FINGERPRINT
    VIBRATE
    WAKE_LOCK
    WRITE_SYNC_SETTINGS
    
  • Dangerous Permissions
  • Dangerous Permissions涉及到用户隐私,在使用时需要用户实时授权才行

    group:android.permission-group.CONTACTS
      permission:android.permission.WRITE_CONTACTS
      permission:android.permission.GET_ACCOUNTS
      permission:android.permission.READ_CONTACTS
    group:android.permission-group.PHONE
      permission:android.permission.READ_CALL_LOG
      permission:android.permission.READ_PHONE_STATE
      permission:android.permission.CALL_PHONE
      permission:android.permission.WRITE_CALL_LOG
      permission:android.permission.USE_SIP
      permission:android.permission.PROCESS_OUTGOING_CALLS
      permission:com.android.voicemail.permission.ADD_VOICEMAIL
    group:android.permission-group.CALENDAR
      permission:android.permission.READ_CALENDAR
      permission:android.permission.WRITE_CALENDAR
    group:android.permission-group.CAMERA
      permission:android.permission.CAMERA
    group:android.permission-group.SENSORS
      permission:android.permission.BODY_SENSORS
    group:android.permission-group.LOCATION
      permission:android.permission.ACCESS_FINE_LOCATION
      permission:android.permission.ACCESS_COARSE_LOCATION
    group:android.permission-group.STORAGE
      permission:android.permission.READ_EXTERNAL_STORAGE
      permission:android.permission.WRITE_EXTERNAL_STORAGE
    group:android.permission-group.MICROPHONE
      permission:android.permission.RECORD_AUDIO
    group:android.permission-group.SMS
      permission:android.permission.READ_SMS
      permission:android.permission.RECEIVE_WAP_PUSH
      permission:android.permission.RECEIVE_MMS
      permission:android.permission.RECEIVE_SMS
      permission:android.permission.SEND_SMS
      permission:android.permission.READ_CELL_BROADCASTS
    

    android部分知识学习

    蓝牙适配器
    主要功能包括:
    1 开关蓝牙设备
    2 扫描蓝牙设备
    3 设置/获取蓝牙状态信息
    蓝牙状态值
    蓝牙Name
    蓝牙Mac地址
    BluetoothAdapter.getDefaultAdapter();
    BluetoothAdapter STATE
    STATE_OFF 蓝牙已经关闭
    STATE_ON 蓝牙已经打开
    STATE_TURNING_OFF 蓝牙处于关闭过程中
    STATE_TURNING_ON 蓝牙处于打开过程中
    BluetoothAdapter SCAN_MOD
    SCAN_MODE_CONNECTABLE 表明该蓝牙可以扫描其他蓝牙设备
    SCAN_MODE_CONNECTABLE_DISCOVERABLE 该蓝牙设备同时可以扫码其他蓝牙设备,并且可以被其他蓝牙设备扫描到
    SCAN_MODE_NONE 该蓝牙不能扫描以及被扫描

  • 获取蓝牙适配器
  • 
    BluetoothAdapter _bluetooth = BluetoothAdapter.getDefaultAdapter();
    
  • 打开蓝牙
  • 
    _bluetooth.enable();
    

    requestWindowFeature
    DEFAULT_FEATURES 系统默认状态,一般不需要指定
    FEATURE_CONTEXT_MENU 启用ContextMenu,默认该项已启用,一般无需指定
    FEATURE_CUSTOM_TITLE 自定义标题。当需要自定义标题时必须指定。如:标题是一个按钮时
    FEATURE_INDETERMINATE_PROGRESS 不确定的进度
    FEATURE_LEFT_ICON 标题栏左侧的图标
    FEATURE_NO_TITLE 无标题
    FEATURE_OPTIONS_PANEL 启用“选项面板”功能,默认已启用
    FEATURE_PROGRESS 进度指示器功能
    FEATURE_RIGHT_ICON 标题栏右侧的图标

  • 浏览搜索
  • 
    setProgressBarIndeterminateVisibility(true);
    setTitle("搜索中...");
    if (mBtAdapter.isDiscovering()) {
        mBtAdapter.cancelDiscovery();
    }
    mBtAdapter.startDiscovery();
    
  • getRemoteDevice
  • 给定Mac地址创建一个BluetoothDevice类的实力(代表远程蓝牙实力),并连接

    _device = _bluetooth.getRemoteDevice(address);
    // createRfcommSocketToServiceRecord创建一个BluetoothSocket实例
    _socket = _device.createRfcommSocketToServiceRecord(UUID.fromString(MY_UUID));
    _socket.connect();
    

    剩余的通信均依靠_socket来完成,附录核心代码

    public void onSendButtonClicked(View v){
        int i=0;
        int n=0;
        try{
            OutputStream os = _socket.getOutputStream();
            byte[] bos = edit0.getText().toString().getBytes();
            for(i=0;i < bos.length;i++){
                if(bos[i]==0x0a)n++;
            }
            byte[] bos_new = new byte[bos.length+n];
            n=0;
            for(i=0;i < bos.length;i++){
                if(bos[i]==0x0a){
                    bos_new[n]=0x0d;
                    n++;
                    bos_new[n]=0x0a;
                }else{
                    bos_new[n]=bos[i];
                }
                n++;
            }
            
            os.write(bos_new);  
        }catch(IOException e){          
        }   
    }
    
    Thread ReadThread=new Thread(){     
        public void run(){
            int num = 0;
            byte[] buffer = new byte[1024];
            byte[] buffer_new = new byte[1024];
            int i = 0;
            int n = 0;
            bRun = true;
            while(true){
                try{
                    while(is.available()==0){
                        while(bRun == false){}
                    }
                    while(true){
                        num = is.read(buffer);
                        n=0;
                        
                        String s0 = new String(buffer,0,num);
                        fmsg+=s0;
                        for(i=0;i < num;i++){
                            if((buffer[i] == 0x0d)&&(buffer[i+1]==0x0a)){
                                buffer_new[n] = 0x0a;
                                i++;
                            }else{
                                buffer_new[n] = buffer[i];
                            }
                            n++;
                        }
                        String s = new String(buffer_new,0,n);
                        smsg+=s;
                        if(is.available()==0)break;  //
                    }
                        handler.sendMessage(handler.obtainMessage());                       
                    }catch(IOException e){
                    }
            }
        }
    };
    

    欢迎留言

    avatar
      Subscribe  
    Notify of