[ERLEDIGT] Widget reagiert nicht auf Click mit anschliessendem Http-Request

  • 23 Antworten
  • Letztes Antwortdatum
Tatmotiv

Tatmotiv

Ambitioniertes Mitglied
6
Hi,

ich bekomme mein Gehirn einfach nicht so gewickelt, das ich mit Java klar komme. Darum würde ich mir sehr über Hilfe freuen.

Ich hab eine Activity (die ist für die Frage aber egal) und ein Homescreen widget in dem ich beim drauf klicken daten aus dem Netz laden will (eine klassische WetterApp :D).

Ich habe soweit mit intents und pending intents rumgefummelt das bei onClick eine random Zahl in widget gezaubert wird und auch das reine downloaden der Daten ist mittels HttpURLConnection auch gelöst. Aber die beiden Funktionen zu verheiraten klappt nicht.

Code:
/*
* Implementation of App Widget functionality.
*/
public class RawDataWidget extends AppWidgetProvider {

    static AppWidgetManager globalAppWidgetManager;

    static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId)
    {
    }

    @override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {

    // There may be multiple widgets active, so update all of them
    for (int appWidgetId : appWidgetIds) {

        // Get the layout for the App Widget
        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.raw_data_widget);

        // start data download
        try {

            String data = new downloadTask().execute("<domain die daten liefert>").get();

        }
        catch (ExecutionException | InterruptedException ei) {

            ei.printStackTrace();

        }

        // Update the widget text
        String number = String.format("%03d", (new Random().nextInt(900) + 100)) + "\n";
        views.setTextViewText(R.id.raw_widget_text, number + data);

        // Creating a pending intent, which will be invoked when the user clicks on the widget
        Intent refreshIntent = new Intent(context, RawDataWidget.class);
        refreshIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
        refreshIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, refreshIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        views.setOnClickPendingIntent(R.id.raw_widget_frame, pendingIntent);

        // Instruct the widget manager to update the widget
        appWidgetManager.updateAppWidget(appWidgetId, views);
        }

    }

    private static class downloadTask extends AsyncTask<String, String, String> {

        protected void onPreExecute() {

            super.onPreExecute();

        }

        protected String doInBackground(String... params) {

            HttpURLConnection connection = null;
            BufferedReader reader = null;

            try {

                URL url = new URL(params[0]);
                connection = (HttpURLConnection) url.openConnection();
                connection.connect();
                InputStream stream = connection.getInputStream();
                reader = new BufferedReader(new InputStreamReader(stream));
                StringBuffer buffer = new StringBuffer();
                String line = "";
                while ((line = reader.readLine()) != null) {

                    buffer.append(line+"\n");

                }
                return buffer.toString();

            } catch (MalformedURLException e) {

                e.printStackTrace();

            } catch (IOException e) {

                e.printStackTrace();

            } finally {

                if (connection != null) {

                    connection.disconnect();

                }
                try {

                    if (reader != null) {
                    reader.close();

                }
                } catch (IOException e) {

                    e.printStackTrace();

                }

            }
            return null;

        }

        @override
        protected void onPostExecute(String result) {

            super.onPostExecute(result);

        }

    }

}




Hier meine myWidget.java:

Und das ganze funktioniert auch, jedesmal, wenn die App aus AndroidStudio gestartet wird oder das Widget neu auf dem Homescreen erzeugt wird, erscheinen eine neue random Nummer und die heruntergeladenen Daten im Widget.

Aber beim klick auf das widget erscheint keine neue random nummer und es werden auch keine neuen Daten downgeloaded. Ist der Teil mit try { downloadTask()... nicht mit drin, wird bei jedem click auf das widget wieder nur eine neue RandomNummer angezeigt, aber warum das mit dem download zusammen nicht klappt, verstehe ich nicht.

Eure Hilfe wäre toll.
Danke und Gruß
tm
 
Zuletzt bearbeitet:
Hallo tm ,

jetzt habe ich mir mal den Code Lesbar gemacht und schaue es mir mal an :)

Ich lasse mal dein Widget komplett ausser acht und frage mal , was dein Async macht wenn du ihn
durch einen Click erneut anstösst.

Gibt er auch schon keine neue Daten heraus ?
 
Zuletzt bearbeitet:
Hi Swa00,
danke für die Formatierung. Den code tag hab ich gesucht, aber nicht gefunden. Jetzt sehe ich ihn auch. Und hab gleich mal die Einrückungen wieder richtig hergestellt.

