0

I want to show a Custom Listview inside a popup window using service class. This list is fetching data from database and working fine in an activity but not in popup window. Below is my code. Any help will be appreciated.

This is my Service class:

public class PopupService extends Service{

    final static String URL = "https://billspill.com/json.php";
    private WindowManager mWindowManager;
    private View popupview;

    public PopupService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        popupview  = LayoutInflater.from(this).inflate(R.layout.popup, null);
        //Add the view to the window.
        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.TYPE_PHONE,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT);

        params.gravity = Gravity.TOP | Gravity.START;  
        params.x = 0;
        params.y = 100;

        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        mWindowManager.addView(popupview, params);
        Button close = (Button)popupview.findViewById(R.id.dismiss);
        close.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stopSelf();

            }
        });

        ListView lv = (ListView)popupview.findViewById(R.id.pager);
        new Downloader(this,lv,URL).execute();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (popupview != null) mWindowManager.removeView(popupview);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_NOT_STICKY;
    }

Below is my Downloader class which extends AsyncTask. This Downloader class calls DataParser method from DataParser class which further calls Adapter class to inflate data into the list. These three classes are working fine in an activity, but when I call Downloader in my service, the app crashes. I think there is a problem in passing the Context in Downloader from the service class.

public class Downloader extends AsyncTask<Void,Void,String> {

    Context ctx;
    ListView lv;
    ProgressDialog pd;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pd=new ProgressDialog(ctx);
        pd.setTitle("Retrive");
        pd.setMessage("Retrieving....please wait");
        pd.show();
    }

    @Override
    protected void onPostExecute(String jsonData) {
        super.onPostExecute(jsonData);
        pd.dismiss();
        if(jsonData==null)
        {
            Toast.makeText(ctx,"Unsuccessfull,No data Retrieved",Toast.LENGTH_SHORT).show();
        }
        else {
            DataParser parser = new DataParser(ctx,jsonData,lv);

            parser.execute();
        }
    }

    private String downloadData(){

        HttpURLConnection con = Connector.connect(urlAddress);
        if(con==null) {
            Toast.makeText(ctx,"Connection is null",Toast.LENGTH_LONG).show();
        }

        try{
            InputStream is = new BufferedInputStream(con.getInputStream());
            BufferedReader br = new BufferedReader(new InputStreamReader(is));

            String line;
            StringBuffer jsonData= new StringBuffer();

            while ((line=br.readLine())!=null)
            {

                jsonData.append(line+"/n");
            }
            br.close();
            is.close();
            return jsonData.toString();

        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    public Downloader(Context ctx, ListView lv, String urlAddress) {
        this.ctx = ctx;
        this.lv = lv;

        this.urlAddress = urlAddress;
    }

    String urlAddress;

    @Override
    protected String doInBackground(Void... params) {
        return downloadData();
    }

Beginning of crash:

 --------- beginning of crash
05-14 18:58:00.694 10664-10664/com.billspillsmoothshopping.android E/AndroidRuntime: FATAL EXCEPTION: main
 Process: com.billspillsmoothshopping.android, PID: 10664
 java.lang.RuntimeException: Unable to create service com.billspillsmoothshopping.android.PopupService: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
     at android.app.ActivityThread.handleCreateService(ActivityThread.java:2771)
     at android.app.ActivityThread.access$1800(ActivityThread.java:151)
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1386)
     at android.os.Handler.dispatchMessage(Handler.java:102)
     at android.os.Looper.loop(Looper.java:135)
     at android.app.ActivityThread.main(ActivityThread.java:5254)
     at java.lang.reflect.Method.invoke(Native Method)
     at java.lang.reflect.Method.invoke(Method.java:372)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:902)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:697)
  Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
     at android.view.ViewRootImpl.setView(ViewRootImpl.java:584)
     at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:282)
     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
     at android.app.Dialog.show(Dialog.java:298)
     at com.billspillsmoothshopping.android.m_MySQL.CompareDownloader.onPreExecute(CompareDownloader.java:32)
     at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:591)
     at android.os.AsyncTask.execute(AsyncTask.java:539)
     at com.billspillsmoothshopping.android.PopupService.onCreate(PopupService.java:81)
     at android.app.ActivityThread.handleCreateService(ActivityThread.java:2761)
     at android.app.ActivityThread.access$1800(ActivityThread.java:151) 
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1386) 
     at android.os.Handler.dispatchMessage(Handler.java:102) 
     at android.os.Looper.loop(Looper.java:135) 
     at android.app.ActivityThread.main(ActivityThread.java:5254) 
     at java.lang.reflect.Method.invoke(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:372) 
Pang
  • 9,564
  • 146
  • 81
  • 122

1 Answers1

0

You can not attach a popup window with the service you will have to pass the actual activity context not the service context that's the reason you r getting this error.

I would suggest you to use only asynctask https://developer.android.com/reference/java/lang/Object.html to fetch the data and show it if the service is not so necessary and if its too necessary to use service after downloading data pass this data to some activity using broadcast receiver https://developer.android.com/reference/android/content/BroadcastReceiver.html and then show the popup window. Hope it helps. P.S. "We use service for long running task and with no attachment with UI like playing audio, downloading big data's from server etc."

Reyansh Mishra
  • 1,879
  • 1
  • 14
  • 26
  • Can you please suggest me solution to this problem also?http://stackoverflow.com/questions/43981847/how-to-stop-a-running-service-using-broadcast-receiver-in-android – Priyam Tyagi May 15 '17 at 16:22