I am working on an Android app that includes a signaturepad.
I would like to upload the resulting bitmap to a remote server.
I havenĀ“t found any resources that show how to manage this bitmap and how to convert it to a uploadable format.
This is the function that gets the signaturepad bitmap, and the needed function to upload it to a remote server:
btnFirmar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Bitmap signatureBitmap = mSignaturePad.getSignatureBitmap();
uploadBitmap(signatureBitmap);//WHAT TO DO WITH THIS...
}
});
I have solved it as follows, using the Volley Library:
private void uploadBitmap() {
dialog = new ProgressDialog(getActivity());
dialog.setMessage("Uploading Signature...");
dialog.setCancelable(false);
jsonObject = new JSONObject();
Bitmap image = signatureBitmap;
dialog.show();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
String encodedImage = Base64.encodeToString(byteArrayOutputStream.toByteArray(), Base64.DEFAULT);
try {
jsonObject.put(Utils.imageName, numero);
jsonObject.put(Utils.image, encodedImage);
} catch (JSONException e) {
Log.e("JSONObject Here", e.toString());
}
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, Utils.urlUpload, jsonObject,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject jsonObject) {
Log.e("Message from server", jsonObject.toString());
dialog.dismiss();
// messageText.setText("Image Uploaded Successfully");
Toast.makeText(getActivity(), "Signature Uploaded Successfully", Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Log.e("Message from server", volleyError.toString());
dialog.dismiss();
}
});
jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(5000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
Volley.newRequestQueue(getActivity()).add(jsonObjectRequest);
}
What is the process? For C#, I'm trying to get image and send by HTTP client, perhaps, on the server only get a blank image, this is the code on the Xamarin Forms:
<forms:SignaturePadView
BackgroundColor="Transparent"
StrokeColor="Blue"
StrokeWidth="3"
HeightRequest="250"
Name="Signature"
/>
And in the View Model:
Stream image = await Signature.GetImageStreamAsync(SignatureImageFormat.Png);
To send:
var bytes = new byte[image.Length];
await image.ReadAsync(bytes, 0, (int)image.Length);
string imageBase64 = Convert.ToBase64String(bytes);
On the request:
try
{
var client = new HttpClient();
var response = await client.PostAsync(urlBase,
new StringContent(string.Format(
"imgSign={0}",
imageBase64),
Encoding.UTF8, "application/x-www-form-urlencoded"));
if (!response.IsSuccessStatusCode)
{
return response.ToString();
}
else
{
var response = await response.Content.ReadAsStringAsync();
return response;
}
}
catch
{
return null;
}
Server receives by a Post Request and using file_puts_contents to send image on folder:
if (isset ($image = $_POST['imgSign'])) {
$dateNow = date("d-m-Y");
$imageName = 'Id'.$dateNow;
$image = $_POST['imgSign'];
$path = "../images/$imageName.png";
if(file_put_contents($path,base64_decode($image))){
...update DB
}
}
Related
I wanted to upload a file from my android internal storage to Any cloud storage(ex.google drive,One drive etc)since kloudless provides an api to upload file to any cloud storage using accesstoken I wanted to use the same api for uploading the file (https://api.kloudless.com/v1/accounts/accountid+/storage/files/).
I tried it through postman I am able to upload the file
Now I tried through android volley I am able to create the file in the cloud but there is no data inside it. Here is my code
public class MainActivity extends AppCompatActivity {
Button b;
TextView TV;
File myFile;
String responseString;
String path;
public String BASE_URL = "https://api.kloudless.com";
private static final int FILE_SELECT_CODE = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TV = findViewById(R.id.textView);
b = findViewById(R.id.button);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showFileChooser();
}
});
}
private void showFileChooser() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
try {
startActivityForResult(
Intent.createChooser(intent, "Select a File to Upload"),
FILE_SELECT_CODE);
} catch (android.content.ActivityNotFoundException ex) {
// Potentially direct the user to the Market with a Dialog
Toast.makeText(this, "Please install a File Manager.",
Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == FILE_SELECT_CODE) {
if (resultCode == RESULT_OK) {
// Get the Uri of the selected file
Uri uri = data.getData();
Log.d("TAG", "File Uri: " + uri.toString());
// Get the path
String path = null;
try {
path = FileUtils.getPath(this, uri);
} catch (URISyntaxException e) {
e.printStackTrace();
}
Log.d("TAG", "File Path: " + path);
try {
data();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
super.onActivityResult(requestCode, resultCode, data);
}
public void data() throws FileNotFoundException, UnsupportedEncodingException {
final String url = BASE_URL + "/v1/accounts/" + "accountid" + "/storage/files/";
final RequestQueue queue = Volley.newRequestQueue(this);
HashMap<String, Object> params = new HashMap<String, Object>();
params.put( "file","somedata");
JSONObject Body=new JSONObject(params);
final JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url,Body, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
// response
Log.d("Response", response.toString());
}
},
new ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// error
Log.d("Error.Response", error.toString());
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> params = new HashMap<String, String>();
params.put("Authorization", "Bearer Bearerkey");
params.put("Content-Type", "form-data");
params.put("X-Kloudless-Metadata", "{\"parent_id\":\"root\",\"name\":\"testdone.txt\"}");
// params.put("Content-Length", Space);
return params;
}
};
queue.add(request);
}
Please help me how to send the file in body of my request
I work at Kloudless and while I am not very familiar with the Android Volley, the issue here appears to be that you are setting a JSON body with the incorrect content type. In order to replicate the Postman request, you would need to use a multipart file upload instead, as described here: How to upload file using Volley library in android? The file would need to be added to a field called file, e.g entity.addPart("file", new FileBody(new File("....")));
In order for there to be more efficient handling on the server side (for larger files), the request performed should instead include the binary file contents in the request body and have the header Content-Type: application/octet-stream. Based on some cursory searching, it seems like the Volley library doesn't make that very easy so it might be best to try a different library.
Finally found the simple solution to upload a file to api
RequestQueue queue = Volley.newRequestQueue(this);
String url = BASE_URL + "/v1/accounts/" + "353284419" + "/storage/files/";
StringRequest postRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Toast.makeText(MainActivity.this, response, Toast.LENGTH_LONG).show();
// response
Log.d("Response", response);
}
},
new ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// error
Log.d("Error.Response", error.toString());
}
}
) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Authorization", "Bearer ix7wW4CFJsHxhttg42qsO6HNNRPh06");
params.put("Content-Type", "application/octet-stream");
params.put("X-Kloudless-Metadata", "{\"parent_id\":\"root\",\"name\":\"testing uplodes.pdf\"}");
// params.put("Content-Length", Space);
return params;
}
#Override
public byte[] getBody() throws com.android.volley.AuthFailureError {
File f=new File(path);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
FileInputStream fis = null;
try {
fis = new FileInputStream(f);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
byte[] bytesArray = new byte[(int)f.length()];
try {
fis.read(bytesArray);
} catch (IOException e) {
e.printStackTrace();
}
return bytesArray;
};
};
postRequest.setRetryPolicy(new DefaultRetryPolicy(
40000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
queue.add(postRequest);
}
just convert the file into binary array and send it in the body
My java code is not connect with flask. It doesn't give any error or response. Program run infinitely.
When i try to connect it is not going on response or on error function. After completing function call it start running and never stop.
Java Code:
Button button;
RequestQueue rQueue;
String url ="http://127.0.0.1:5000/predict";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button);
rQueue = Volley.newRequestQueue(MainActivity.this);
}
public void predict(View view){
UploadTwoImages();
}
public String getStringImage(Bitmap bmp) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] imageBytes = baos.toByteArray();
String encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT);
return encodedImage;
}
public void UploadTwoImages() {
Bitmap icon = BitmapFactory.decodeResource(getResources(),R.drawable.logo);
final String imageOne = getStringImage(icon);
final ProgressDialog pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Registration is in Process Please wait...");
pDialog.show();
StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String s) {
pDialog.dismiss();
Log.d("JSONResult", s);
try {
JSONObject jObject = new JSONObject(s);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
}
}) {
//adding parameters to send
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("image", imageOne);
return parameters;
}
};
request.setRetryPolicy(new DefaultRetryPolicy(
90000,
0,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
request.setShouldCache(false);
rQueue.add(request);
}
Flask Server Code:
#app.route('/predict', methods=['GET', 'POST'])
def upload():
if request.method == "POST":
if request.files:
output={}
image = request.files["image"]
print(request.files)
basepath = os.path.dirname(__file__)
file_path = os.path.join(
basepath, 'uploads', secure_filename(image.filename))
print(image.filename)
image.save(file_path)
return str([1])
return "Error"
if __name__ == '__main__':
app.run(debug=True)
url = ipv4address:portNumber/apiName
In android manifest add following 2 lines and it works for me.
android:usesCleartextTraffic="true"
<uses-permission android:name="android.permission.INTERNET"/>
I have written the code for capturing the image from the camera and send to the server. But sometimes it works sometimes its not with the error volley timeout error. And almost all the cases when I am using JIO network which used IPv6 IP( I don't know what is affecting this) its not working.
I am capturing the image and convert into base64 and sending to the POST to the PHP server.
To start the camera :
btn_cam.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
captureImage();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent,CAMERA_REQUEST_CODE);
} catch (Exception e){
e.printStackTrace();
}
}
});
After capturing the image :
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_REQUEST_CODE && resultCode == RESULT_OK) {
Bitmap bitmap = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream.toByteArray();
encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);
}
}
Then sending the encoded string to the APACHE server :
btn_submit.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
_house_no = house_number.getText().toString();
_state = state.getText().toString();
_streetName = locality.getText().toString();
_city = city.getText().toString();
_postalCode = postcode.getText().toString();
_state = state.getText().toString();
_district = district.getText().toString();
_tahsil = "0";
final ProgressDialog loading = ProgressDialog.show(MainActivity.this, "", "Please wait...", false, false);
try {
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
String URL = ServerLinks.SUBMIT;
JSONObject jObj = new JSONObject();
jObj.put("userID",userID);
jObj.put("house",_house_no);
jObj.put("street",_streetName);
jObj.put("city",_city);
jObj.put("post_code",_postalCode);
jObj.put("state",_state);
jObj.put("district",_district);
jObj.put("lat",lat);
jObj.put("long",longi);
jObj.put("image",encoded);
final String requestBody = jObj.toString();
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("FINAL_SUBMIT_RESPONSE", response.toString());
loading.dismiss();
try {
JSONObject object = new JSONObject(response);
int response_code = object.getInt("code");
String message = object.getString("Message");
if (response_code == 400) {
Snackbar.make(rootLinearLayout, message, Snackbar.LENGTH_SHORT).show();
house_number.setText("");
} else {
Snackbar.make(rootLinearLayout, message, Snackbar.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
loading.dismiss();
VolleyLog.d("RESULT_ERROR", "Error: " + error.getMessage());
Toast.makeText(getApplicationContext(), "Something Went Wrong!! Please submit it again", Toast.LENGTH_SHORT).show();
}
}) {
#Override
public byte[] getBody() throws AuthFailureError {
try {
return requestBody == null ? null : requestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", requestBody, "utf-8");
return null;
}
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/json");
params.put("x-api-key", OAuth);
return params;
}
};
stringRequest.setShouldCache(false);
requestQueue.add(stringRequest);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}`
Can you please help me how should I increase the efficiency of my form with the image. Thank You in advance
Inside my code I have done this like that :
HttpClient httpclient;
httpclient = HttpClientSingalTon.getHttpClienttest();
HttpPost httpPostRequest = new HttpPost(URL);
// Try This
httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
MultipartEntity mpEntity = new MultipartEntity();
ContentBody cbFile = new FileBody(yourimagefile, "image/jpeg");
mpEntity.addPart("file", cbFile);
httpPostRequest.setEntity(mpEntity);
HttpResponse response = (HttpResponse) httpclient.execute(httpPostRequest);
I have a problem when I try to use volley to communicate with a server (I created the server, so I can change a thing here too).
So when I use the stringRequest I have this problem:
my string contains 2 quotes, for example, the string looks like this: ""something""
while I send "something" and when I try to use this data like
if (response == "\"something\"")
do something
that doesn't work. I just can't use this string normally.
And when I try to use JsonObjectRequest I don't know why but I allways have this issue:
org.json.JSONException: Value {"name":"nofind"} of type java.lang.String cannot be converted to JSONObject
I tried to send this :
"{\"name\":\"nofind\"}",
"{'name':'nofind'}",
"{name:\"nofind\"}",
"{name:'nofind'}"
But It's always the same problem. I don't know why.
So please, if someone can help me. I will be very grateful
EDIT :
here my code :
JsonObjectRequest :
JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, URL_SERVER+URL_IMAGE,
null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
resultsTextView.setText(response.toString());
snackbar.dismiss();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("ERROR","error => "+error.toString());
resultsTextView.setText(R.string.ErrorServor);
snackbar.dismiss();
}
}){
#Override
public byte[] getBody(){
ByteArrayOutputStream stream = new ByteArrayOutputStream();
faceBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
faceBitmap.recycle();
return byteArray ;
}
#Override
public String getBodyContentType() {
return "image/jpeg";
}
};
request.setRetryPolicy(new DefaultRetryPolicy(
0,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
queue.add(request);
String request:
StringRequest request = new StringRequest(Request.Method.POST, URL_SERVER + URL_IMAGE,
this, this){
#Override
public byte[] getBody() {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
faceBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
faceBitmap.recycle();
return byteArray ;
}
#Override
public String getBodyContentType() {
return "image/jpeg";
}
};
request.setRetryPolicy(new DefaultRetryPolicy(
0,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
queue.add(request);
}
#Override
public void onErrorResponse(VolleyError error) {
Log.d("ERROR","error => "+error.toString());
resultsTextView.setText(R.string.ErrorServor);
snackbar.dismiss();
}
#Override
public void onResponse(String response) {
try {
if (response != "nofind")
{
resultsTextView.setText(response);
NoButton.setVisibility(View.VISIBLE);
YesButton.setVisibility(View.VISIBLE);
}
else {
resultsTextView.setText(R.string.NoBack);
}
resultsTextView.setText(obj.toString());
} catch (JSONException e) {
e.printStackTrace();
System.out.println(e);
}
For each people who have the same problem as me.
To establish a communication between a WCF server and an Android application with Volley.
For the StringRequest the solution is written above.I just had to use .equals(MyString) in place of ==MyString.
But for the JsonObjectRequest the problem was on the server. In the BodyStyle parameter.
the Solution is I had to Wrappe Only the response.
So this is the function who worked for me.
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/NewUser",BodyStyle = WebMessageBodyStyle.WrappedResponse, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
dynamic NewUser(User user);
More information About the BodyStyle here :
RESTful web service body format
I wanna send a PDF file stored in internal storage ( InternalStrorage/PDF/OCK.pdf )
I already sent String Data to my php server using Android Volley without problems via this function:
private void upload(){
StringRequest stringRequest = new StringRequest(Request.Method.POST, UploadURL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
String Response = jsonObject.getString("response");
Toast.makeText(getApplicationContext(),Response, Toast.LENGTH_LONG).show();
selectedimage.setImageResource(0);
selectedimage.setVisibility(View.GONE);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}
){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("date",DateFormat.getDateTimeInstance().format(new Date()).toString());
params.put("description",editTextDescription.getText().toString());
params.put("statut", whatstatutis());
params.put("action",editTextImediatActionTaken.getText().toString());
return params;
}
};
MySingleton.getInstance(getApplicationContext()).addTorequesteque(stringRequest);
}
I wanna send the PDF file with my data in the same time.
Finally i find the solution.
1- Just convert the PDF to to byte array
2- Byte Array to base64
3- Send it like normal strings
byte[] data = null;
File filessss = new File(Link_Of_The_PDF.pdf);
try {
data = FileUtils.readFileToByteArray(filessss);
} catch (IOException e) {
e.printStackTrace();
}
return Base64.encodeToString(data, Base64.DEFAULT);