Im widget habe ich den AsyncTask bisher noch nie zwei mal funktionieren gesehen.
Grundsätzlich funktioniert er aber schon, denke ich, denn das gleiche Konstrukt verwende ich in der Aktivity bei einem button onClickListener() und da tut es auch mehrmals.
 
Moin,

ich habe die Vermutung , dass dein erster Async nicht beendet ist
Starte ihn mal bitte mit downloadTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

Wenn es dann funktioniert , dann hängt er sich der Erste auf , oder ist noch nicht fertig .
Mit dem obigen Versuch wird jedesmal ein Neuer gestartet und wartet nicht auf den Vorherigen
(Ist aber nicht SInn und Zweck der Sache)

Und dann würde ich allerdings eher für so etwas grundsätzlich ION oder Ähnliches verwenden.
Was für eine Art Daten bekommst du denn dort eigenlich ?


Ergo : Du beginnst sofort mit was Anderem ,nachdem du den Thread gestartet hast
Code:
  String number = String.format("%03d", (new Random().nextInt(900) + 100)) + "\n";
        views.setTextViewText(R.id.raw_widget_text, number + data);

        // Creating a pending intent, which will be invoked when the user clicks on the widget
        Intent refreshIntent = new Intent(context, RawDataWidget.class);
        refreshIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);

Da fehlt bei Dir eine Callback Mimik
Und im PostExecute machst du mit den String praktisch gar nichts

Desweitern : deklariere deinen Thread nicht static
 
Zuletzt bearbeitet:
  • Danke
Reaktionen: Tatmotiv
swa00 schrieb:
ich habe die Vermutung , dass dein erster Async nicht beendet ist
Starte ihn mal bitte mit downloadTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

Wenn es dann funktioniert , dann hängt er sich der Erste auf , oder ist noch nicht fertig .
Mit dem obigen Versuch wird jedesmal ein Neuer gestartet und wartet nicht auf den Vorherigen
(Ist aber nicht SInn und Zweck der Sache)

Was für eine Art Daten bekommst du denn dort eigenlich ?

Das hab ich so umgesetzt:
Code:
String data = new downloadTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "<url zum Server der die Daten liefert>").get();

Änderte aber erstmal nichts am Verhalten

Das mit dem Async ist bei meiner Version eh so ein bisschen gelogen, denn das .get() am Ende des Aufrufes sorgt dafür, das auf die Rückgabe gewartet wird. Darum kann es auch sofort "data" zugewiesen werden. Das geht, weil nur einige wenige Zeichen json (also ein String) vom Server kommt. Halt nur so Temperatur und Feinstaubdaten. Wirklich nichts großes und immer in weniger als 2 Sek übertragen.

swa00 schrieb:
Da fehlt bei Dir eine Callback Mimik
Und im PostExecute machst du mit den String praktisch gar nichts

Jo, weiß ich. Ist aber nicht nötig wegen dem .get(). Dahingehend hab ich aber auch schon mehrfach versucht es umzubauen. Ich scheitere immer daran, das ich context und appWidgetManager nicht an die andere Klasse weitergegeben bekomme. Diese braucht es aber um wieder das Widget neu zeichnen zu können.

swa00 schrieb:
Desweitern : deklariere deinen Thread nicht static
Gemacht. Ändert aber bisher auch nichts.
 
Also ich komme eigentlich nicht ganz mit deiner Vorgehensweise zurecht , denn eigentlich verwendest du einen AsyncTask
nicht so , wie er wendet werden soll.

Die Technik mit get() ist eh ein wenig veraltet und die Übergabe deines Strings (link) auch nicht so richtig.
Darf ich fragen , woher du das hast ?

Wirklich nichts großes und immer in weniger als 2 Sek übertragen.
Das spielt keine Rolle, Dein Ablauf ist sehr ungewöhnlich .

Für dich führst du deinen Thread aus und wartest mit get() darauf das der fertig ist.
Also ein SpaghettiCode al la Basic . Das ist aber eigentlich nicht im Sinne des Erfinders ..

Die Punkte , die du oben als "unrelevant" erachtest , sehe ich als sehr relevant -
Und genau da liegt der Unterschied :)

Json :
Um ein Json zu parsen , bzw zu lesen , solltest du auf alle Fälle ION benutzen.
Und auch hier wird dir bei der Verwendung klar , dass alle Bibliotheken IMMER mit einem Callback
arbeiten . Dein UI muss freilaufen

Du kannst nicht das Programm - nennen wir es mal "einfrieren" lassen , das geht so nicht :)
 
