androidUser1993
androidUser1993

Reputation: 175

Android - Use Broadcast Receiver to reload activity

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.

Upvotes: 0

Views: 356

Answers (1)

sbso
sbso

Reputation: 403

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 = ""});

Upvotes: 1

Related Questions