蓝牙+文件传输+ 聊天页面
首先判断手机版本
//把要给的权限放进字符串组
String[] strings=new String[]{"android.permission.ACCESS_COARSE_LOCATION","android.permission.ACCESS_FINE_LOCATION","android.permission.READ_EXTERNAL_STORAGE","android.permission.WRITE_EXTERNAL_STORAGE"};
if (Build.VERSION.SDK_INT >=Build.VERSION_CODES.M) {
if (ActivityCompat.checkSelfPermission(this,strings[0]) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(strings,100);
}
}
蓝牙权限
<!-- 用于进行网络定位 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 用于访问GPS定位 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH"/>
打开蓝牙
Intent intent = new Intent();
intent.setAction(BluetoothAdapter.ACTION_REQUEST_ENABLE);//开启蓝牙
intent.setAction(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);//允许被搜索
intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,200);//允许被搜索200s
startActivityForResult(intent,100);
关闭蓝牙
bluetoothAdapter.disable();//强制关闭蓝牙
展示信息
展示已经配对的 和 搜索附近的 listview 、adapter、list集合必须分开
ListView already_listview,select_listview;
MyAdapter already_adapter;
MyAdapter select_adapter;
List<BluetoothDevice> already_lists=new ArrayList<>();
List<BluetoothDevice> select_lists=new ArrayList<>();
显示已经配对
Set<BluetoothDevice> devices = adapter.getBondedDevices();//已经配对的设备
already_lists.addAll(devices);//将设备添加到集合中
already_adapter.notifyDataSetChanged();//通知适配器更新
展示在列表并发送文件:
already_listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, final int i, final long l) {
new Thread(new Runnable() {
@Override
public void run() {
BluetoothDevice bluetoothDevice = already_lists.get(i); // 拿到点击的已连接设备
try {
BluetoothSocket socket = bluetoothDevice.createInsecureRfcommSocketToServiceRecord(uuid);
//连接
socket.connect();
if (socket.isConnected()) {
OutputStream os = socket.getOutputStream();
int max = (int) new File("/sdcard/jiligulu.mp4").length();
os.write((max+"").getBytes());
seekBar.setMax(max);
//最好放线程中睡一秒,否则会和发送的内容拼一起
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
FileInputStream fis = new FileInputStream("/sdcard/jiligulu.mp4");
int len=0;
int count=0;
byte[] bys = new byte[1024];
while((len=fis.read(bys))!=-1){
os.write(bys,0,len);
count+=len;
Message obtain = Message.obtain();
obtain.what=101;
obtain.obj=count;
handler.sendMessage(obtain);
if (count==max) {
Toast.makeText(MainActivity.this, "发送完毕", Toast.LENGTH_SHORT).show();
break;
}
}
Toast.makeText(MainActivity.this, "发送成功", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(MainActivity.this, "发送失败", Toast.LENGTH_SHORT).show();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
});
搜索附近蓝牙设备,点击能够进行配对
adapter.startDiscovery();
展示在列表:
select_listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
BluetoothDevice device = select_lists.get(i); //拿到点击的蓝牙设备
device.createBond(); // 建立连接
}
});
用广播
声明、注册:
myBrodcast=new MyBrodcast();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
registerReceiver(myBrodcast,intentFilter);
seekBar =findViewById(R.id.seekbar);
class MyBrodcast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i("TAG", "开始添加: ");
if (intent.getAction().equals(BluetoothDevice.ACTION_FOUND)) { //扫描一个
//获取设备 - BluetoothDevice.EXTRA_DEVICE
BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.i("TAG", "onReceive: "+bluetoothDevice);
select_lists.add(bluetoothDevice);
select_adapter.notifyDataSetChanged();
}
}
}
传输文件
谁发消息,谁是客户端,接收消息的是服务端
读写内存的权限要给
客户端发送文件代码:
already_listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, final int i, final long l) {
new Thread(new Runnable() {
@Override
public void run() {
BluetoothDevice bluetoothDevice = already_lists.get(i); // 拿到点击的已连接设备
try {
BluetoothSocket socket = bluetoothDevice.createInsecureRfcommSocketToServiceRecord(uuid);
//连接
socket.connect();
if (socket.isConnected()) {
OutputStream os = socket.getOutputStream();
int max = (int) new File("/sdcard/jiligulu.mp4").length();
os.write((max+"").getBytes());
seekBar.setMax(max);
//最好放线程中睡一秒,否则会和发送的内容拼一起
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
FileInputStream fis = new FileInputStream("/sdcard/jiligulu.mp4");
int len=0;
int count=0;
byte[] bys = new byte[1024];
while((len=fis.read(bys))!=-1){
os.write(bys,0,len);
count+=len;
Message obtain = Message.obtain();
obtain.what=101;
obtain.obj=count;
handler.sendMessage(obtain);
if (count==max) {
Toast.makeText(MainActivity.this, "发送完毕", Toast.LENGTH_SHORT).show();
break;
}
}
Toast.makeText(MainActivity.this, "发送成功", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(MainActivity.this, "发送失败", Toast.LENGTH_SHORT).show();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
});
服务端
MainActivity:
package com.example.day6_2_server;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.SeekBar;
import android.widget.Toast;
import java.io.IOException;
import java.util.UUID;
public class MainActivity extends AppCompatActivity {
BluetoothManager manager;
BluetoothAdapter adapter;
SeekBar seekBar;
private UUID uuid = UUID.fromString("00001106-0000-1000-8000-00805F9B34FB");//蓝牙通讯规范
String[] strings=new String[]{"android.permission.ACCESS_COARSE_LOCATION","android.permission.ACCESS_FINE_LOCATION","android.permission.WRITE_EXTERNAL_STORAGE","android.permission.READ_EXTERNAL_STORAGE"};
Handler handler=new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if (msg.what==101) {
seekBar.setMax((Integer) msg.obj);
}else if(msg.what==102){
seekBar.setProgress((Integer) msg.obj);
}else if(msg.what==103){
Toast.makeText(MainActivity.this, "传输完成", Toast.LENGTH_SHORT).show();
}
}
};
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
seekBar=findViewById(R.id.seekbar);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ActivityCompat.checkSelfPermission(this,strings[0])!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(strings,101);
}
}
manager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
adapter = manager.getAdapter();
//开启线程 接收客户端连接
server();
}
private void server() {
new Thread(new Runnable() {
@Override
public void run() {
Log.i("TAG", "开启服务端");
try {
BluetoothServerSocket socket = adapter.listenUsingInsecureRfcommWithServiceRecord(adapter.getName(), uuid);
//无线连接客户端
while (true) {
BluetoothSocket accept = socket.accept();
Log.i("TAG", "监听到一个设备连接:"+accept.getRemoteDevice().getName());
//连接后 ,开始接收客户端发来的消息
new ServerThread(accept,handler).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
ServerThread:
package com.example.day6_2_server;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class ServerThread extends Thread{
BluetoothSocket socket;
Handler handler;
public ServerThread(BluetoothSocket socket, Handler handler) {
this.socket = socket;
this.handler = handler;
}
@Override
public void run() {
Log.i("TAG", "开启服务线程 ");
new Thread(new Runnable() {
@Override
public void run() {
try {
InputStream is = socket.getInputStream();
int len=0;
byte[] bys = new byte[1024];
int count=0; // 进度
int max = is.read(bys);
String s = new String(bys, 0, max);
int i = Integer.parseInt(s);
Message obtain = Message.obtain();
obtain.what=101;
obtain.obj=i;
handler.sendMessage(obtain);
FileOutputStream fos = new FileOutputStream("/sdcard/yu.mp4");
while ((len=is.read(bys))!=-1) {
fos.write(bys,0,len);
count+=len;
Message obtain1 = Message.obtain();
obtain1.what=102;
obtain1.obj=count;
handler.sendMessage(obtain1);
if (count==max) {
handler.sendEmptyMessage(103);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
聊天页面Activity
package com.example.day6_bluetooth;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import com.example.day6_bluetooth.adapter.ChatAdapter;
import com.example.day6_bluetooth.message.Message;
import com.example.day6_bluetooth.thread.SendThread;
import com.example.day6_bluetooth.thread.ServerThread;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class ChatActivity extends AppCompatActivity {
BluetoothManager bluetoothManager;
BluetoothAdapter bluetoothAdapter;
BluetoothDevice device;
LinearLayoutManager linearLayoutManager;
TextView header_name;
RecyclerView recyclerView;
EditText getMessage;
ChatAdapter adapter;
List<Message> lists=new ArrayList<>();
String path="https://www.baidu.com/img/bd_logo1.png";
Handler handler=new Handler(){
@Override
public void handleMessage(@NonNull android.os.Message msg) {
super.handleMessage(msg);
if (msg.what==110) {
String s = msg.obj.toString();
if(s.contains("https")){
lists.add(new Message((String) msg.obj,Message.LEFT_pic));
adapter.notifyDataSetChanged();
}else{
lists.add(new Message((String) msg.obj,Message.LEFT));
adapter.notifyDataSetChanged();
}
}
}
};
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
server();
init();
}
private void server() {
new Thread(new Runnable() {
@Override
public void run() {
Log.i("yu", "服务端开启 ");
try {
BluetoothServerSocket socket = bluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord(bluetoothAdapter.getName(), MainActivity.uuid);
while(true){
Log.i("yu", "等待设备连接 ");
BluetoothSocket accept = socket.accept();
Log.i("yu", "监听到一个设备已连接: "+accept.getRemoteDevice().getName());
new ServerThread(accept,handler).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
private void init() {
bluetoothManager= (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
bluetoothAdapter=bluetoothManager.getAdapter();
header_name=findViewById(R.id.chat_header);
recyclerView=findViewById(R.id.chat_recyclerview);
getMessage=findViewById(R.id.edit_message);
device = getIntent().getParcelableExtra("device");
header_name.setText(device.getName());
adapter=new ChatAdapter(lists);
recyclerView.setAdapter(adapter);
linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
}
public void click(View view) {
switch (view.getId()){
case R.id.sendMessage:
String message = getMessage.getText().toString();
Log.i("yu", "发送的消息: "+message);
try {
BluetoothSocket socket = device.createInsecureRfcommSocketToServiceRecord(MainActivity.uuid);
new SendThread(message,socket).start();
} catch (IOException e) {
e.printStackTrace();
}
lists.add(new Message(message,Message.RIGHT));
adapter.notifyDataSetChanged();
linearLayoutManager.scrollToPosition(lists.size()-1);
break;
case R.id.sendPicture:
Log.i("yu", "发送的消息: "+path);
try {
BluetoothSocket socket = device.createInsecureRfcommSocketToServiceRecord(MainActivity.uuid);
new SendThread(path,socket).start();
} catch (IOException e) {
e.printStackTrace();
}
lists.add(new Message(path,Message.RIGHT_pic));
adapter.notifyDataSetChanged();
linearLayoutManager.scrollToPosition(lists.size()-1);
break;
}
}
}