ym——Android从零开始(29)(Bluetooth2.0+4.0)(新)

转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持!


Bluetooth蓝牙 2.0

本章讲解的是蓝牙2.0通讯,如想学习蓝牙4.0通讯:点击查看

蓝牙,是一种支持设备短距离通信(一般10m内)的无线电技术。能在包括移动电话、PDA、无线耳机、笔记本电脑、相关外设等众多设备之间进行无线信息交换。

1.png

蓝牙标识的来源

蓝牙这个标志的设计:它取自Harald Bluetooth 名字中的「H」和「B」。蓝牙标志的来历个字母,用古北欧字母来表示,将这两者结合起来,就成为了蓝牙的 logo

2.png

Android包含了对蓝牙网络协议栈的支持,这使得安卓程序之间能够通过手机蓝牙无线连接交换数据。Android的应用程序框架提供了访问蓝牙功能的APIs。这些APIs让应用程序能够无线连接其他蓝牙设备,实现点对点,或点对多点的无线交互功能。

使用蓝牙APIs,一个Android应用程序能够实现下列功能:

获得本地蓝牙适配器( local Bluetooth adapter )用于配对蓝牙设备

扫描其他蓝牙设备;

通过服务发现(service discovery)连接其他设备;

建立RFCOMM信道(channels)

数据通信;

使用蓝牙功能,我们至少需要声明两方面的权限:BLUETOOTHBLUETOOTH_ADMIN

BLUETOOTH权限实现蓝牙通信,例如请求一个连接、接受一个连接和传输数据

BLUETOOTH_ADMIN权限,初始化device discovery或者管理蓝牙设置(Bluetooth settings)。大多数应用程序必须具有这个权限才能够发现本地蓝牙设备。

manifest文件中声明程序的蓝牙权限:

<uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permissionandroid:name="android.permission.BLUETOOTH" />


蓝牙基本代码开启蓝牙

核心代码:

//获得蓝牙适配器
ba=BluetoothAdapter.getDefaultAdapter();
       //如果蓝牙不可用,设置其可用
       if(!ba.isEnabled()){
//三种开启方式 任选一种即可
//1
ba.enable();
//2
Intent intent = newIntent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
       intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,300);
                  startActivity(intent);
//3
Intent in=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivity(in);
       }
       //设置蓝牙可见。
       if(ba.getScanMode()!=BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE){
       Intent in=new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
       //设置蓝牙在300秒之内可被发现
       in.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
       startActivity(in);
       }

关闭蓝牙

public void close(View v){
           BluetoothAdapter bluetoothAdapter =BluetoothAdapter.getDefaultAdapter();
           if(bluetoothAdapter != null){
                  if(bluetoothAdapter.isEnabled()){
                         //关闭
                         bluetoothAdapter.disable();
                  }
           }
}

获得已有的连接蓝牙

    public void get(View v){
           BluetoothAdapter bluetoothAdapter =BluetoothAdapter.getDefaultAdapter();
           if(bluetoothAdapter != null){
                  if(!bluetoothAdapter.isEnabled()){
                         bluetoothAdapter.enable();
                  }
                  Set<BluetoothDevice>devices = bluetoothAdapter.getBondedDevices();
                  for(BluetoothDevicedevice:devices){
                         Log.i("i","name:"+device.getName()+",address:"+device.getAddress());
                  }
           }
    }

扫描可用的蓝牙

   public void scan(View v){
           BluetoothAdapter bluetoothAdapter =BluetoothAdapter.getDefaultAdapter();
           if(bluetoothAdapter != null){
                  if(!bluetoothAdapter.isEnabled()){
                         bluetoothAdapter.enable();
                  }
                  //开始扫描
                  bluetoothAdapter.startDiscovery();
                  //注册广播接收者
                  IntentFilterfilter = new IntentFilter();
                  //发现蓝牙设备
                  filter.addAction(BluetoothDevice.ACTION_FOUND);
                  //扫描完成
                  filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
                  registerReceiver(newMyReceiver(), filter);
           }
    }
   
   private class MyReceiver extends BroadcastReceiver{
              @Override
              public void onReceive(Context context,Intent intent) {
                     //TODO Auto-generated method stub
                     Stringaction = intent.getAction();
                     if(action.equals(BluetoothDevice.ACTION_FOUND)){
                            BluetoothDevice device =intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                            Log.i("i","name:"+device.getName()+",address:"+device.getAddress());
                     }elseif(action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)){
                            Log.i("i", "扫描完成");
                     }
              }
           
    }


蓝牙通讯

3.png

UUID要一样一样的(类似于网络编程IP地址)

客户端

要进行蓝牙通信服务端完成下面五个步骤:

增加权限

启动蓝牙

创建ServerSocket监听本地蓝牙、等待连接

接收连接,创建Socket

数据通信

