본문 바로가기
Android

Bluetooth file & text transfer #3 client

by 캡틴노랑이 2021. 3. 17.
반응형

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

댓글