Data Transferring Between Android Based Mobile Devices
Join the DZone community and get the full member experience.
Join For FreeIn my previous article, I had shared some concepts of socket programming and gone through how to connect two Android devices using socket communication. I suggest that you read that article before you start.
In this part, we will learn how to send data between two devices once they are connected.
First, I'll show a dialog box, asking for the user to choose between an image and video. Then, based on our user's choice, we will use the MediaPicker library for file selection.
xxxxxxxxxx
// setup the alert builder
AlertDialog.Builder builder = new AlertDialog.Builder(mainActivity);
builder.setTitle("Choose type");
// add a list
String[] animals = {"Image", "Video"};
builder.setItems(animals, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case 0: // Image
new ImagePicker.Builder(mainActivity)
.mode(ImagePicker.Mode.CAMERA_AND_GALLERY)
.compressLevel(ImagePicker.ComperesLevel.MEDIUM)
.directory(ImagePicker.Directory.DEFAULT)
.allowMultipleImages(false)
.allowOnlineImages(false)
.build();
break;
case 1: // Video
new VideoPicker.Builder(mainActivity)
.mode(VideoPicker.Mode.CAMERA_AND_GALLERY)
.extension(VideoPicker.Extension.MP4)
.build();
break;
}
}
});
// create and show the alert dialog
AlertDialog dialog = builder.create();
dialog.show();
On activity result, we will get the selected file:
xxxxxxxxxx
List<String> mPaths = data.getStringArrayListExtra(VideoPicker.EXTRA_VIDEO_PATH);
Log.d("File size",mPaths.size()+"");
SendFileModel sendFileModel = new SendFileModel();
Set<File> files = new HashSet<>();
for(int i=0;i<mPaths.size();i++)
files.add(new File(mPaths.get(i)));
sendFileModel.files = new ArrayList<>(files);
sendFileModel.type = FILE;
filesList.add(sendFileModel);
ArrayList<SendFileModel> map = (ArrayList<SendFileModel>) ((MyApplicationClass) (getActivity().getApplicationContext())).getFilesList().clone();
map.add(sendFileModel);
((MyApplicationClass) (getActivity().getApplicationContext())).setMap(map);
if (isSender) {
sendFiles(filesList);
} else if (isReceiver) {
ArrayList<SendFileModel> sendFileModels = ((MyApplicationClass) (getActivity().getApplicationContext())).getFilesList();
tcpClient.sendFiles(sendFileModels);
}
SendFileModel
is a model where we can manage file type, send, receive status, and list all of our files.
xxxxxxxxxx
public class SendFileModel {
public String type;
public boolean isSend;
public boolean isReceived;
public List<File> files;
}
To send a list of files, you need to get the total size of the file and send the size to the receiver. Then, you need to write the file name and the directory name if you want the same directory as per the sender. After that, start writing the content of the file.
xxxxxxxxxx
SendFileModel sendFileModel = list.get(i);
ArrayList<File> files = new ArrayList<>(list.get(i).files);
long totalSize = 0;
float sendSize = 0;
for (int j = 0; j < files.size(); j++) {
totalSize = totalSize + files.get(j).length();
DataOutputStream dataOS = new DataOutputStream(socket.getOutputStream());
OutputStream out = socket.getOutputStream();
dataOS.writeLong(totalSize);
dataOS.writeInt(files.size());
File file = files.get(j);
int size = (int) (file.length());
dataOS.writeInt(size);
dataOS.writeUTF(file.getName());
dataOS.writeUTF(file.getParentFile().getName());
byte[] bytes = new byte[16 * 1024];
InputStream in = new FileInputStream(file);
int count;
while ((count = in.read(bytes)) > 0) {
sendSize = sendSize + count;
timer.schedule(new TimerTask() {
public void run() {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}, 5000);
out.write(bytes, 0, count);
cancelTimer();
float per = (sendSize / totalSize) * 100;
}
}
sendFileModel.isSend = true;
At the receiving end, we need to check the file type, and if the type is file, start reading the data.
xxxxxxxxxx
if (jsonObject.has(JsonHelper.FILE)) {
try {
tcpClient.receiveFiles(new DataInputStream(socket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
First, get the total size, file size, and file name, and create the folder, as per your need. THen, you can start reading files, while sending and receive the files show progress bar to show file is being send.
xxxxxxxxxx
OutputStream outputStream;
for (TCPListener listener : allListeners)
istener.showProgressDialog();
long totalSize = dataOS.readLong();
int totalFile = dataOS.readInt();
float readSize = 0;
for (int i = 0; i < totalFile; i++) {
int len = dataOS.readInt();
String fileName = dataOS.readUTF();
String folderName = dataOS.readUTF();
String path1 = Environment.getExternalStorageDirectory().getPath() + "/DataSharing/" + folderName;
File file = new File(path1);
if (!file.exists()) {
file.mkdirs();
}
File file1 = new File(file, fileName);
byte[] bytes = new byte[16 * 1024];
outputStream = new FileOutputStream(file1);
int count;
while (len > 0 && (count = dataOS.read(bytes, 0, Math.min(bytes.length, len))) > 0) {
len = len - count;
outputStream.write(bytes, 0, count);
outputStream.flush();
readSize = readSize + count;
for (TCPListener listener : allListeners) {
float percentage = (readSize / totalSize) * 100;
listener.updatePercentage((int) (percentage));
}
}
// Once file is added notify the system so that it can be visible immediately
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file1)));
MediaScannerConnection.scanFile(
context,
new String[]{file1.getAbsolutePath()},
null,
(path, uri) -> {
long id = WifiHotSpots.getSongIdFromMediaStore(file1.getPath(), context);
for (TCPListener listener : allListeners) {
listener.fileReceived(id, file1);
}
});
}
for (TCPListener listener : allListeners)
listener.dismissDialog();
Show a message once the file is received.
xxxxxxxxxx
public void fileReceived(long id, File file1) {
mainActivity.runOnUiThread(() -> Toast.makeText(mainActivity, "File received in DataSharing folder", Toast.LENGTH_SHORT).show());
}
Once the file is sent, reset the list in the application class and application class manage list of the file.
xxxxxxxxxx
public void reset(){
this.filesList.clear();
filesList = new ArrayList<>();
}
After that, the file can be seen in the newly created folder. This way, you can also show the list of files received, and before sending, show all the files in the list view.
Demo:
Source Code: https://github.com/omeryilmaz86/AndroidDataSharing.git.
Opinions expressed by DZone contributors are their own.
Trending
-
RBAC With API Gateway and Open Policy Agent (OPA)
-
Competing Consumers With Spring Boot and Hazelcast
-
From On-Prem to SaaS
-
Extending Java APIs: Add Missing Features Without the Hassle
Comments