public class Test_2_14_serverActivity extends Activity {
    /** Called when the activity is first created. */
    private Handler mHandler = new Handler(){
        public void handleMessage(Message msg){
            Toast.makeText(Test_2_14_serverActivity.this, "下载完成", 1).show();
        };
    };
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 得到蓝牙
        BluetoothAdapter ba =BluetoothAdapter.getDefaultAdapter();
        if (ba != null) {
            if (!ba.isEnabled()) {
                ba.enable();
            }
            try {
                // 创建蓝牙服务器
                final BluetoothServerSocket bss = ba
                        .listenUsingRfcommWithServiceRecord(
                                "jky",
                                UUID.fromString("974E7FCD-7FD8-AD1B-C160-A2023FD216B9"));
                new Thread() {
                    public void run() {
                        while (true) {
                            // 等待 客户蓝牙
                            try {
                                
                                BluetoothSocket bs =bss.accept();
                                // 拿到客户蓝牙传输过来的流
                                InputStream is =bs.getInputStream();
                                // 准备一个输出流写入本地sdcard下面
                                File file =
new File(Environment.getExternalStorageDirectory(),"jky.mp3");
                                OutputStream os =
new FileOutputStream(file);
                                byte[] buffer = new byte[1024];
                                int len = 0;
                                while((len = is.read(buffer))!=-1)
                                {
                                    os.write(buffer, 0, len);
                                }
                                os.close();
                                is.close();
                                Message msg = mHandler.obtainMessage();
                                msg.sendToTarget();
                            } catch (Exception e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                    };
                }.start();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

客户端需要完成以下五个步骤

增加权限

启动蓝牙

查找可连接蓝牙设备

请求连接远程蓝牙设备,获得Socket

数据通信

public class Test_2_14_clienActivity extends Activity implements OnItemClickListener{
    /** Called when the activity is first created. */
    private List<BluetoothDevice>devices =
newArrayList<BluetoothDevice>();
    private ListView lv;
    private MyAdapter adapter;
    private BluetoothDevice bluetoothDevice;
    private TextView tv_song_name;
    private Handler mHandler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                    Toast.makeText(getApplicationContext(), "OK", 1).show();
            
               
            }
    };
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        adapter = new MyAdapter();
        lv = (ListView)findViewById(R.id.lv);
        lv.setAdapter(adapter);
        lv.setOnItemClickListener(this);
        tv_song_name = (TextView)findViewById(R.id.tv_song_name);
    }
    private class MyAdapter extends BaseAdapter{
        @Override
        public int getCount() {
            // TODO Auto-generated methodstub
            return devices.size();
        }
        @Override
        public Object getItem(int position) {
            // TODO Auto-generated methodstub
            return devices.get(position);
        }
        @Override
        public long getItemId(int position) {
            // TODO Auto-generated methodstub
            return position;
        }
        @Override
        public View getView(int position, ViewconvertView, ViewGroup parent) {
            // TODO Auto-generated methodstub
            View view = null;
            ViewHolder Holder = null;
            if(convertView == null)
            {
                Holder = new ViewHolder();
                view =getLayoutInflater().inflate(R.layout.main_item, null);
                Holder.name =
(TextView) view.findViewById(R.id.tv_name);
                Holder.address =
(TextView) view.findViewById(R.id.tv_address);
                view.setTag(Holder);
               
            }else
            {   
                view = convertView;
                Holder = (ViewHolder)view.getTag();
            }
                BluetoothDevice bd = devices.get(position);
                Holder.name.setText(bd.getName());
                Holder.address.setText(bd.getAddress());
            return view;
        }
       private class ViewHolder
       {
           TextView name;
           TextView address;
       }
      
    }
    public void send(View v)
    {
       BluetoothAdapterba = BluetoothAdapter.getDefaultAdapter();
       if(ba!=null){
           if(!ba.isEnabled())
           {
               ba.enable();
               
           }
           new Thread(){
               public void run() {
                   try {
                       //  生成一个蓝牙客户端
                        BluetoothSocket bs =
bluetoothDevice.createRfcommSocketToServiceRecord(UUID.fromString("5EDE275A-050B-D2A0-01F3-89494A5399AC"));
                        // 连接
                        bs.connect();
                        // 拿到路径
                        String name =
tv_song_name.getText().toString();
                        // 找到本地文件
                        File file = new File(name);
                        InputStream is = new FileInputStream(file);
                        // 写出去
                        OutputStream os =bs.getOutputStream();
                        byte[] buffer = new byte[1024];
                        int len = 0;
                        while((len = is.read(buffer))!= -1)
                        {
                            Log.i("i", "写写写");
                            os.write(buffer, 0, len);
                        }
                        os.close();
                        is.close();
                        Log.i("i", "写写写完");
                        Message obtainMessage =
mHandler.obtainMessage();
                        obtainMessage.sendToTarget();
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                  
               };
           }.start();
       }
      
      
      
    }
    public void query(View v){
       devices.clear();
       adapter.notifyDataSetChanged();
       bluetoothDevice = null;
        
       BluetoothAdapterba = BluetoothAdapter.getDefaultAdapter();
       if(ba != null)
       {
           if(!ba.isEnabled())
           {
               ba.enable();
           }
           // 查询现有蓝牙
           ba.startDiscovery();
           IntentFilter filter = new IntentFilter();
           filter.addAction(BluetoothDevice.ACTION_FOUND);
           filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
           registerReceiver(new MyReceiver(), filter);
       }
    }
    // 查询歌曲广播接受者
    private class MyReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context,Intent intent) {
            // TODO Auto-generated methodstub
            String action = intent.getAction();
            if(action.equals(BluetoothDevice.ACTION_FOUND))
            {
                BluetoothDevice bd =
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                devices.add(bd);
                adapter.notifyDataSetChanged();
            }
        }
      
    }
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
            long id) {
         bluetoothDevice = devices.get(position);
        
    }
}


课后问题:

1.蓝牙主要是用于什么方面?

通讯


2.BluetoothAdapter和BluetoothDevices两个类    分别表示什么?

本机蓝牙、发现的蓝牙



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值