반응형
test device : note 4
android os : Marshmallow 6.0
Client Source
activity_bluetooth2.xml
Bluetooth2Activity.java
package com.example.sampleproject;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.FileUtils;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import com.example.sampleproject.Data.BlueToothData;
import com.example.sampleproject.Data.SettingValue;
import com.example.sampleproject.Helper.DataTypeHelper;
import com.example.sampleproject.Norang.NorangActivity;
public class Bluetooth2Activity extends NorangActivity {
private TextView tvLog;
private BluetoothAdapter bluetoothAdapter;
private BluetoothSocket socket;
private ClientThread clientThread;
private ListenerThread listenerThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bluetooth2);
InitializeControl();
InitializeCommonDataBind();
}
private void InitializeControl() {
toolbar = findViewById(R.id.tbToolBar);
setToolbar("");
tvLog=findViewById(R.id.tvLog);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.READ_EXTERNAL_STORAGE)) {
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},1);
}
}
if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
}
private void InitializeCommonDataBind() {
bluetoothAdapter= BluetoothAdapter.getDefaultAdapter();
if(bluetoothAdapter==null){
Toast.makeText(this, "이 기기에는 블루투스가 없습니다.", Toast.LENGTH_SHORT).show();
finish();
return;
}
if(bluetoothAdapter.isEnabled()){
DiscoveryBluetoothDevices();
}else{
Intent intent= new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, SettingValue.BT_REQ_ENABLE);
}
}
private Handler listenerHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
BlueToothData data = (BlueToothData)msg.obj;
switch(data.getMessage_type())
{
case TEXT:
tvLog.append("new " + new String(data.getData(), 0, data.getData().length));
break;
case FILE:
Log.d("listenerHandler", "receive file");
try{
Log.d("listenerHandler", "Save");
File file = new File("/storage/emulated/0/1234/00001.jpg"); //new File(data.getFileName());
FileOutputStream fos = new FileOutputStream(file);
fos.write(data.getData());
fos.close();
Log.d("listenerHandler", "End");
tvLog.append("wrote the file.");
}catch(Throwable e){
Log.e("file", "listenerHandler: Error writing to file. " + e.getMessage() );
}
break;
}
}
};
protected void DiscoveryBluetoothDevices(){
Intent intent= new Intent(this, BluetoothDeviceListActivity.class);
startActivityForResult(intent,SettingValue.BT_REQ_DISCOVERYABLE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode){
case SettingValue.BT_REQ_ENABLE:
if(resultCode==RESULT_CANCELED){
Toast.makeText(this, "사용 불가", Toast.LENGTH_SHORT).show();
finish();
}else{
DiscoveryBluetoothDevices();
}
break;
case SettingValue.BT_REQ_DISCOVERYABLE:
if(resultCode==RESULT_OK){
String deviceAddress= data.getStringExtra("Address");
clientThread= new ClientThread(deviceAddress);
clientThread.start();
}
break;
}
}
public void btnSendTextOnClick(View view)
{
listenerThread.write(SettingValue.BT_MESSAGE_TYPE.TEXT, "Server sent test message.\n");
}
public void btnSendFileOnClick(View view)
{
///storage/self/primary/DCIM/Camera/20190616_233731.jpg //1m
//listenerThread.write(SettingValue.BT_MESSAGE_TYPE.FILE, "/storage/emulated/0/Download/m_1548925438_9398_i16252312250.gif");
listenerThread.write(SettingValue.BT_MESSAGE_TYPE.FILE, "/storage/emulated/0/DCIM/Camera/20190616_233731.jpg");
}
@Override
protected void onDestroy() {
try {
clientThread.interrupt();
listenerThread.interrupt();
socket.close();
} catch(Exception e) { }
super.onDestroy();
}
//inner class////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class ClientThread extends Thread{
String address;
public ClientThread(String address)
{
this.address = address;
}
@Override
public void run() {
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
try {
socket= device.createInsecureRfcommSocketToServiceRecord(SettingValue.BT_UUID);
socket.connect();
listenerThread = new ListenerThread(socket);
listenerThread.start();
showText("Connected server.\n");
listenerThread.write(SettingValue.BT_MESSAGE_TYPE.TEXT, "note 4\n");
} catch (IOException e) {
Log.e("SendData", e.getMessage());
}
}
public void showText(final String msg){
runOnUiThread(new Runnable() {
@Override
public void run() {
tvLog.append(msg);
}
});
}
}
public class ListenerThread extends Thread {
protected BluetoothSocket mSocket;
private final InputStream inStream;
private final OutputStream outStream;
private int nSendingType = 0; //0 length, 1 data
private int nDataSize = 0;
public ListenerThread(BluetoothSocket socket) {
showText("\nListenerThread will run.\n");
mSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = mSocket.getInputStream();
tmpOut = mSocket.getOutputStream();
} catch (IOException e) {
Log.e("ListenerThread", e.getMessage());
}
inStream = tmpIn;
outStream = tmpOut;
}
public void run() {
byte[] buffer; // buffer store for the stream
showText("ListenerThread is waiting.\n");
// Keep listening to the InputStream until an exception occurs
while (true) {
// Read from the InputStream
buffer = new byte[SettingValue.BT_SEND_DATABUFFER_SIZE];
try {
if(nSendingType == 0)
{
//Log.e("nSendingType", Integer.toString(nSendingType));
inStream.read(buffer);
ByteArrayInputStream byteIn = new ByteArrayInputStream(buffer);
nDataSize = (int)(new ObjectInputStream(byteIn)).readObject();
nSendingType = 1;
//Log.e("nDataSize", Integer.toString(nDataSize));
}
else
{
int byteNo = 0;
int writeByte = 0;
int bufferSize = nDataSize;
Log.e("elseFileDataSize", Integer.toString(nDataSize));
while (nDataSize != writeByte)
{
byteNo = inStream.read(buffer, writeByte, bufferSize);
writeByte += byteNo;
bufferSize = bufferSize - byteNo;
Log.e("writeByte", Integer.toString(writeByte));
Log.e("byteNo", Integer.toString(byteNo));
}
ByteArrayInputStream byteIn = new ByteArrayInputStream(buffer);
BlueToothData data = (BlueToothData)(new ObjectInputStream(byteIn)).readObject();
//Message send
Message msg = new Message();
msg.what = 1;
msg.obj = (BlueToothData)data;
listenerHandler.sendMessage(msg);
nSendingType = 0;
nDataSize = 0;
}
} catch (Exception e) {
Log.e("ListenerThread run", e.getMessage());
break;
}
}
}
public void write(SettingValue.BT_MESSAGE_TYPE message_type, String text) {
try {
BlueToothData data = new BlueToothData();
byte[] buffer = new byte[10240000]; //10M
switch (message_type)
{
case TEXT :
Log.d("write", "write: Writing to outputstream: " + text);
data.setMessage_type(message_type);
data.setData(text.getBytes());
break;
case FILE:
try{
FileInputStream fis = new FileInputStream(text);
BufferedInputStream bis = new BufferedInputStream(fis);
int length = bis.read(buffer);
Log.d("file", "start to send file.");
data = new BlueToothData();
data.setMessage_type(SettingValue.BT_MESSAGE_TYPE.FILE);
data.setFileName(text);
data.setData(buffer);
} catch (Exception e) {
Log.e("write", "file read Error. " + e.getMessage() );
}
break;
}
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
oos.writeObject(data);
showText(Integer.toString(baos.toByteArray().length)+ "\n");
//////////////////////////////////
//send byte length.
ByteArrayOutputStream baosL = new ByteArrayOutputStream();
ObjectOutputStream oosL = new ObjectOutputStream(baosL);
oosL.writeObject(baos.toByteArray().length);
showText(String.valueOf(baosL.toByteArray().length) + "\n");
outStream.write(baosL.toByteArray());
outStream.flush();
//send byte length.
//////////////////////////////////
//send main data.
outStream.write(baos.toByteArray());
outStream.flush();
} catch (Exception e) {
Log.e("write", "ObjectOutputStream Error. " + e.getMessage());
}
}
catch(Exception e)
{
Log.e("write", "ByteArrayOutputStream Error. " + e.getMessage() );
}
//data send
} catch (Exception e) {
Log.e("write", "write: Error writing to output stream. " + e.getMessage() );
}
}
public void showText(final String msg){
runOnUiThread(new Runnable() {
@Override
public void run() {
tvLog.append(msg);
}
});
}
}
//inner class////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
*NorangActivity는 기본 Activity사용하면 됨.
Marshmallow 6.0에서만 테스트 되었음. 그 이외의 버전은... 안될 수 있음...
반응형
'Android' 카테고리의 다른 글
Android QRcode Create (2) | 2021.03.17 |
---|---|
Android Barcode Create (555) | 2021.03.17 |
Bluetooth file & text transfer #2 server (4) | 2021.03.17 |
Bluetooth file & text transfer #1 etc (6) | 2021.03.17 |
Android ListView Sorting (6) | 2021.01.03 |
댓글