Are my codes correct? I already have published this on my Web server. What happens are, it is creating a text file but the base64 string are not written on that text file.
These are my codes from Android Studio
private void uploadImage() {
final ProgressDialog loading = ProgressDialog.show(this,"Uploading...","Please wait...",false,false);
StringRequest stringRequest = new StringRequest(Request.Method.POST, UPLOAD_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String s) {
loading.dismiss();
Toast.makeText(MainActivity.this, s , Toast.LENGTH_LONG).show();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
loading.dismiss();
Toast.makeText(MainActivity.this, volleyError.getMessage().toString(), Toast.LENGTH_LONG).show();
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
String image = getStringImage(bitmap);
Map<String,String> params = new Hashtable<String, String>();
params.put("b64", image);
Log.d("base64: ", String.valueOf(params));
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
These are my codes on VS
[HttpPost]
public String ProcessImg([FromBody] string b64)
{
String base64 = b64;
String jsonStr = null;
//function to create image from b64 string
try
{
var FilePath = ConfigurationManager.AppSettings["imgFilePath"];
if (!Directory.Exists(FilePath))
{
Directory.CreateDirectory(FilePath);
}
//to create file and write base64 string
var name = DateTime.Now.ToString("MMddyyyy-HHmmss");
var FileName = Path.Combine(FilePath, name + ".png");
string path = Path.Combine(FilePath, name + ".txt");
StreamWriter file = new StreamWriter(path);
file.Write(base64);
file.Close();
if (File.Exists(FileName))
{
jsonStr = "file successfully created on server. :" + FileName;
}
else
{
jsonStr = "Sorry the file you tried to convert failed.";
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
jsonStr = ex.Message;
}
//Algo
return jsonStr;
}
StreamWriter is best used with the using keyword as it implements IDisposable which automatically calls the Dispose() method like this:
using(StreamWriter file = new StreamWriter())
{
file.Write(base64);
}
Otherwise you will have to call the Flush() method manually to write the buffered input to the disk before closing the file:
StreamWriter file = new StreamWriter();
file.Write(base64);
file.Flush();
file.Close();
The flush part is done when the stream's Dispose() method is called, thus implementing it with the using keyword automatically takes care of that.
Related
I need to use Mediaplayer inside a JsonObjectRequest. My Code is like this
obreq = new JsonObjectRequest(Request.Method.GET, url,
// The third parameter Listener overrides the method onResponse() and passes
//JSONObject as a parameter
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
MediaPlayer mediaPlayer = MediaPlayer.create(this,R.raw.ok);
mediaPlayer.start();
JSONObject obj = response.getJSONObject("result");
}
// Try and catch are included to handle any errors due to JSON
catch (JSONException e) {
// If an error occurs, this prints the error to the log
Log.e("Errore: ", e.getLocalizedMessage());
e.printStackTrace();
}
}
},
// The final parameter overrides the method onErrorResponse() and passes VolleyError
//as a parameter
new Response.ErrorListener() {
#Override
// Handles errors that occur due to Volley
public void onErrorResponse(VolleyError error) {
Log.e("Volley", "Error");
MediaPlayer mediaPlayer = MediaPlayer.create(this,R.raw.error);
mediaPlayer.start();
throw new NullPointerException("uuuuuu");
}
}
) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> customHeaders = new HashMap<>();
String login_url = Helper.getConfigValue(getApplicationContext(), "login_url");
String pwd_url = Helper.getConfigValue(getApplicationContext(), "pwd_url");
String credentials = login_url + ":" + pwd_url;
String auth = "Basic "
+ Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
customHeaders.put("Content-Type", "application/json; charset=utf-8");
customHeaders.put("Authorization", auth);
return customHeaders;
}
};
shareedit delete flag
but i get the error
"Cannot resolve method 'create(anonymous
com.android.volley.Response.Listener, int)"
in MediaPlayer line
How can I solve the problem?
Thanks
As your "this" is referring to you volley object
MediaPlayer.create(this,R.raw.ok);
replace it with you activity reference, like
MediaPlayer.create(yourActivity.this,R.raw.ok);
I'm working on an android app that needs to save a pdf file from an api. So I had to extend Request volley class to a ByteArray class:
package br.com.tarcisojunior.myapp;
import android.support.annotation.NonNull;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;
/**
* Created by tarcisojunior on 18/04/18.
*/
public class ByteArrayRequest extends Request<byte[]> {
private final Response.Listener<byte[]> mListener;
public ByteArrayRequest(String url, Response.Listener<byte[]> listener,
Response.ErrorListener errorListener) {
this(Method.GET, url, listener, errorListener);
}
public ByteArrayRequest(int method, String url, Response.Listener<byte[]> listener, Response.ErrorListener errorListener) {
super(method, url, errorListener);
mListener = listener;
}
#Override
protected Response parseNetworkResponse(NetworkResponse response) {
return Response.success(response.data, HttpHeaderParser.parseCacheHeaders(response));
}
#Override
protected void deliverResponse(byte[] response) {
if(null != mListener){
mListener.onResponse(response);
}
}
#Override
public String getBodyContentType() {
return "application/octet-stream";
}
}
I my Activity i'm calling ByteArrayRequest to perform an api request:
private void getCarnePDF(final int empreendimento,final int coligada,final String quadra,final String lote){
RequestQueue requestQueue;
ByteArrayRequest request;
requestQueue = Volley.newRequestQueue(this);
request = new ByteArrayRequest(Request.Method.GET, getString(R.string.baseUrl) + getString(R.string.carnePdfUrl),
new Response.Listener<byte[]>() {
#Override
public void onResponse(byte[] response) {
Log.i("getBilletCard", response.toString());
try {
byte[] bytes = response;
saveToFile(bytes, "card.pdf");
}catch (Exception e){
Toast.makeText(BilletCardActivity.this, "Erro ao converter resposta", Toast.LENGTH_LONG).show();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
//headers.put("Content-Type", "application/json");
headers.put("token", token);
headers.put("empreendimento", String.valueOf(empreendimento));
headers.put("coligada", String.valueOf(coligada));
headers.put("quadra", quadra);
headers.put("lote",lote);
return headers;
}
};
requestQueue.add(request);
}
and in listener the saveToFile function should create the pdf file. The pdf file is created but raises an error "Can't open file". Here's my saveToFile function:
public void saveToFile(byte[] byteArray, String pFileName){
File f = new File(Environment.getExternalStorageDirectory() + "/myappname");
if (!f.isDirectory()) {
f.mkdir();
}
String fileName = Environment.getExternalStorageDirectory() + "/myappname/" + pFileName;
try {
FileOutputStream fPdf = new FileOutputStream(fileName);
fPdf.write(byteArray);
fPdf.flush();
fPdf.close();
Toast.makeText(this, "File successfully saved", Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
Toast.makeText(this, "File create error", Toast.LENGTH_LONG).show();
} catch (IOException e) {
Toast.makeText(this, "File write error", Toast.LENGTH_LONG).show();
}
}
The file is successfully create, but it doesn't open
When I tried same endpoint from Postman, everything works fine and file is successful saved and opened
after comparing Postman headers with my code, I've found that a "Cache-control=no-cache" header was missing in request.
After add this header, file was correctly downloaded.
so changed to this:
.
.
.
.
.
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Cache-Control", "no-cache");
headers.put("token", token);
headers.put("empreendimento", String.valueOf(empreendimento));
headers.put("coligada", String.valueOf(coligada));
headers.put("quadra", quadra);
headers.put("lote",lote);
return headers;
}
.
.
.
.
.
Am trying to send data received from my android app to a server side php script. Am using the Volley. However, when I declare the the RequestQueue I get an error
"newRequestQueue (android.content.Context, com.android.volley.toolbox.HttpStack) cannot be applied to ()"
I tried using::
Blockquote
RequestQueue queue = Volley.newRequestQueue(this);
Blockquote
RequestQueue queue = Volley.newRequestQueue(getActivity().getApplicationContext());
Blockquote
Error is still the same on both cases. Please what am doing wrong?
PS- volley is in PostDataToEmail method of a fragment.
Here is the code below:
public void PostDataToEmail(){
final String service = service_type.toString();
final String error_message = incident.getText().toString();
final String requester = user_name.getText().toString();
final String number = mobile_no.getText().toString();
final String site = location.getText().toString();
final String support_time = timeDate.getText().toString();
final String support_date = date_field.getText().toString();
final String mode_of_contact = contact_mode.toString();
RequestQueue queue = Volley.newRequestQueue();
String url = "http://mywebsite/fromApp.php";
StringRequest postRequest = new StringRequest (Request.Method.POST, url,
new Response.Listener<String>(){
#Override
public void onResponse(String response) {
Log.d("Response", response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse (VolleyError error) {
Log.d("ERROR", "error => " +error.toString());
}
}
) {
#Override
protected Map<String, String> getParams(){
Map<String, String> params = new HashMap<String, String>();
params.put("grant_type", "password");
params.put(" ", "{{%escape/");
params.put("Service: ", service);
params.put("Error Message: ", error_message);
params.put("Requester: ", requester);
params.put("Mobile No: ", number);
params.put("Location: ", site);
params.put("Time: ", support_time);
params.put("Date: ", support_date);
params.put("Contact mode: ", mode_of_contact);
return params;
}
};
queue.add(postRequest);
}
You need to add this in your declaration. RequestQueue some=newRequestQueue(this)
i have urls of i got as response from a volley JsonObectRequest. What i want to be able to do is save those images directly into a folder on my external storage so i don't have to load them from the internet anymore. Please keep in mind that download may also include videos...
//Here is the volley code for retrieving the urls
private static final String endpoint = "http://api.androidhive.info/json/glide.json";
//Code to extract image url
JsonArrayRequest req = new JsonArrayRequest(endpoint,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
pDialog.hide();
images.clear();
for (int i = 0; i < response.length(); i++) {
try {
JSONObject object = response.getJSONObject(i);
Image image = new Image();
image.setName(object.getString("name"));
JSONObject url = object.getJSONObject("url");
image.setSmall(url.getString("small"));
image.setMedium(url.getString("medium"));
image.setLarge(url.getString("large"));
image.setTimestamp(object.getString("timestamp"));
} catch (JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
}
}
mAdapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Error: " + error.getMessage());
pDialog.hide();
}
});
Now, how do i request a download so they files are save in my external using volley. Thank you
public boolean storeImages(Bitmap imageBitmap, String fileName, String dirName, int index) {
File file;
if (isExternalStorageWritable() && isExternalStorageReadable()) {
file = storeImageExternalMemory(dirName, albumName, String.valueOf(index));
}
try {
assert file != null;
FileOutputStream out = new FileOutputStream(file);
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
updateImageTable(file, index); // Implement Your own method to update ur DB table, U can access file location from DB table for future use of images
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
Convert your downloaded image into bitmap and the save to desired location in cellphone. Then You can reuse image.
private File storeImageExternalMemory(String dirName, String mediaName) {
String packageName = mContext.getPackageName();
File mediaStorageDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/Android/data/" + packageName + dirName);
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
return null;
}
}
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath(), mediaName + ".jpeg");
return mediaFile;
}
/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
return Environment.MEDIA_MOUNTED.equals(state);
}
/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
return Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state);
}
EDIT: Figured it out -- see answer below
I'm attempting to generate registration tokens, store them in a server, and then use the tokens to send push notifications. At this point, I've successfully sent and stored registration tokens and am sending notifications from a web API, but they aren't arriving to my device. I was wondering if/what I should replace R.string.gcm_defaultSenderId with (i.e. the sender key from GCM?) I'm including my code for token registration as well as my notification listener below.
public class GCMRegistrationIntentService extends IntentService {
//Constants for success and errors
public static final String REGISTRATION_SUCCESS = "RegistrationSuccess";
public static final String REGISTRATION_ERROR = "RegistrationError";
private Context context;
private String sessionGUID = "";
private String userGUID = "";
//Class constructor
public GCMRegistrationIntentService() {
super("");
}
#Override
protected void onHandleIntent(Intent intent) {
context = getApplicationContext();
sessionGUID = RequestQueueSingleton.getInstance(context).getSessionGUID();
userGUID = RequestQueueSingleton.getInstance(context).getUserGUID();
//Registering gcm to the device
registerGCM();
}
//Registers the device to Google Cloud messaging and calls makeAPICall to send the registration
//token to the server
private void registerGCM() {
//Registration complete intent initially null
Intent registrationComplete;
//declare a token, try to find it with a successful registration
String token;
try {
//Creating an instanceid
InstanceID instanceID = InstanceID.getInstance(this);
//Getting the token from the instance id
token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
//Display the token, need to send to server
Log.w("GCMRegIntentService", "token:" + token);
String android_id = Settings.Secure.getString(context.getContentResolver(),
Settings.Secure.ANDROID_ID);
int osTypeCode = Constants.OST_ANDROID;
JSONObject parms = new JSONObject();
try {
parms.put("deviceID", android_id);
parms.put("OSTypeCode", osTypeCode);
parms.put("token", token);
} catch (JSONException e) {
e.printStackTrace();
}
Transporter oTransporter = new Transporter(Constants.TransporterSubjectUSER,
Constants.REGISTER_NOTIFICATION_TOKEN, "", parms, userGUID, sessionGUID);
oTransporter.makeAPICall(getApplicationContext(), "");
//on registration complete. creating intent with success
registrationComplete = new Intent(REGISTRATION_SUCCESS);
//Putting the token to the intent
registrationComplete.putExtra("token", token);
} catch (Exception e) {
//If any error occurred
Log.w("GCMRegIntentService", "Registration error");
registrationComplete = new Intent(REGISTRATION_ERROR);
}
//Sending the broadcast that registration is completed
LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
}
}
And the listener service:
public class GCMPushReceiverService extends GcmListenerService {
private static final String TAG = "GCMPushReceiverService";
//with every new message
#Override
public void onMessageReceived(String from, Bundle data){
System.out.println("WE'VE RECIEVED A MESSAGE");
String message = data.getString("message");
Log.d(TAG, "From: " + from);
Log.d(TAG, "Message: " + message);
sendNotification(message);
}
private void sendNotification(String message) {
Intent intent = new Intent(this, LogInPage.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
int requestCode = 0;
PendingIntent pendingIntent =
PendingIntent.getActivity(this, requestCode, intent, PendingIntent.FLAG_ONE_SHOT);
Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder noBuilder = new NotificationCompat.Builder(this);
noBuilder.setContentTitle("title");
noBuilder.setContentText(message);
noBuilder.setContentIntent(pendingIntent);
noBuilder.setSound(sound);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, noBuilder.build()); //0 = ID of notification
}
}
Lastly, as it may be of some assistance, the information transporter/networking class:
public class Transporter {
private String subject;
private String request;
private String key;
private Date lastUpdateDate;
private boolean forceLoad = false;
private Date requestDate;
private Date responseDate;
private int status;
private String statusMsg = "";
private String tempKey = "";
private JSONObject additionalInfo = null;
private JSONObject parameters;
public static String sessionGUID = "";
public static String userGUID = "";
public static String SERVER = Constants.qa_api;
//transporter object to interact with the server, containing information about the request
//made by the user
public Transporter(String pSubject, String pRequest, String pKey,
JSONObject parms, String userGUID, String sessionGUID)
{
subject = pSubject;
request = pRequest;
key = pKey;
parameters = parms;
setUserGUID(userGUID);
setSessionGUID(sessionGUID);
}
//implements an API call for a given transporter, takes 2 arguments:
//the application context (call getApplicationContext() whenever it's called)
//and a String that represents the field that we are trying to update (if there is one)
//i.e. if we are calling getUserFromSession(), we want the user guid so jsonID = "userGUID"
public void makeAPICall(final Context context, final String jsonID) {
RequestQueue mRequestQueue =
RequestQueueSingleton.getInstance(context).getRequestQueue();
String targetURL = getServerURL() + "/Transporter.aspx";
StringRequest postRequest = new StringRequest(Request.Method.POST, targetURL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
String parseXML= parseXML(response);
System.out.println("response: " + parseXML);
JSONObject lastResponseContent = null;
try {
lastResponseContent = new JSONObject(parseXML);
} catch (JSONException e) {
e.printStackTrace();
}
try {
if (lastResponseContent != null && !jsonID.equals("")) {
String info = lastResponseContent.getString(jsonID);
if (jsonID.equals("userGUID")) {
userGUID = info;
RequestQueueSingleton.getInstance(context).setUserGUID(userGUID);
}
}
//put other things in here to pull whatever info
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
}) {
#Override
public byte[] getBody() throws AuthFailureError {
String body = getXML(subject,
request, "",
sessionGUID, userGUID, null, parameters);
return body.getBytes();
}
};
postRequest.setTag("POST");
mRequestQueue.add(postRequest);
}
you need to send a post to the url "https://android.googleapis.com/gcm/send":
private void sendGCM() {
StringRequest strReq = new StringRequest(Request.Method.POST,
"https://android.googleapis.com/gcm/send", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
NetworkResponse networkResponse = error.networkResponse;
Log.e(TAG, "Volley error: " + error.getMessage() + ", code: " + networkResponse);
Toast.makeText(getApplicationContext(), "Volley error: " + error.getMessage(), Toast.LENGTH_SHORT).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("data", "message that you send");
params.put("to", "token gcm");
Log.e(TAG, "params: " + params.toString());
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String,String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
headers.put("Authorization", "key="google key");
return headers;
}
};
}
So the Volley calls are non-sequential so the first call (to get a userGUID) didn't return before the second call (to register for notifications), so while the token registration was "successful," there was no corresponding user information so it didn't know how/where to send the push notification. To resolve, I made a special case in the makeAPICall class which created another StringRequest which first basically did the normal getUserFromSession but then recursively called MakeAPICall with the new userGUID information. To avoid an infinite loop, I used an if else statement: (if userGUID == null || userGUID.equals("")) then I did the recursive call, so when the first call returned that conditional was always false and it would only make one recursive call. This answer may be a rambling a bit, but the key take away is using onResponse to make another Volley call for sequential requests. See: Volley - serial requests instead of parallel? and Does Volley library handles all the request sequentially