Vishal Kumar
Vishal Kumar

Reputation: 4627

Can not call activity method from another class via Service

I want to sync my app in the background...and using notification based approach for this. I have a broadcast receiver, Service , Activity and another java class with Context reference of Receiver. On receiving push notification... the receiver calls the Service and the Service calls BackgroundSync. BackgroundSync class performs some volley network calls and on success, it stores data in local DB inside an Async Task. Now in onPostExecute() of this class.. I want to call a method on activity to show a dialog.

//Inside service. This method is called from receiver on receiving push notification

public static void syncDataFromServer(Context context) {
  Toast.makeText(context, "Data Sync Started", Toast.LENGTH_LONG).show();
  try {
    new BackgroundSync(context);
    Log.d("SYNC", "Called BackgroundSync Class with Context " + context);
  } catch (Exception e) {
    Log.d("SYNC", "Exception BackgroundSync Class :" + e.toString());
  }
}

This is the background sync class:

public class BackgroundSync implements IRequestCallback {

    private Context context;

    BackgroundSync(Context context) {
    this.context = context;
    fetchRetailers(context);
    }

    private class InsertTask extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... params) {
    try {
    DBAdapter dbAdapter = new DBAdapter(context);
    dbAdapter.open();
    dbAdapter.insertData(params[0], false);
    dbAdapter.close();
    Log.d("SYNC", "Retailers saved to Local database in Async Task of BackgroundSync");
    } catch (IllegalAccessException e) {
    Log.d("SYNC", "Exception "+e.toString());
    }
    return "";
    }

    @Override
    protected void onPostExecute(String s) {
    super.onPostExecute(s);
    MainActivity.notifyBackgroundSyncDone(context);
    }
    }

    @Override
    public void fetchRetailerResponseAPI(Object response, String str) {
    try {
    new InsertTask().execute(response.toString());
    Log.d("SYNC", "Fetch Retailer API Success");
    } catch (Exception e) {
    Log.d("SYNC", "Exception "+e.toString());
    }
    }
    }


    public void fetchRetailers(Context context) {
    try {
    BaseData baseData = new BaseData();
    baseData.setApi(Constants.VIEW_RETAILERS_API);
    baseData.setUrl(CommonUtil.getBaseUrl() + "distributors/" + Integer.parseInt(Prefs.getId(context)) + "/retailers");
    baseData.setPostOrGet(Request.Method.GET);
    Task task = new Task(this, context);
    task.getData(baseData);
    Log.d("SYNC", "Fetching retailers from Server");
    } catch (Exception e) {
    Log.d("SYNC", "Exception "+e.toString());
    }
    }
}

Everything is working well... and I am able to display a toast in my activity ..however I can't show a dialog. Looks like there is some problem with various contexts.

This is the method in the activity:

 public static void notifyBackgroundSyncDone(Context context){
        Toast.makeText(context, "Data Sync Finished", Toast.LENGTH_LONG).show();

        AlertDialog.Builder builder1 = new AlertDialog.Builder(context);
        builder1.setMessage("Write your message here.");
        builder1.setCancelable(true);
        builder1.setPositiveButton("Yes",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.cancel();
                    }
                });
        builder1.setNegativeButton("No",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.cancel();
                    }
                });

        AlertDialog alert11 = builder1.create();
        alert11.show();

    }

Upvotes: 0

Views: 87

Answers (2)

mahesh singh
mahesh singh

Reputation: 212

do this and try it may show your dialog

public static void notifyBackgroundSyncDone(Context context){
        Toast.makeText(context, "Data Sync Finished", Toast.LENGTH_LONG).show();

        AlertDialog.Builder builder1 = new AlertDialog.Builder(context);
        builder1.setMessage("Write your message here.");
        builder1.setCancelable(true);
        builder1.setPositiveButton("Yes",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                       // dialog.cancel();
                    }
                });
        builder1.setNegativeButton("No",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                       // dialog.cancel();
                    }
                });

        AlertDialog alert11 = builder1.create();
        alert11.show();

    }

Upvotes: 0

Mike M.
Mike M.

Reputation: 39191

AlertDialogs, and therefore their Builders, require an Activity Context from which to draw GUI-related settings and resources. The Context you're passed in your BroadcastReceiver is an Application Context, which will not have those necessary resources, and will cause the AlertDialog creation to fail.

If you want to show a something very similar to an AlertDialog directly from a Service or a BroadcastReceiver, you can create an Activity with a Dialog theme, and start it with an Intent with any necessary data attached as extras.

Upvotes: 1

Related Questions