Mastering communication between Android devices and handling complex data structures through socket programming

Recently, I've been exploring Android and I have a task at hand to establish a TCP socket connection and listen on a specific port. The client application will be sending me 2 images along with a related string. Instead of transmitting each piece of data separately, we decided to encapsulate everything in a JSON object before sending it over. My main query revolves around the process of parsing this JSON payload to extract and save those 2 images and the string. The expected structure of the JSON is as follows:

data
{
    FileName: "some string",
    Image1: "Image encoded using base64 encoding",
    Image2: "Image encoded using base64 encoding"
}

I'm making use of an AsyncTask, so let's delve into the code snippet where I retrieve data from the socket:

public class DataRecord
{
    String Image1;
    String Image2;
    String FileName;
}


protected DataRecord doInBackground(Socket... sockets) {
DataRecord dataRecord = null;

if (isExternalStorageWritable() && sockets.length > 0) {
    Socket socket = sockets[0];

    dataRecord = socket.getOutputStream(); // what approach should I follow to populate this object with data received from the socket ???

    File file = new File(Environment.getExternalStorageDirectory(), dataRecord.FileName);

    byte[] bytes = new byte[(int) file.length()];
    BufferedInputStream inputStream;
    try {
        inputStream = new BufferedInputStream(new FileInputStream(file));
        inputStream.read(bytes, 0, bytes.length);

        OutputStream outputStream = dataRecord.Image1;
        outputStream.write(bytes, 0, bytes.length);
        outputStream.flush();

        socket.close();
    }
    catch (Exception e) { }
    finally {
        try {
            socket.close();
        } catch (IOException e) { }
    }
}
return dataRecord;
}

It's essential for me to efficiently extract the contents from the socket object, build an object based on that information in order to store the images onto the SD card, and retrieve the string for display on the UI.

Answer №1

Although there may be multiple answers to this question, sharing an answer can be beneficial. I discovered a helpful resource at A Simple Java TCP Server and TCP Client, which provided guidance for initiating my solution. Additionally, I utilized Gson to parse my JSON string with the assistance of this informative tutorial: Android JSON Parsing with Gson Tutorial. Here is an overview of the code:

ServerSockerThread.java - This java class represents the listening server that anticipates incoming files:

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerSocketThread extends Thread {
    static final int SocketServerPORT = 6789;
    ServerSocket serverSocket;

    @Override
    public void run() {
        Socket socket = null;
        try {
            serverSocket = new ServerSocket(SocketServerPORT);
            while (true) {
                socket = serverSocket.accept();
                new FileSaveThread().execute(socket);
            }
        }
        catch (IOException e) { }
        finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) { }
            }
        }
    }

    protected void onDestroy() {
        if (serverSocket != null) {
            try {
                serverSocket.close();
            }
            catch (IOException e) { }
        }
    }
}

FileSaveThread.java - This java class is invoked by the aforementioned server class for each incoming file:

import android.os.AsyncTask;
import android.os.Environment;
import android.util.Base64;
import com.google.gson.Gson;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.Socket;

public class FileSaveThread extends AsyncTask<Socket, Void, DataRecord> {

    @Override
    protected void onPostExecute(DataRecord dataRecord) {
        super.onPostExecute(dataRecord);        
    }

    @Override
    protected DataRecord doInBackground(Socket... sockets) {
        DataRecord dataRecord = null;

        if (isExternalStorageWritable() && sockets.length > 0) {
            Socket socket = sockets[0];
            try {
                Gson gson = new Gson();
                Reader reader = new InputStreamReader(socket.getInputStream());
                SocketObject socketObject = gson.fromJson(reader, SocketObject.class);              

                SaveFileToSDCard(socketObject.Image1, "Image1.png");
                SaveFileToSDCard(socketObject.Image2, "Image2.png");
                SaveFileToSDCard(socketObject.Image3, "Image3.png");

                dataRecord = new DataRecord(socketObject.Name);
            }
            catch (Exception e) { }
            finally {
                try {
                    socket.close();
                } catch (IOException e) { }
            }
        }
        return dataRecord;
    }

    public boolean isExternalStorageWritable() {
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            return true;
        }
        return false;
    }

    private void SaveFileToSDCard(String base64String, String fileName) throws IOException {
        byte[] decodedString = Base64.decode(base64String.getBytes(), android.util.Base64.DEFAULT);
        File file = new File(Environment.getExternalStorageDirectory(), fileName);
        FileOutputStream fileOutputStream = new FileOutputStream(file, false);
        fileOutputStream.write(decodedString);
        fileOutputStream.close();
        fileOutputStream.flush();
    }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Laravel Eloquent model, text being cut off at maximum length

While working with Laravel, I encountered an issue when loading a database row into an Eloquent object. The problem arose from one of the columns being a longtext type containing a JSON encoded array with over 2 million characters. The original error I fac ...

struggling with responseText functionality in javascript

