This Android app is using Android Studio. The function is to scan and display data from the beacon/eddystone. The app already functions and after the scanning stops, the data saves to the local file. I need to transfer the data to the server. How can i insert the volley coding to the mainacitivity.java. I tried to put under the stopscanning button, but it shows error. Im really beginners to learn about android studio.
Here is the coding:
private void stopScanning(Button scanButton) {
try {
beaconManager.stopRangingBeaconsInRegion(region);
} catch (RemoteException e) {
// TODO - OK, what now then?
}
String scanData = logString.toString();
if (scanData.length() > 0)
{
public class MainActivity extends AppCompatActivity {
//The values of these variables will be fetched by the file(Where you will store data)
private String PREFERENCE_SCANINTERVAL = "scanInterval";
private String PREFERENCE_TIMESTAMP = "timestamp";
private String PREFERENCE_POWER = "power";
private String PREFERENCE_PROXIMITY = "proximity";
private String PREFERENCE_RSSI = "rssi";
private String PREFERENCE_MAJORMINOR = "majorMinor";
private String PREFERENCE_UUID = "uuid";
private String PREFERENCE_INDEX = "index";
private String PREFERENCE_LOCATION = "location";
private String PREFERENCE_REALTIME = "realTimeLog";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String url = "http://beaconscanner.byethost33.com/beaconscanner.php";//This is the url of your server where you will be sending the data to.
//StringRequest is a class in the Volley Library.
//The constructor of this class has four parameters.
// 1 parameter is Request.Method.POST =this specifies the method type, That is post.
//2 parameter is the url you will be sending the request to.That is the server
//3 parameter is the response listener , It will listen for any response from your server . you will be able to fetch the response from the server using this.
//4 parameter is the error listener, it will listen for any error's during the connection or etc.
StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//Here you will be able to fetch the response coming from the server.
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
})
//This is the method we override.
{
//This is method is used to send the data to the server for post methods. This method returns all the data you want to send to server. This is how you send data using Volley.
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> params = new HashMap<String, String>();
params.put("scanInterval",PREFERENCE_SCANINTERVAL);
params.put("timestamp",PREFERENCE_SCANINTERVAL);
params.put("power",PREFERENCE_POWER);
params.put("proximity",PREFERENCE_PROXIMITY);
params.put("rssi",PREFERENCE_RSSI);
params.put("majorMinor",PREFERENCE_MAJORMINOR);
params.put("uuid",PREFERENCE_UUID);
params.put("index",PREFERENCE_INDEX);
params.put("location",PREFERENCE_LOCATION);
params.put("realTimelog",PREFERENCE_REALTIME);
return params;
}
};//The constructor ends here.
Volley.newRequestQueue(this).add(request);// This is the main potion of this code. if you dont add this you will not be able to send the request to your server. this helps you to send it.
}
}
// Write file
fileHelper.createFile(scanData);
// Display file created message.
Toast.makeText(getBaseContext(),
"File saved to:" + getFilesDir().getAbsolutePath(),
Toast.LENGTH_SHORT).show();
scanButton.setText(MODE_STOPPED);
} else {
// We didn't get any data, so there's no point writing an empty file.
Toast.makeText(getBaseContext(),
"No data captured during scan, output file will not be created.",
Toast.LENGTH_SHORT).show();
scanButton.setText(MODE_STOPPED);
}
}
Please add your stacktrace. Also I guess that you want to send the data using the body not the params :). In that case, call the request using the following signature:
new JsonObjectRequest(Request.Method.POST, url, new JSONObject(bodyData), new Response.Listener<JSONObject>() { }
public void sendMyData(HashMap map) {
String url = "http://"....";
StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
progressBar.setVisibility(View.INVISIBLE);
try {// to receive server response, in this example it's jsonArray
JSONArray jsonArray = new JSONArray(response);
//code
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println(error);
}
}) {
#Override
public String getBodyContentType() { // if your server uses java restfull webservice , you have to override this content type
return "application/json";
}
#Override
protected Map<String, String> getParams() throws AuthFailureError {// parameters which should server receive
Map<String, String> parameters =map;
return parameters;
}
};
requestQueue.add(request);
}
Related
I am working on chatbot which uses API to get data but when i make request in start it is working good but if i want to make another request , the result is still the old response from old request, which i have to send request again to get new result. Is there any solution ????
i tried wait() in function that have volley requests but it does not work
public String getResult(String team1,String team2,String code,Context context)
{
this.context=context;
//"https://apifootball.com/api/?action=get_H2H&firstTeam=Arsenal&secondTeam=Chelsea&APIkey=7"
String URL="https://apifootball.com/api/?action=get_H2H&firstTeam="+team1+"&secondTeam="+team2+"&APIkey=7";
//"https://apifootball.com/api/?action=get_countries&APIkey=7";
RequestQueue rq= Volley.newRequestQueue(context);
JsonObjectRequest objreq= new JsonObjectRequest(
Request.Method.GET,
URL,
null,
new Response.Listener<JSONObject>()
{
#Override
public void onResponse(JSONObject response) {
String Scores="";
// Log.e("result:",response.get(0).toString());
JSONObject obj;
// obj=response.getJSONObject("firstTeam_VS_secondTeam");
try {
JSONArray obj2 =response.getJSONArray("firstTeam_VS_secondTeam");
Log.e("obj", obj2.getJSONObject(0).getString("match_hometeam_score"));
Scores=Scores+ obj2.getJSONObject(0).getString("match_hometeam_score")+"\n"+obj2.getJSONObject(0).getString("match_awayteam_score")+"\n"+obj2.getJSONObject(0).getString("match_date");
} catch (JSONException e) {
}
String []arr = Scores.split("\n");
model = new ChatModel("First team:"+arr[0]+"\nSecond team:"+arr[1]+"\n"+"Date:"+arr[2], false);
list_chat.add(model);
//share(Scores);
}
},
new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError error) {
Log.e("rest response",error.toString());
}
}
);
rq.add(objreq);
SharedPreferences m= PreferenceManager.getDefaultSharedPreferences(context);
final String resp=m.getString("Response","");
return resp;
}
main activity
if(result.equals("error")==true) {
APIAdapter ap = new APIAdapter();
head2Head = ap.getResult("Bristol City", "Reading", "kjkn", getApplicationContext());
finres = head2Head;
Log.e("headto",head2Head);
arr = head2Head.split("\n");
//send(arr[2],false);
// model = new ChatModel("First team:"+arr[0]+"\nSecond team:"+arr[1]+"\n"+"Date:"+arr[2], false); // user send message
/*
Team t1=new Team(3,"Bristol City");
Team t2=new Team(0,"Reading");
Long tid1=x.insertTeam(t1);
Long tid2=x.insertTeam(t2);
Match m=new Match(0,Integer.parseInt(String.valueOf(tid1)),Integer.parseInt(String.valueOf(tid2)),arr[2]);
Long mid=x.insertMatch(m);
Log.e("mid",String.valueOf(mid));
Result resul=new Result(0,Integer.parseInt(String.valueOf(mid)),x.getTeam(tid1).getTeamId(),x.getTeam(tid2).getTeamId(),Integer.parseInt(arr[0]),Integer.parseInt(arr[1]));
x.insertResult(resul);
*/}
send("First team:"+arr[0]+"\nSecond team:"+arr[1]+"\n"+"Date:"+arr[2], false);
}
send()
void send(String text,boolean sender)
{
ChatModel model = new ChatModel(text,sender); // user send message
list_chat.add(model);
CustomAdapter adapter = new CustomAdapter(list_chat,getApplicationContext());
listView.setAdapter(adapter);
//remove user message
editText.setText("");
}
I am not sure if i understand what your problem is but i will do my best to help.
Define RequestQueue outside of the function(onCreate() can be a good place), this way you don't init it every time you make a request and it can actually work as a Queue for requests.
There might be a problem with the way you handle list_chat, please post the code that you use to display it.
I am developing an android application and I have one activity which shows all the tables in a restaurant. Within this activity, there is a method to change the table color (the table is just a button) based on whether a customer is at the table.
On the customer's screen, when they select their table, my MYQSL database is updated and the user is now assigned to the table.
Now, when I go to open the map screen (note: this is used by waiters on the app, it cant be accessed by customers), the table will be a different color (it checks the table status in the db, if the table is assigned it is a different color).
However, the only way to get the updated map is by reloading the map activity. I want the map activity to update automatically using a BroadcastReceiver() but I am struggling to find a tutorial on how to implement this. When a customer clicks a table to assign themselves to it, I want the broadcast to be sent, automatically reloading the map activity... Is this possible? And if so, how do I implement it?
EDIT: The waiter and customer are using the same application but on different devices
The ChooseTable activity has an on click listener for each table which results in the following method being called:
private void assignUserToTable(final int table, final String userid) {
String url = "hidden";
StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
if (response.trim().equals("success")) {
Toast.makeText(ChooseTable.this, "Welcome!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(ChooseTable.this, "Oops, something went wrong!", Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(ChooseTable.this, "Error! " + error.toString(), Toast.LENGTH_LONG).show();
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("table_id", String.valueOf(table));
params.put("user", userid);
return params;
}
};
MySingleton.getInstance(this).addToRequestQueue(stringRequest);
}
The waiter map view looks has the following method which checks the table status on the activity being loaded:
private void checkTables(){
String url = "hidden";
StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try{
JSONObject jsonObject = new JSONObject(response);
String success = jsonObject.getString("success");
JSONArray jsonArray = jsonObject.getJSONArray("toggles");
if(success.equals("1")){
for(int i=0; i<jsonArray.length(); i++){
JSONObject object = jsonArray.getJSONObject(i);
String tableid = object.getString("tableid");
if(Tbl1.getTag().equals(tableid)){
Tbl1.setBackgroundColor(ContextCompat.getColor(WaitingStaffMapScreen.this, R.color.tableReq));
} else if(Tbl2.getTag().equals(tableid)){
Tbl2.setBackgroundColor(ContextCompat.getColor(WaitingStaffMapScreen.this, R.color.tableReq));
} else if(Tbl3.getTag().equals(tableid)){
Tbl3.setBackgroundColor(ContextCompat.getColor(WaitingStaffMapScreen.this, R.color.tableReq));
} else if(Tbl4.getTag().equals(tableid)){
Tbl4.setBackgroundColor(ContextCompat.getColor(WaitingStaffMapScreen.this, R.color.tableReq));
} else if(Tbl5.getTag().equals(tableid)){
Tbl5.setBackgroundColor(ContextCompat.getColor(WaitingStaffMapScreen.this, R.color.tableReq));
} else if(Tbl6.getTag().equals(tableid)){
Tbl6.setBackgroundColor(ContextCompat.getColor(WaitingStaffMapScreen.this, R.color.tableReq));
} else if(Tbl7.getTag().equals(tableid)){
Tbl7.setBackgroundColor(ContextCompat.getColor(WaitingStaffMapScreen.this, R.color.tableReq));
} else if(Tbl8.getTag().equals(tableid)){
Tbl8.setBackgroundColor(ContextCompat.getColor(WaitingStaffMapScreen.this, R.color.tableReq));
}
}
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(WaitingStaffMapScreen.this, "Oops, something went wrong!", Toast.LENGTH_LONG).show();
}
}
},new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(WaitingStaffMapScreen.this, "Error! " +error.toString(), Toast.LENGTH_LONG).show();
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("table_id", "0");
return params;
}
};
MySingleton.getInstance(this).addToRequestQueue(stringRequest);
}
Essentially I want some means of reloading the map screen activity when a table button has been clicked.
Since everything is running on separate devices, what I would do is implement firebase cloud messaging:
https://firebase.google.com/docs/cloud-messaging/android/client
When the application is started, the device receives a token.
When the device receives this token, you will POST it to your database(assuming you have a table of devices) under a new column(ie: FirebaseToken) for that device row.
When the table status is updated(ie: a user selects a table), and that reaches out to the server, you will have a query that goes through each device registered to the business, and sends a push notification.
Then on the android app, you will have a firebase service running that receives the push notification(ie:)
public class MyFirebaseMessagingService extends FirebaseMessagingService
{
NotificationManager notificationManager;
#Override public void onMessageReceived(RemoteMessage remoteMessage)
{
Map<String,String> data = remoteMessage.getData();
if (data.get("title").equals("Update Tables")) {
//Call logic to update the adapter
}
}
}
Very general gist of it. Relatively easy to implement. Any questions, I can do my best to clarify.
As the below comment said, using group messaging is best. I didn't know how many devices each business would have, so was trying to keep it as simple as possible.
Here is a server side example. This will simply send a push notification to the phone, and will be received in the FirebaseMessagingService class you extended.
public bool SendMessage(string firebaseTokenId, FirebaseMessages type)
{
httpWebRequest = (HttpWebRequest)WebRequest.Create("http://fcm.googleapis.com/fcm/send");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Headers.Add("Authorization", "your key");
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
var messageToSend = new Message()
{
to = firebaseTokenId,
data = new DataPayload()
{
title = firebaseMessages[type].title,
message = firebaseMessages[type].body,
}
};
string json = JsonConvert.SerializeObject(messageToSend, Formatting.Indented);
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
}
public enum FirebaseMessages
{
UpdateTables
}
public class Message
{
public DataPayload data {get;set;}
public string to { get; set; }
}
public class DataPayload
{
public string title { get; set; }
public string message { get; set; }
}
//on the on receive, this is a datapayload(not notification), so no push intent will ever be shown, hence you can leave the body null.
firebaseMessages.Add(FirebaseMessages.MessageReceived, new FirebaseMessage() { title = "Table Update", body = ""});
I am using volley to upload my bitmap file to the server. In server side, i'm using codeigniter framework to do that job but i've got response from the server when I trying to upload the file that says,
"you did not select a file to upload"
here is the code
Volley
public void uploadImage(final Context context, final Bitmap bitmap) {
String url = "https://zenosama1111.000webhostapp.com/Upload/do_upload";
RequestQueue requestQueue = Volley.newRequestQueue(context);
StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, 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("thumbnail", bitmapToString(bitmap));
return params;
}
};
requestQueue.add(request);
}
server side
public function do_upload()
{
$config['upload_path'] = './thumbnails/';
$config['allowed_types'] = 'gif|jpg|png|jpeg';
$config['max_size'] = 100;
$config['max_width'] = 160;
$config['max_height'] = 100;
$this->load->library('upload', $config);
if ( ! $this->upload->do_upload('thumbnail'))
{
echo false;
}
else
{
echo true;
}
$error = array('error' => $this->upload->display_errors());
echo json_encode($error);
}
other tutorials are using pure php code to upload a file but not in codeigniter..
somebody know how can i fix this problem?
This $this->upload->do_upload($this->input->post('thumbnail')) or $this->upload->do_upload('thumbnail') won't work.
do_upload will only work with an item from the $_FILES array (different than post array) and the parameter of do_upload($param) must be the fieldname of the file input.
e.g. <input name="userfile" type="file"> => do_upload('userfile')
It isn't intended to be used the way you are using it as your item is in the post array. Hence maybe a file_put_contents($filename, $this->input->post('thumbnail')); would work for your needs.
If you could get the item to be in the $_FILES array then you might have a chance of using the CI upload library.
I have a LoginActitvity with two textfields for the username and password and a login-button. When the user presses the button, the app starts an async task. The async task implements my VolleyHandler. It checks if the login parameters are correct and fetches some user data (using volley and json). While doing this, a ProgressDialog appears. When the async task is finished, it starts an intent to the MainActivity in the onPostExecute method.
Now to my question: Is it a good idea to make volley-requests in the async task, or do you have a better solution?
Thanks.
You cannot use asynctask. Volley care about it. You can use callback for work with data and ui.
Looks like this:
public class LoginActivity extends SinglePaneActivity implements DownloadCallback {
//...
public void sendRequest(){
Downloader download = new Download(this);
downloader.download(userName, password);
progresbar.show();
}
public void requestFinish(){
progersbar.dismis();
//... continue
}
}
callback:
public interface DownloadCallback {
void requestFinish();
}
in class downloader
private RequestQueue requestQueue;
DownloadCallback mcallback;
public void Downloader(DownloadCallback callback){
mCallback = callback;
requestQueue = Volley.newRequestQueue(mContext);
initVolleyListeners();
}
private void initVolleyListeners() {
mSuccessListener = new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
mCallback.requestFinish();
}
};
mErrorListener = new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
mCallback.requestFinish();
}
};
public void download(String user, String pass){
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, createJson(user, pass), mSuccessListener , mErrorListener ) {
//header for send JSON to server
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json; charset=utf-8");
return headers;
}
};
requestQueue.add(jsonObjectRequest );
}
And one point. Don't send user name in json. You send it as param in header. Use this application/x-www-form-urlencoded and set up pass an username as params in header.
Update:
Now It will work. Sorry I wrote it in a hurry.
Article about how callback work
if (isConnected()) {
Event eInstance = new Event();
theEvents = eInstance.downloadEvents(eventsNightlife, getActivity());
rAdapter = new RecyclerAdapter(theEvents);
recyclerView.setAdapter(rAdapter);
progrsBar.setVisibility(View.GONE);
....
This is part of the code that runs at "onCreateView". The method downloadEvents uses Volley to download JSON data, extract it and return a list of items (theEvents). Now when my app starts, the recycler view is empty. If I go to my home screen out of the app and then run my app again, this time the data sometimes gets downloaded.
I debugged step by step, and at first launch (i mean when the app is not just resuming), theEvents is empty, so the download didn't return or manage to return anything...
Suggestions on how to execute things before the UI has been shown to the user or what actually needs to be done to approach this task better?
Also, I use a swipeRefreshLayout and at its onRefresh method I do:
public void onRefresh() {
Event eInstance = new Event();
theEvents = eInstance.downloadEvents(eventsNightlife, getActivity());
rAdapter.notifyDataSetChanged();
swipeRefreshLayout.setRefreshing(false);
}
but it doesn't work. I also tried to
rAdapter = new RecyclerAdapter(theEvents);
rAdapter.notifyDataSetChanged();
recyclerView.swapAdapter(rAdapter, false);
still not working.
EDIT: My downloadEvents method implementing Volley:
public List<Event> downloadEvents(String urlService, Context context) {
eventsList = new ArrayList<>();
RequestQueue requestQueue = Volley.newRequestQueue(context);
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest
(Request.Method.GET, urlService, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try {
String durationStr = null;
for (int i = 0; i < response.length(); i++) {
JSONObject eventJson = response.getJSONObject(i);
String title = eventJson.getString("EventTitle");
String body = eventJson.getString("EventBody");
String date = eventJson.getString("EventDate");
String time = eventJson.getString("EventTime");
int duration = Integer.parseInt(eventJson.getString("EventDuration"));
if (duration > 60) {
durationStr = "Duration: " + duration / 60 + " h";
} else if (duration < 60) {
durationStr = "Duration: " + duration + " m";
}
String place = eventJson.getString("EventPlace");
String organ = eventJson.getString("Organization");
Event event = new Event(title, body, date, time, durationStr, place, organ);
eventsList.add(event);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("VOLLEY ERROR", "" + error);
}
}
);
requestQueue.add(jsonArrayRequest);
return eventsList;
}
You can use EventBus for your purpose that is a simple and truth way.
Here, i write an example for how to use EventBus with volley.
Consider that i want to download some data.
This is the class that my download methods is inside it (you can add more methods to it in the future):
Im used volley to download my data:
// Download methods is inside volley
public class MyDownloader{
public static void downloadData(){
DownloadDataEvent dlDataEvent=new DownloadDataEvent();
List<String> myResult=new ArrayList<>();
...
#Override
public void onResponse(JSONArray response) {
super.onResponse(response);
if(respone!=null){
// Do what i want with my received data
dlDataEvent.setData(response);
}
// Post my event by EventBus
EventBus.getDefault().post(dlDataEvent);
...
}
}
}
This is my event:
public class DownloadDataEvent{
private JSONArray mData;
public void setData(JSONArray data){
mData=data;
}
public JSONArray setData(){
return mData;
}
}
Now i want to use my downloadData() method inside my MainActivity:
(I called my downloadData method inside onCreate.)
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
...
// I have to register this class for EventBus subscriber:
if(!EventBus.getDefault().isRegister(this)){
EventBus.getDefault().registerSticky(this);
}
// Call my downloadData method
if(isConnected()){
MyDownloader.downloadData();
}
}
// And for receive the data through EventBus, i have to create a
// method (subscriber) in this template:
public void onEventMainThread(DownloadDataEvent downloadDataEvent){
JSONArray result=downloadDataEvent.getData();
// Do what i want with my received data
}
}
you can create more than one subscriber every where you want to use received data.
I passed JSONArray to my DownloadDataEvent that it is not good. you can deserialize your received data and pass it to your DownloadDataEvent.
I used Volley to download data
Maybe my descriptions were confusing, but EventBus is a well-known library and is very easy to use.