Popuprutna när widget jobbar

Diskussion i 'Frågor, support och diskussion' startad av Pajn, 15 dec 2011.

  1. Pajn

    Pajn Adult Droid Medlem

    Blev medlem:
    12 aug 2009
    Inlägg:
    606
    Mottagna gillanden:
    51

    MINA ENHETER

    Jag har gjort en Widget som när man klickar på den kör en sak. Den är väldigt enkel och är bara för att man ska slippa gå in i appen och trycka.
    Jag vill ha en popup medan den jobbar som säger att den gör det.

    Nu gör jag såhär:

    I WidgetProvider:
    Kod:
            // Create an Intent to launch ExampleActivity
            Intent intent = new Intent(mContext, WidgetClickHandler.class);
            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
            PendingIntent pendingIntent = PendingIntent.getActivity(mContext, appWidgetId, intent, 0);
    
            // Get the layout for the App Widget and attach an on-click listener
            // to the button
            RemoteViews views = new RemoteViews(mContext.getPackageName(), R.layout.widget);
            views.setOnClickPendingIntent(R.id.WidgetlinearLayout, pendingIntent);
            views.setTextViewText(R.id.WidgetText, db.getGroup(Integer.parseInt(gID)));
    
            // Tell the AppWidgetManager to perform an update on the current app widget
            appWidgetManager.updateAppWidget(appWidgetId, views);
    Och i activityn:
    Kod:
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    		
            int appWidgetId = getIntent().getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
            SharedPreferences prefs = mContext.getSharedPreferences("RAXA", 0);
        	String hostname = prefs.getString("hostname", "http://***.eu");
        	String group = prefs.getString("RAXAWidget" + appWidgetId, "n");
        	if (!group.equals("n")) {
    	  	    String gID = group.substring(1);
                String URL = hostname + "/action.php?group=" + gID;
                new HTTPhandler(mContext).execute(URL);
        	}
            //finish();
        }
    HTTPhandler har hand om jobbet och visar en popup när den börjar samt tar bort den när den är klar.

    Som det är nu visas popupen, men när den är klar stannar jag kvar i Activityn. Om jag tar bort kommentaren på finish(); blir det force close när den vill ta bort popupen eftersom den redan dödat Activityn (samt att popupen försvinner).
    Om jag lägger till .get() när jag kallar HTTPhandler så väntar den tills den är klar, problemet är att den även väntar med att rita upp activityn så att den bara blinkar till när den jobbat färdigt.

    Är det någon som har en bra lösning på mitt problem?
     
  2. ozp

    ozp Teen Droid Medlem

    Blev medlem:
    6 maj 2010
    Inlägg:
    250
    Mottagna gillanden:
    31

    MINA ENHETER

    Du får ha ett callback från HTTPhandler till din aktivitet och göra finish i callbacket
     
    Pajn gillar detta.
  3. Pajn

    Pajn Adult Droid Medlem

    Blev medlem:
    12 aug 2009
    Inlägg:
    606
    Mottagna gillanden:
    51

    MINA ENHETER

    Jag är inte så duktig på Java så jag tittade på Java Tip 10: Implement callback routines in Java - JavaWorld

    Problemet är att den blev blockande + att Callbacken inte verkar köras :ehm:

    Här är koden för HTTPhandler
    Kod:
    package com.pajn.raxa.mobile;
    
    import java.io.BufferedInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import java.net.URL;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.HttpClient;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.params.HttpParams;
    import org.apache.http.util.ByteArrayBuffer;
    
    import android.app.ProgressDialog;
    import android.content.Context;
    import android.os.AsyncTask;
    import android.util.Log;
    
    
    public class HTTPhandler extends AsyncTask<String, Void, String> {
    	private Callback Callback = null;
    	
        private final HttpClient httpclient = new DefaultHttpClient();
    
        final HttpParams params = httpclient.getParams();
        HttpResponse response;
    
        private Context mContext;
        ProgressDialog pd;
    
        public HTTPhandler(Context context) {
            this.mContext = context;
        }
        
    	String hostname = "";
    
        protected void onPreExecute() {
        	pd = ProgressDialog.show(mContext, "Executing", "Please wait", true, false);
        }
    
    	@Override
        protected String doInBackground(String... URL) {
        	
    		InputStream in = null;
    		String result = "";
    		try {
    		    URL url = new URL(hostname + URL[0]);
    			HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
    			HttpURLConnection httpConn = (HttpURLConnection) urlConn;
    			httpConn.setAllowUserInteraction(false);
    			httpConn.connect();
    			in = httpConn.getInputStream();
    			BufferedInputStream bis = new BufferedInputStream(in);
    			ByteArrayBuffer baf = new ByteArrayBuffer(50);
    			int read = 0;
    			int bufSize = 512;
    			byte[] buffer = new byte[bufSize];
    			while(true){
    			    read = bis.read(buffer);
    			    if(read==-1){
    			    	break;
    			    }
    			    baf.append(buffer, 0, read);
    			}
    			result = new String(baf.toByteArray());
    		} catch (MalformedURLException e) {
    			// DEBUG
    			Log.e("DEBUG: ", e.toString());
    		} catch (IOException e) {
    			// DEBUG
    			Log.e("DEBUG: ", e.toString());
    		}
    
            return result;
        }
    	
        protected String execute(Callback CB, String... URL) {
        	Callback = CB;
        	return doInBackground(URL);
        }
    
        protected void onPostExecute(String content) {
        	pd.dismiss();
        	if (!Callback.equals(null)) {
        		Callback.Callback();
        	}
        }
    }
    Och jag kallar den helt enkelt med new HTTPhandler(mContext).execute(this, URL);

    EDIT: Nu var jag lite för snabb. Det var constructorn som jag skulle lägga till ett nytt "alternativ" till.
    Nu funkar det, nästan.
    Enda problemet är att när jag kör finish(); så tar den bort activityn, men istället för att skicka tillbaka mig till hemskärmen skickar den mig till den första activityn i min app som tydligen också har hamnat i stacken. Hur löser jag det?
     
    Last edited: 16 dec 2011
  4. ozp

    ozp Teen Droid Medlem

    Blev medlem:
    6 maj 2010
    Inlägg:
    250
    Mottagna gillanden:
    31

    MINA ENHETER

    Du borde kunna använda FLAG_ACTIVITY_NEW_TASK

    Skicka in den till ditt i ditt pending intent som startar aktiviteten
     
  5. Pajn

    Pajn Adult Droid Medlem

    Blev medlem:
    12 aug 2009
    Inlägg:
    606
    Mottagna gillanden:
    51

    MINA ENHETER

    Nej det hjälpte inte tyvärr :(
    Jag antar att den jag söker är FLAG_ACTIVITY_TASK_ON_HOME men den finns först med i API ver 11

    Går det att känna av i min "start" activity att jag kommer från den andra och då köra finish() i den med?

    EDIT:
    Jag flyttade koden i WidgetClickHandler till den första activityn och låter den hantera både och. Då funkar det om jag har backat ur appen med bakåtknappen, men om jag har använt hemknappen öppnas den senaste activityn jag var i (antagligen var det så förut med, jag testade inte lika mycket då). Så på nått sätt måste jag tömma stacken...

    EDIT2:
    Jaa! Äntligen.
    android:launchMode="singleInstance" på WidgetClickHandler var lösningen (möjligtvis tillsammans med alla flaggor jag skickade, har inte testat utan dem.)
     
    Last edited: 16 dec 2011