I am developing an app in which I need to transfer data in file between two devices.
I have seen tutorial regarding Bluetooth chat but can't figure out what stuff needed for file transfer. How can I do this?
A greater distance between the two devices results in a weaker Bluetooth signal and slower file transmission. 3. If the file is large in size (for example, larger than 100 MB), it is recommended that you use Wi-Fi, USB, or another transfer method.
Possible Reasons. File Transfer is disabled on your Android phone or tablet. The USB cable you're using to connect both devices is damaged or malfunctioning. Similarly, it can be an issue with the USB port on your Mac.
On your phone, tap the "Charging this device via USB" notification. Under "Use USB for," select File Transfer. An Android File Transfer window will open on your computer. Use it to drag files.
Today i had the same task & after spending couple of hours i'd achieved this. I'm posting the whole code so someone else can easily understand this. This is my Activity:
package com.aqua.bluetoothfiletransfer.indragni;
import java.io.File;
import java.util.List;
import android.Manifest;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.aqua.bluetoothfiletransfer.R;
public class MainActivity extends AppCompatActivity {
private static final int DISCOVER_DURATION = 300;
private static final int REQUEST_BLU = 1;
String path;
private static final String[] INITIAL_PERMS = {Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.READ_CONTACTS,
Manifest.permission.WRITE_CONTACTS,
Manifest.permission.CAMERA,
Manifest.permission.ACCESS_FINE_LOCATION};
private static final int INITIAL_REQUEST = 1337;
private static final int REQUEST_WRITE_STORAGE = INITIAL_REQUEST + 4;
TextView textView_FileName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mainn);
textView_FileName = (TextView) findViewById(R.id.textView_FileName);
if (!canAccessLocation() || !canAccessCamera() || !canAccessWriteStorage() || !canAccessReadStorage() || !canAccessReadContacts() || !canAccessWriteContacts()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(INITIAL_PERMS, INITIAL_REQUEST);
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_WRITE_STORAGE:
if (canAccessWriteStorage()) {
//reload my activity with permission granted or use the features what required the permission
System.out.println("permission grantedddd");
} else {
Toast.makeText(this, "The app was not allowed to write to your storage. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show();
}
break;
}
}
public void sendViaBluetooth(View v) {
if (path == null) {
Toast.makeText(this, "Please select file first", Toast.LENGTH_SHORT).show();
return;
}
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
if (btAdapter == null) {
Toast.makeText(this, "Bluetooth is not supported on this device", Toast.LENGTH_LONG).show();
} else {
enableBluetooth();
}
}
public void getFile(View v) {
Intent mediaIntent = new Intent(Intent.ACTION_GET_CONTENT);
mediaIntent.setType("*/*"); //set mime type as per requirement
startActivityForResult(mediaIntent, 1001);
}
public void enableBluetooth() {
Intent discoveryIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoveryIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, DISCOVER_DURATION);
startActivityForResult(discoveryIntent, REQUEST_BLU);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == DISCOVER_DURATION && requestCode == REQUEST_BLU) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setType("*/*");
File f = new File(path);
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(f));
PackageManager pm = getPackageManager();
List<ResolveInfo> appsList = pm.queryIntentActivities(intent, 0);
if (appsList.size() > 0) {
String packageName = null;
String className = null;
boolean found = false;
for (ResolveInfo info : appsList) {
packageName = info.activityInfo.packageName;
if (packageName.equals("com.android.bluetooth")) {
className = info.activityInfo.name;
found = true;
break;
}
}
if (!found) {
Toast.makeText(this, "Bluetooth havn't been found",
Toast.LENGTH_LONG).show();
} else {
intent.setClassName(packageName, className);
startActivity(intent);
}
}
} else if (requestCode == 1001
&& resultCode == Activity.RESULT_OK) {
Uri uriPath = data.getData();
Log.d("", "Video URI= " + uriPath);
path = getPath(this, uriPath);// "/mnt/sdcard/FileName.mp3"
System.out.println("pathhhh " + path);
textView_FileName.setText(path);
} else {
Toast.makeText(this, "Bluetooth is cancelled", Toast.LENGTH_LONG)
.show();
}
}
private boolean canAccessWriteStorage() {
return (hasPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE));
}
private boolean canAccessReadStorage() {
return (hasPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
}
private boolean canAccessReadContacts() {
return (hasPermission(Manifest.permission.READ_CONTACTS));
}
private boolean canAccessWriteContacts() {
return (hasPermission(Manifest.permission.WRITE_CONTACTS));
}
private boolean canAccessCamera() {
return (hasPermission(Manifest.permission.CAMERA));
}
private boolean canAccessLocation() {
return (hasPermission(Manifest.permission.ACCESS_FINE_LOCATION));
}
private boolean hasPermission(String perm) {
return (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(this, perm));
}
public static String getPath(final Context context, final Uri uri) {
final boolean isKitKatOrAbove = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKatOrAbove && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
// TODO handle non-primary volumes
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{
split[1]
};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
* @param context The context.
* @param uri The Uri to query.
* @param selection (Optional) Filter used in the query.
* @param selectionArgs (Optional) Selection arguments used in the query.
* @return The value of the _data column, which is typically a file path.
*/
public static String getDataColumn(Context context, Uri uri, String selection,
String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {
column
};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
}
This is my layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:id="@+id/textView_FileName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:text="Please select file"
android:textSize="18sp" />
<Button
android:id="@+id/button_GetFile"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="getFile"
android:text="Get file from device" />
<Button
android:id="@+id/button_SendFile"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="sendViaBluetooth"
android:text="Send via Bluetooth" />
</LinearLayout>
Last step is please declare all the permissions in manifest:
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
That's it.
File transfer is same like you send message. First you convert file to input stream and then transfer this to founded device.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With