finished the first version of the communicator package

This commit is contained in:
paul-loedige 2020-12-31 03:41:21 +01:00
parent 5407dc0f5b
commit 7936281924
3 changed files with 293 additions and 20 deletions

View File

@ -2,56 +2,148 @@ package com.example.aped.communication;
import android.content.Context;
import android.util.Log;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import com.example.aped.utils.ExternalStorageHandler;
import org.json.JSONObject;
import java.io.File;
import kotlin.NotImplementedError;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* Class that handles communication with the raspberry pi.
*/
public class Communicator {
private String address;
private int port;
private RequestQueue requestQueue;
public Communicator(String address, int port, Context context) {
this.address = address;
this.port = port;
requestQueue = Volley.newRequestQueue(context);
/** Ipv4 address of the raspberry. **/
private final String address;
/** API port of the raspberry. **/
private final int port;
/** Request queue used for asynchronous requests. **/
private final RequestQueue requestQueue;
/**The context of the application.**/
private final Context context;
/**
* Constructor of the Communicator.
* @param pAddress the ipv4 address of the raspberry
* @param pPort the port of the raspberry
* @param pContext the context of the application
*/
public Communicator(final String pAddress,
final int pPort,
final Context pContext) {
this.address = pAddress;
this.port = pPort;
requestQueue = Volley.newRequestQueue(pContext);
this.context = pContext;
}
public void read(String deviceName, Response.Listener<JSONObject> responseListener) {
String requestString = "http://" + address + ":" + port + "/device/" + deviceName + "/";
/**
* Reads the device state from the raspberry.
* @param deviceName the name of the device
* @param responseListener the {@link Response.Listener} for defining
* actions to be performed on response
*/
public void read(final String deviceName,
final Response.Listener<JSONObject> responseListener) {
String url = "http://" + address
+ ":" + port
+ "/device/" + deviceName + "/";
JsonObjectRequest request = new JsonObjectRequest(
Request.Method.GET,
requestString,
url,
null,
responseListener,
error -> Log.e("Communicator", "Error during READ: " + error.getMessage())
error -> Log.e("Communicator",
"Error during READ: " + error.getMessage())
);
requestQueue.add(request);
}
public void write(String deviceName, JSONObject message, Response.Listener<JSONObject> responseListener) {
String requestString = "http://" + address + ":" + port + "/device/" + deviceName + "/";
/**
* Writes an api call to the endpoint of a device.
* @param deviceName the name of the device
* @param message the JSON message
* @param responseListener the {@link Response.Listener} for defining
* actions to be performed on response
*/
public void write(final String deviceName,
final JSONObject message,
final Response.Listener<JSONObject> responseListener) {
String url = "http://" + address
+ ":" + port
+ "/device/" + deviceName + "/";
JsonObjectRequest request = new JsonObjectRequest(
Request.Method.POST,
requestString,
url,
message,
responseListener,
error -> {
Log.e("Communicator", "Error during WRITE: " + error.getMessage()); error.printStackTrace(); }
error -> Log.e("Communicator",
"Error during WRITE: " + error.getMessage())
);
requestQueue.add(request);
}
public void uploadXML(File xmlFile) {
throw new NotImplementedError();
/**
* Uploads the config.xml file to the raspberry.
*/
public void uploadXML() throws FileNotFoundException {
File xmlFile = new File(ExternalStorageHandler
.getExternalPrivateStorageDir(context), "config.xml");
String url = "http://" + address + ":" + port + "/XML/";
FileOutputVolleyRequest request = new FileOutputVolleyRequest(
Request.Method.POST,
url,
xmlFile,
response -> System.out.println(response.toString()),
error -> Log.e("Communicator",
"Error during XML UPLOAD" + error.getMessage())
);
requestQueue.add(request);
}
/**
* Downloads the config.xml file from the raspberry.
*/
public void downloadXML() {
throw new NotImplementedError();
String url = "http://" + address + ":" + port + "/XML/";
InputStreamVolleyRequest request = new InputStreamVolleyRequest(
Request.Method.GET,
url,
response -> {
try {
if (response != null) {
String xmlPath = ExternalStorageHandler
.getExternalPrivateStorageDir(context);
File xmlFile = new File(xmlPath, "config.xml");
/*create the default XML config by using the
default.xml from the assets folder*/
if (xmlFile.exists()) {
xmlFile.delete();
}
FileOutputStream fileOutputStream =
new FileOutputStream(xmlFile);
fileOutputStream.write(response);
fileOutputStream.close();
}
} catch (IOException e) {
Log.e("Communicator",
"Error while reading the XML DOWNLOAD "
+ "from the raspberry: "
+ e.getMessage());
}
},
error -> Log.e("Communicator",
"Error during XML DOWNLOAD: " + error.getMessage())
);
requestQueue.add(request);
}
}

View File

@ -0,0 +1,121 @@
package com.example.aped.communication;
import android.util.Log;
import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Map;
/**
* Custom {@link Request} to send xml files to the raspberry pi.
*/
public class FileOutputVolleyRequest extends Request<JSONObject> {
/** Listener for response callback. **/
private final Response.Listener<JSONObject> listener;
/** File to be sent. **/
private final File file;
/** Headers of the response recieved from the raspberry. **/
private Map<String, String> responseHeaders;
/**
* Constructor.
* @param method {@link Request.Method}
* @param url url the request will be sent to
* @param pFile the file that will be sent
* @param pListener a listener for the response callback
* @param errorListener a listener for an error callback
*/
public FileOutputVolleyRequest(final int method,
final String url,
final File pFile,
final Response.Listener<JSONObject> pListener,
final Response.ErrorListener errorListener) {
super(method, url, errorListener);
setShouldCache(false);
this.listener = pListener;
this.file = pFile;
}
/**
* Overrides for the body content type.
* @return xml body content type
*/
@Override
public String getBodyContentType() {
return "application/xml; charset = utf-8";
}
/**
* Defines the body content.
* @return the body content
* @throws AuthFailureError
*/
@Override
public byte[] getBody() throws AuthFailureError {
try {
BufferedReader bufferedReader = new BufferedReader(
new FileReader(file)
);
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
stringBuilder.append("\n");
}
bufferedReader.close();
String requestBody = stringBuilder.toString();
return requestBody.getBytes("utf-8");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* Parses the response into an {@link JSONObject}.
* @param response the response from the raspberry
* @return a {@link Response<JSONObject>}
*/
@Override
protected Response<JSONObject> parseNetworkResponse(
final NetworkResponse response) {
responseHeaders = response.headers;
JSONObject obj = null;
try {
obj = new JSONObject(new String(response.data));
} catch (JSONException e) {
Log.e("FileOutputVolleyRequest",
"Failed parsing JSON:" + e.getMessage());
}
return Response.success(
obj, HttpHeaderParser.parseCacheHeaders(response)
);
}
/**
* Deliveres the Response to the response listener.
* @param response the parsed response
*/
@Override
protected void deliverResponse(final JSONObject response) {
listener.onResponse(response);
}
}

View File

@ -0,0 +1,60 @@
package com.example.aped.communication;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;
import java.util.Map;
/**
* Custom {@link Request} to enable recieving files from the raspberry pi.
* Credit: https://mobikul.com/downloading-files-using-volley/
*/
public class InputStreamVolleyRequest extends Request<byte[]> {
/** Listerner for response callback. **/
private final Response.Listener<byte[]> listener;
/** Headers of the response recieved from the raspberry.**/
private Map<String, String> responseHeaders;
/**
* Constructor.
* @param method {@link Request.Method}
* @param url the API url to send the request to
* @param pListener the listener for the response callback
* @param errorListener the listener for an error callback
*/
public InputStreamVolleyRequest(final int method,
final String url,
final Response.Listener<byte[]> pListener,
final Response.ErrorListener errorListener) {
super(method, url, errorListener);
setShouldCache(false);
this.listener = pListener;
}
/**
* Parses the response into a byte array.
* @param response the response recieved from the raspberry
* @return the parsed response
*/
@Override
protected Response<byte[]> parseNetworkResponse(
final NetworkResponse response) {
responseHeaders = response.headers;
return Response.success(
response.data, HttpHeaderParser.parseCacheHeaders(response)
);
}
/**
* Delivers the recieved response to the listener.
* @param response the parsed response
*/
@Override
protected void deliverResponse(final byte[] response) {
listener.onResponse(response);
}
}