Android studio bluetooth file transfer drops transfer

26 Views Asked by At

I wrote a program in Android Studio to send a file via Bluetooth automatically to a raspberry Pi. But when I run the program the file transfers till 0.5% then it shows nothing, that means the program is stuck in the loop but not transferring the file.

MainActivity.java

package com.example.myapplication;


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.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;

// Declare a socket variable





public class MainActivity extends AppCompatActivity {

    public static final int REQUEST_BLUETOOTH_PERMISSION = 1;
    private static final int PERMISSION_REQUEST_CODE =1 ;
    final Handler mHandler = new Handler(Looper.getMainLooper());
    private int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 0;
    private FileInputStream fileInputStream;
    private OutputStream outputStream;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);



        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.BLUETOOTH},
                    REQUEST_BLUETOOTH_PERMISSION);
        } else {
            StartBluetoothTransfer();
        }
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            // Permission is not granted
            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
            } else {
                // No explanation needed, we can request the permission.
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
            }
        }

    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_BLUETOOTH_PERMISSION) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission granted, start Bluetooth transfer
                StartBluetoothTransfer();
            } else {
                Toast.makeText(this, "Bluetooth permission is required for this app.", Toast.LENGTH_SHORT).show();
            }
        }
    }

    private void StartBluetoothTransfer() {
        // Bluetooth transfer will be handled in a separate thread
        Thread bluetoothThread = new Thread(new BluetoothTransferThread());
        bluetoothThread.start();
    }
    private class BluetoothTransferThread implements Runnable {
        @Override
        public void run() {

            BluetoothSocket socket = null;
            BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();

            if (adapter == null || !adapter.isEnabled()) {
                showToastOnMainThread("Turn on Bluetooth");
                return;
            }
        if (!adapter.isEnabled()) {
            // Create an Intent to request the user to enable Bluetooth
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            // Start the activity and get the result
            if (ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                // Set the app's package name as data
                intent.setData(Uri.parse("package:" + getPackageName()));
                // Start the activity and get the result
                startActivityForResult(intent, REQUEST_BLUETOOTH_PERMISSION);
                return;}}

            Set<BluetoothDevice> pairedDevices = adapter.getBondedDevices();
            boolean deviceFound = false;

            for (BluetoothDevice device : pairedDevices) {
                if (device.getName().equals("raspberrypi")) {
                    UUID uuid = UUID.fromString("00001106-0000-1000-8000-00805F9B34FB");
                    try {
                        socket = device.createRfcommSocketToServiceRecord(uuid);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                    try {
                        socket.connect(); // Connect the socket to the device
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }

                    if (socket.isConnected()) {
                        deviceFound = true;
                        showToastOnMainThread("device connected to RPi");
                        String filePath = "/storage/emulated/0/BluetoothShare/video.mp4"; // Update this path to the actual video file
                        File videoFile = new File(filePath);


                        if (videoFile.exists()) {
//
                            showToastOnMainThread("file found");



                            try {
                               FileInputStream fileInputStream = new FileInputStream(videoFile);

                                 OutputStream outputStream = socket.getOutputStream();

                                byte[] buffer = new byte[8192];
                                int bytesRead = 0;
                                long totalBytesSent=0;
                                long fileSize = videoFile.length();

                                showToastOnMainThread("File size: " + fileSize + " bytes");


                                while ((bytesRead = fileInputStream.read(buffer)) != -1) {
//                                        showToastOnMainThread("sending file");
                                    outputStream.write(buffer, 0, bytesRead);
//                                        showToastOnMainThread("000");
                                    totalBytesSent += bytesRead;
//                                        showToastOnMainThread("001");
                                    double progress = (double) totalBytesSent / fileSize * 100;
                                    showToastOnMainThread("Progress: " + progress + "%, Bytes read: " + bytesRead);
                                }
                                showToastOnMainThread("File sent to RPi");
                            } catch (FileNotFoundException e) {
                                e.printStackTrace();
                                showToastOnMainThread("File not found"+ e.getMessage());
                            } catch (IOException e) {
                                e.printStackTrace();
                                showToastOnMainThread("Error sending file");
                            }finally {


                                try {
                                    if (fileInputStream != null) {
                                        fileInputStream.close();
                                    }
                                    if (outputStream != null) {
                                        outputStream.close();
                                    }
                                } catch (IOException e) {
                                    e.printStackTrace();
                                    showToastOnMainThread("Error closing streams: " + e.getMessage());
                                }}
                        }else {
                            showToastOnMainThread("Video file does not exist");
                        }
                    }
                    break;
                }

            if (!deviceFound) {
                Toast.makeText(MainActivity.this, "Device not connected", Toast.LENGTH_SHORT).show();
            }
        }}}
    private void showToastOnMainThread(final String message) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
            }
        });
    }

}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyApplication"
        tools:targetApi="30"
        android:requestLegacyExternalStorage="true">
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths" />
        </provider>
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Bluetooth connect" />
    </RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

I was trying to send a video file automatically to a raspberry Pi via bluetooth. Normal bluetooth file transfer is working perfectly but the app I coded drops the file transfer and does nothing. I've set toast to show up as soon as the program exists the transfering loop but it never shows up. The progress toast stops as soon as reaches 0.5%. I tried different buffer sizes but no hope. the file is 33MB .mp4 file. the program shows no errors in the log.The bluetooth connection shows "connected" throughout. I'm using blueman software on the raspberry Pi for bluetooth file transfer. I'm really out of ideas and anything would be appreciated, thank you.

0

There are 0 best solutions below