Zuletzt bearbeitet:
  • Danke
Reaktionen: Tatmotiv
Mir ist klar. Das das das das Gegenteil von best practice ist und total Spagetti. Aber ich war froh das gefunden zu haben. Und es funktioniert ja auch beim erstellen das widgets leider aber nicht beim drauf klicken (obwohl beides über die gleiche Funktion gesteuert wird: onUpdate().

Der Grund warum ich es tat, mein Tatmotiv also (höhö), ist, wenn ich versuche die Async-Klasse richtig zu verwenden, ich den den zum zeichnen benötigten appWidgetManager und Context nicht in die Async-Klasse befördert bekomme. Diese aber doch nötig ist um das widget (mit den neuen Daten) neu zu zeichnen.
 
Ok, wir kommen der Sache schon mal näher :)

Mir war schon ein wenig bewusst , dass du ein wenig Copy&Paste machst .
Leider ist das - nicht übel nehmen - ein wenig daneben gegangen :)

Mach mal was ganz einfaches :

Implementiere dir ION

Dependencies
Code:
 compile 'com.koushikdutta.ion:ion:2.+'

dann :
Code:
   Ion.with(mActivity).load(DeineWetterUrl).asJsonObject().setCallback(new FutureCallback<JsonObject>()
            {
                @Override
                public void onCompleted(Exception e, JsonObject result)
                {
                  //  Hier  parst  du dein Json und  machst dein WidgetCall
                }
            }

Und schon biste Glücklich :)
 
Zuletzt bearbeitet:
  • Danke
Reaktionen: Tatmotiv
swa00 schrieb:
Und schon biste Glücklich
Das wäre ja mal was neues mit Java. :D

Ok also Danke für den Hinweis mit ION, ich hab davon schon gelesen gehabt, aber nicht gewusst was es ist und wofür.

hab jetzt also ION mal im onUpdate() eingebaut:
Code:
Ion.with(context).load("wetterserver.../?json").asJsonObject().setCallback(new FutureCallback<JsonObject>(){
  @Override
  public void onCompleted(Exception e, JsonObject result)
  {
      //  HIer  parst  du dein Json und  machst dein WidgetCall
      String outputDataString = result.toString();
      String number = "x" + String.format("%03d", (new Random().nextInt(900) + 100)) + "x\n";
      views.setTextViewText(R.id.raw_widget_text, number + outputDataString);

      // Creating a pending intent, which will be invoked when the user clicks on the widget
      Intent refreshIntent = new Intent(context, RawDataWidget.class);
      refreshIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
      refreshIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
      PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, refreshIntent, PendingIntent.FLAG_UPDATE_CURRENT);
      views.setOnClickPendingIntent(R.id.raw_widget_frame, pendingIntent);

      // Instruct the widget manager to update the widget
      appWidgetManager.updateAppWidget(appWidgetId, views);
      updateAppWidget(context, appWidgetManager, appWidgetId);
  }
}

Dabei bleibt aber immernoch das Problem bestehen, dass innerhalb der (jetzt ION) Klasse context und appWidgetManager nicht bekannt sind. zumindest, meckert AndroidStudio innerhalb selbige nicht bekannt sind.
 
Ein Schritt nach dem Anderen

a) hast du dein Json bekommen ?
b) Ich kenne deine Initialisierung oben nicht , dort ermittelst du den context . Wie sieht denn dein Construktor aus ?
Wie hast du appWidgetManager initialisiert und wie deklariert ... ?
c) Du solltest die Zugriffe für deine TextViews innerhalb des Callbacks in einen runOnUiThread setzen


Einmal komplett-Code bitte


P:S und dann solltest du nicht so faul sein und nur einen String parsen, sondern schon ordentlich dein
JSonObject behandeln :)
Eine einzige Format-Änderung schon klatscht dir das Ganze auf den Bauch
 
Zuletzt bearbeitet:
swa00 schrieb:
a) hast du dein Json bekommen ?

Ja, auch über ION wird das JSON vom server geladen. Bei Test hab ich es einfach ins log geschrieben. Siehe Quelltext. Das komplette parsing ist mir grade egal, erstmal muss die Gundfunktion gehen. Was nicht heißt, das es nicht wichtig ist. Aber es nimmt einen sehr großen Teil meines Projektes ein und ist darum komplett ausgelagert.

swa00 schrieb:
b) Ich kenne deine Initialisierung oben nicht , dort ermittelst du den context . Wie sieht denn dein Construktor aus ?
Wie hast du appWidgetManager initialisiert und wie deklariert ... ?