I am encountering an issue with passing variables from PHP to JavaScript using JSON. The problem lies in the fact that I am able to debug and view the items in the responseText within my JavaScript, but I am unable to assign them to a variable or properly ...

What is the process for obtaining JSON data on a C# WebAPI backend?

How can I successfully receive JSON data on my WebAPI backend in C#? I am facing an issue with the JSON data sent from my JavaScript frontend. { "User_Id": 1, "TotalPrice": 35, "DeliveryAddress": "At my house", "CartItems": [ ...

Iterating over a collection of objects to retrieve a specific value

{ "items": [ { "id": "12sd31sd", "name": "test1", "createdDate": 1554894979, }, { "id": "sz978z7", "name": "test2", "createdDate": 1569595456, }, ...

Is there a way to immobilize an object in JavaScript without resorting to Object.freeze()?

Is there a way to freeze the following object without relying on Object.freeze()? Let's find out: const obj = { a:'test', b:'Something' } ...

Attempting to send a String in a particular structure

I'm facing an issue with the format I'm trying to pass. The expected format should be like this: [{"blah.png"},{"blah2.png"}] However, instead of getting the desired format, I am receiving this: ["blah.png","blah2.png"] Below is the code snip ...

Contact specific position in list of WebElements

If anyone requires reference or background information, my initial question was about: Retrieving a list of WebElements and identifying them I have successfully retrieved a list of WebElements at this stage. @FindBy(css = "td[id^=ctl00_SomeGridData_uc ...

A JSON object containing a PHP variable

I'm trying to integrate a PHP variable into my PayPal single payout call code where the price is defined at 'value':".$planPrice." When I manually input a number like "1000", it works fine and I receive the notification. However, when I use ...

The functionality of "Expectedconditions.not" in Selenium Webdriver is not performing as anticipated

WebDriverWait wait = new WebDriverWait(driver, 60) WebElement element = driver.findElement(By.xpath("//div[contains(text(),'Loading...')]")); System.out.println("Test"); wait.until(ExpectedConditions.not(ExpectedConditions.presenceOfElementLocat ...

Could there possibly be a glitch in the updated Spring JSON reader, or is it likely an error on my end?

I have set up the following reader: @Configuration public class ReaderConfig { @Bean public JsonItemReader<String> jsonItemReader(Resource resource) { return new JsonItemReaderBuilder<String>() .jsonObjectReader ...

Encountered an issue while attempting to assess Jackson deserialization for this specific

I am currently in the process of establishing a many-to-many relationship between movies and users. However, I encountered an error while attempting to save a movie: 2017-12-01 16:12:43.351 WARN 17328 --- [nio-8090-exec-5] .c.j.MappingJackson2HttpMessageC ...

Trying to optimize this Active Record Query for better performance in Ruby on Rails

Hello, I'm currently new to active record and exploring two map functions. I'm curious if there's a more efficient way to optimize the following query: When I run this query, I see hundreds of lines in my terminal and worry about potential ...

When incorporating axios within an express route, it is causing the data field to display unusual characters instead of JSON

I've been grappling with this issue for quite some time now, and any assistance would be greatly appreciated. Initially, I attempted to resolve the problem by utilizing the Moralis nodeJs library. While it worked fine on my local environment, it retu ...

The JSON schema is failing to validate properly

I am having issues with my JSON schema validation. It seems to only recognize the first pattern. { "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "properties": { "Pr ...

How to Transfer Rows Between Two DevExpress Grids in ASP.NET Core

In my current ASP.NET Core project using Razor pages, I have incorporated two devexpress grids. The main objective is to select a row from one grid, click on the floating action button labeled "add", and have that selected row transferred to the grid on th ...

The signature provided by the pusher is invalid: The expected HMAC SHA256 in hexadecimal digest is

The HTML file contains JavaScript code that calls the server for authentication. The code snippet from the HTML file is as follows: <html> <script> <head> var options = { authEndpoint: "api/pusher.json?socket_id=9900&channel_name ...

Getting a string array from a JSON object within the deserialize method

I am working with a JSON object that looks like this: { "name": "John", "age": 29, "bestFriends": [ "Stan", "Nick", "Alex" ] } In my code, I have created a custom implementation of JsonDeserializer: public class CustomDeserializer im ...

Tips on using JQuery to extract form field information from a drop-down menu, display it in a div, and then compare it with the subsequently

In my HTML file, I am using two dropdown lists and JQuery for validation. First, I need to save the selected items from both dropdown lists in a variable and then compare them with the next selection. If the data from both dropdown lists match, an alert m ...

What is the method for including an item in a Dictionary?

I encountered an issue with a nested dictionary in a Json file. Here is the current content of the file (highscore_history.txt): { "Highscores": { "0highscore": 2 } } My goal is to add a new entry into the nested dictio ...

The WebDriver Manager for Selenium Automation is experiencing issues with the latest Chrome update, version 116

I implemented the selenium framework and included this dependency. However, I encountered an issue where the browser wasn't being invoked due to Chrome version 116. <dependency> <groupId>io.github.bonigarcia</groupId> <art ...