Das alles wird der der Funktion onUpdate() automagisch mit übergeben und steht mir bei der widget-Entwicklung so zur Verfügung.

swa00 schrieb:
c) Du solltest die Zugriffe für deine TextViews innerhalb des Callbacks in einen runOnUiThread setzen

Ok. Das probiere ich gleich. Der jetzige Code ist noch ohne. Ich hab dafür alle context Informationen in memberVariablen kopiert um es wenigstens mal zu probieren. Ja ich weiß das das falsch ist, aber ich wusste es noch nicht besser.

swa00 schrieb:
Einmal komplett-Code bitte

Hier ist einmal komplett mein source file myWidget.java aber wieder ohne die imports aber sonst komplett.

Code:
/*
 * Implementation of App Widget functionality.
 */
public class RawDataWidget extends AppWidgetProvider {

    static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId)
    {
    }

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {

        // There may be multiple widgets active, so update all of them
        for (int appWidgetId : appWidgetIds) {

            // Get the layout for the App Widget
            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.raw_data_widget);


            final Context mContext = context;
            final AppWidgetManager mAppWidgetManager = appWidgetManager;
            final RemoteViews mViews = views;
            final int[] mAppWidgetIds = appWidgetIds;
            final int mAppWidgetId = appWidgetId;
            // download from web async
            Ion.with(context).load("<json-daten-url meines servers").asJsonObject().setCallback(new FutureCallback<JsonObject>(){
                @Override
                public void onCompleted(Exception e, JsonObject result)
                {
                    //  HIer  parst  du dein Json und  machst dein WidgetCall
                    String outputDataString = result.toString();
                    Log.i("myTAG", outputDataString );    -> Das funktioniert. Das json komt im logcat an.
                    
                    // Update the widget text
                    String number = "x" + String.format("%03d", (new Random().nextInt(900) + 100)) + "x\n";
                    mViews.setTextViewText(R.id.raw_widget_text, number + outputDataString);

                    // Creating a pending intent, which will be invoked when the user clicks on the widget
                    Intent refreshIntent = new Intent(mContext, RawDataWidget.class);
                    refreshIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
                    refreshIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, mAppWidgetIds);
                    PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, refreshIntent, PendingIntent.FLAG_UPDATE_CURRENT);
                    mViews.setOnClickPendingIntent(R.id.raw_widget_frame, pendingIntent);

                    // Instruct the widget manager to update the widget
                    mAppWidgetManager.updateAppWidget(mAppWidgetId, mViews);
                    //updateAppWidget(context, appWidgetManager, appWidgetId);
                }
            }
        }
    }
}

Damit funktioniert der download des json und dessen Anzeige im widget, allerdings nur beim plazieren des widgets auf dem homescreen aber nicht bei klicks auf das widget. Also genauso gut oder schlecht wie in meiner Ursprungsversion.
 
Zuletzt bearbeitet:
  • Danke
Reaktionen: Tatmotiv
Der von Dir vermutete runOnUIThread() kann leider nicht verwendet werden, da er nur für Activitys gedacht ist. Dagegen kann wohl auch mit handlern gearbeitet werden -> runOnUiThread method analog for widget? was für mich aktuell noch mehr Voodoo ist und es deshalb noch nicht hinbekomme.

swa00 schrieb:

Mit dem Konstrukt aus dem Post habe ich jetzt meine komlette widgetApp ersetzt, alle async (download) und Json teile rausgenommen und nur die random number Funktion von mir übernommen. Mit dem Resultat, das es nach wie vor bei Generierung des Widgets (also genau ein Mal) funktioniert. Bei jedem klick auf das Widget aber nichts passiert. Auch hab ich mal testweise auch die Toasts aus dem Beispiel verwendet, mit dem gleichen Resultat. Ich hab das gefühl mich im Kreis zu drehen. :-(

Hier mein akueller code diesmal plus xmls:

RawDataWidget.java:
Code:
public class RawDataWidget extends AppWidgetProvider {
    public static String ACTION_WIDGET_RECEIVER = "ActionReceiverWidget";
    public static int appid[];
    public static RemoteViews rview;
 
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        for (int appWidgetId : appWidgetIds) {
            updateWidgetState(context, ACTION_WIDGET_RECEIVER);
            Toast.makeText(context, "onUpdate()"+appWidgetId , Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onReceive(Context paramContext, Intent paramIntent)
    {
        String str = paramIntent.getAction();
        if (paramIntent.getAction().equals(ACTION_WIDGET_RECEIVER)) {
            updateWidgetState(paramContext, str);
        }
        else
        {
            if ("android.appwidget.action.APPWIDGET_DELETED".equals(str))
            {
                int i = paramIntent.getExtras().getInt("appWidgetId", 0);
                if (i == 0)
                  { }
                else
                {
                    int[] arrayOfInt = new int[1];
                    arrayOfInt[0] = i;
                    onDeleted(paramContext, arrayOfInt);
                }
            }
            super.onReceive(paramContext, paramIntent);
        }
    }

    static void updateWidgetState(Context paramContext, String paramString)
    {
        RemoteViews localRemoteViews = buildUpdate(paramContext, paramString);
        ComponentName localComponentName = new ComponentName(paramContext, RawDataWidget.class);
        AppWidgetManager.getInstance(paramContext).updateAppWidget(localComponentName, localRemoteViews);
    }

    private static RemoteViews buildUpdate(Context paramContext, String paramString)
    {
        //Toast.makeText(paramContext, "buildUpdate() ::"+paramString, Toast.LENGTH_SHORT).show();
        rview = new RemoteViews(paramContext.getPackageName(), R.layout.raw_data_widget);
        Intent active = new Intent(paramContext, RawDataWidget.class);
        active.setAction(ACTION_WIDGET_RECEIVER);
        active.putExtra("msg", "Message for Button 1");
        PendingIntent configPendingIntent = PendingIntent.getActivity(paramContext, 0, active, 0);
        rview.setOnClickPendingIntent(R.id.raw_widget_frame, configPendingIntent);
        if(paramString.equals(ACTION_WIDGET_RECEIVER))
        {
            //your code for update and what you want on button click
            String number = "x" + String.format("%03d", (new Random().nextInt(900) + 100)) + "x\n";
            rview.setTextViewText(R.id.raw_widget_text, number + "outputDataString");
            Toast.makeText(paramContext, "--- ::"+number, Toast.LENGTH_SHORT).show();
        }
        return rview;
    }
}

AndroidManifest.xml:
Code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.dataviewer">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".DataViewerApp">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name="layout.RawDataWidget">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                <action android:name="com.example.dataviewer.ACTION_WIDGET_RECEIVER"/>
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/raw_data_widget_info" />
        </receiver>
    </application>

</manifest>

raw_data_widget.xml
Code:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/raw_widget_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#09C"
    android:padding="@dimen/widget_margin">

    <TextView
        android:id="@+id/raw_widget_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:background="#09C"
        android:clickable="true"
        android:contentDescription="@string/appwidget_text"
        android:fontFamily="monospace"
        android:text="@string/appwidget_text"
        android:textAlignment="center"
        android:textAppearance="@android:style/TextAppearance.Widget.PopupMenu.Small"
        android:textSize="10sp"
        tools:text="widget lädt" />
</RelativeLayout>
 
Irgendwo hast du jetzt den Wurm drin.

Was macht denn ein leeres Widget bei dir , wenn du nur mal ein toast ausgibst ?
(Also wie du oben geschrieben hast - alles weg - keine grosse grafik - nix)

Einfach mal den ClickListener abfangen und einen Toast ausgeben ..
Mach dazu mal bitte ein neues Projekt - nicht dass du irgendwas eingebastelt hast , was ich hier nicht sehen
kann

Android (Home screen) Widgets - Tutorial
 
Habe jetzt komplett neu angefangen. Das Beispiel rein kopiert. Alle entsprechenden Namen angepasst. Leider wieder genau das gleiche. Beim aufspielen des APKs durch AndroidStudio erscheint der Toast, aber sonst weder beim click aufs Widget noch beim erzeugen des Widgets auf dem Homescreen (letzteres kann aber auch ein Spezielfall sein in dem keine Toasts angezeigt werden).
 
Oha ,
(na du bist schon ein Kandidat, aber wir kommen noch drauf :)

a) Was sagt denn der AS , wenn du das Device mit ADB / USB verbindest ?
b) Was sagt denn der Emulator ?

Gib mal keine Toasts raus , sondern nur Logs.


[doublepost=1499292097,1499290588][/doublepost]Also nur zur Info :
Ich habe jetzt mal eben schnell das Beispiel von oben ( Vogella) zusammgeschustert,
Das funktioniert wunderbar
[doublepost=1499292198][/doublepost] wd1.png wd2.png
[doublepost=1499292232][/doublepost]Die Zahlen ändern sich bei jedem Click auf das WIdget,
[doublepost=1499292288][/doublepost]Willste das Projekt haben ?
dann eben mal deine email per PN
 
Zuletzt bearbeitet:
  • Danke
Reaktionen: Tatmotiv
swa00 schrieb:
Oha ,
(na du bist schon ein Kandidat, aber wir kommen noch drauf :)

:D

swa00 schrieb:
Oha ,
a) Was sagt denn der AS , wenn du das Device mit ADB / USB verbindest ?

AS?

swa00 schrieb:
Oha ,
b) Was sagt denn der Emulator ?

Dazu musste ic herstmal neu bauen. Ich hab bisher immer auf Android 6 gebaut. Das Nexus Image hat nur Android5, darum hab ich die App nochmal in Android 4 (ICS) gebaut. Auf dem Emulator erscheint der Toast auch beim erstellen des Widgets. Aber auch hier keine Reaktion bei onClick.

swa00 schrieb:
Oha ,
Gib mal keine Toasts raus , sondern nur Logs.

Denke mal, das wird nichts ändern. Die Toasts funktionieren ja. Ich habe in den StackOverflow Problemen oft gelesen das die CodeTeile garnicht betreten werden. Hatte auch schon versucht mit dem Debugger und Breakpoints ran zu gehen. Ohne Erfolg.

swa00 schrieb:
Oha ,
deine Permissions hast du ja gesetzt , richtig ?
z.b.
<uses-permission android:name="android.permission.BIND_APPWIDGET" />

Keine Ahnung, was da gebaucht wird. Ich bin nur PHP Entwickler. /o\ :)
Aber schau mal bitte oben in meinen XML-Schnibseln da steht alles was ich habe. Wenn es da nicht steht, hab ich es wohl auch nicht.

Das Vogella Beispiel wollte ich morgen mal probieren. Ist jetzt zu spät. Aber wenn Du es mir mal gibts, probiere ich es gern live aus. PN folgt.

Danke
 
projekt
 

Anhänge

  • WidgetTest.rar
    1,3 MB · Aufrufe: 97
  • Danke
Reaktionen: Tatmotiv
Vielen Dank dafür. Das funktioniert. :-D
Aber (ich hoffe das klingt nicht unhöflich) das was die da machen, ist genau das gleiche wie es bei mir mit den Random Nummern auch schon lief. Hab ich wahrscheinlich unverständlich ausgedrückt in: [OFFEN] Onclick Datendownload aus dem Netz klappt nicht

Das Problem beginnt erst wenn der AsyncTask dazu kommt. Und selbst das abarbeiten des Tasks klappt (siehe dazu meine Hinweis mit den .get() ) aber wenn das Ergebniss des Task auf irgend eine Weise mit mit in das Widget wandern soll, funktioniert sofort kein klick mehr.

Als nächstes probiere ich mal ION in das bereit gestellte Beispiel einzubauen.

Also nochmal Danke und gute Nacht
TM
 
Auch die Einbindung des ION funktioniert so , wie oben erklärt ...

[ getestet ]


Code:
public class MyWidgetProvider extends AppWidgetProvider
{

    private static final String ACTION_CLICK = "ACTION_CLICK";
    private Context mContext;

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds)
    {
        mContext = context;

        final ComponentName           thisWidget = new ComponentName(context, MyWidgetProvider.class);
        final AppWidgetManager        mWidgetManager = appWidgetManager;
        final int[]               mAppWidgetIds = appWidgetIds;

        String urlcontent = "http://xxxxx";
        Ion.with(context).load(urlcontent).asJsonObject().setCallback(new FutureCallback<JsonObject>()
        {
            @Override
            public void onCompleted(Exception e, JsonObject result)
            {
               //  Hier  parst  du dein Json und  machst dein WidgetCall
                int[] allWidgetIds = mWidgetManager.getAppWidgetIds(thisWidget);
                for (int widgetId : allWidgetIds)
                {

                    RemoteViews remoteViews = new RemoteViews(mContext.getPackageName(), R.layout.widget_layout);
                    int number = (new Random().nextInt(100));
                    remoteViews.setTextViewText(R.id.update, String.format ("%d - %s",number,result.toString()));

                    Intent intent = new Intent(mContext, MyWidgetProvider.class);
                    intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
                    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, mAppWidgetIds);
                    PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext,0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
                    remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);
                    mWidgetManager.updateAppWidget(widgetId, remoteViews);
                }

            }
        });

    }
}
 
Zuletzt bearbeitet:
Zurück
Oben Unten