Im Allgemeinen müsste bei den Custom Roms immer eine Anleitung bei stehen, wie man das rauf bekommt.
Leider bietet CyanogenMod kein Rom für das S3mini, sonst hätte ich Dir das empfohlen.
Beiträge von Marco Feltmann
-
-
Naja, das bedeutet ja nur, dass Deinem einzelnen Fragment kein View zugeordnet ist.
Was tust Du denn in der onCreateView() Deines Fragmentes?
Ich hätte ja schon echt Bock Dir weiterzuhelfen, allerdings häng ich gerade an einem iOS Projekt, dessen Fertigstellungstermin immer näher rückt.
Deshalb kann (und will) ich Dir das Grundgerüst nicht mal eben zusammenzimmern…Kannst Du das irgendwie bei GitHub, GitLab, BitBucket oder ähnlichen Anbietern hochladen?
(Beziehungsweise die Frage, die eigentlich davor gekommen wäre: hast Du schon mal mit einem Source Code Management System wie Git gearbeitet?)Dann würde ich in meiner Pause mal rasch reinschauen.
-
Ja.
Sehen die Hersteller aber nicht so gern.Also lieber in den Laden, in dem Du das gekauft hast oder ein Laden von dem Anbieter, und dort bespielen lassen.
Ansonsten geht Dir die Garantie flöten. -
Was geht an fragmentManager.executePendingTransactions() denn nicht?
-
Mein Fehler, die gehört zum FragmentManager.
-
Ein gutes Beispiel für Content Provider:
http://www.vogella.com/tutorials/AndroidSQLite/article.htmlAlles Andere sind 'advanced topics'. Es dürfte schwierig werden, dazu passende Tutorials zu finden.
Kommt man selbst ziemlich zügig drauf, wenn man die Grundlagen beherrscht.
Wenn nicht, wird man auch die Tutorials nicht verstehen. -
Mein erster Versuch wäre herauszufinden, wie oft er versucht den mViewPager abzufragen.
Dazu alle Arbeiten am mViewPager in ein Konstrukt packen, das vorher prüft, ob mViewPager auch ja nicht null ist.Manuell warten musst Du da eigentlich nicht, da das alles nacheinander abgearbeitet wird.
Andererseits sagt die Dokumentation zur Commit–Methode:ZitatSchedules a commit of this transaction. The commit does not happen immediately; it will be scheduled as work on the main thread to be done the next time that thread is ready.
Du könntest also versuchen, via transaction.executePendingTransactions(); dafür zu sorgen, dass das Ganze sofort umgesetzt wird.
Ich bin aber nach wie vor der Meinung, dass ein Neuerstellen der Pager nach Auswahl eines Items der nicht so ganz korrekte Ansatz ist.
Das merkt man eigentlich immer dann, wenn etwas nicht so reibungslos funktioniert wie es sollte. -
Interessante Sichtweise. Nachdem ich Dir den Lösungsweg AsyncTask zeige kommt Dir die Idee, der Lösungsweg könnte der Strict Mode sein…
Du löst damit keine Sicherheitsprobleme aus, umgehst aber ein Konstrukt, dass Deine App daran hindert bei diversen Problemen* die Nutzerinteraktion zu verweigern.
Insofern: You're doin' it wrong!
*) Server antwortet nicht, keine Netzverbindung, Download dauert ewig…
-
Vermutlich wird der im Layout des Phones einfach nicht gefunden?
Frag doch einfach den Debugger, der beißt nicht.
-
Tja, sobald Du die ausgetretenen Pfade verlässt, wird es alles Andere als leicht.
Und offenbar hast Du von HTTP–Kommunikation noch weniger Ahnung als ich.
Man muss nicht studiert haben, um die gesamten Spezifikationen gemäß RFC 2616 zu verstehen – aber es würde vermutlich helfen. (Wo sonst lernt man das konzentrierte Durchlesen von 176 stinkend langweiligen irgendwas Abstraktes beschreibenden Seiten?)Kurzfassung: Dein Client schickt eine Anfrage mit Header, der Server schickt eine Antwort mit Header.
['Ungesicherten' Fall]
Anfrage: Schick Daten! <Request Header>
Antwort: OK! <Response Header> Daten…<Response Body>
(HTTP Status Code 200, vielleicht von gehört? Von 404 aber ganz bestimmt.)['Gesicherter' Fall]
Anfrage: Schick Daten! <Request Header>
Antwort: Basic Authentifizierung notwendig! <Response Header>
(HTTP Status Code 401)Anfrage: Schick Daten! Basic Authentifizierung: ABuiIOUuisncgQWiuHNfr7ZkOL12 <Request Header>
Antwort: Basic Authentifizierung notwendig! <Response Header>
(HTTP Status Code 401, da Authentifzierungsdaten da waren bedeutet es, dass sie dem Server nicht bekannt sind.)Anfrage: Schick Daten! Basic Authentifizierung: QWxhZGRpbjpvcGVuIHNlc2FtZQ== <Request Header>
Antwort: OK! <Response Header> Daten…<Response Body>Und genau das musst Du in Deiner App nachbauen.
Vielleicht kann Dir HttpClient da Arbeit abnehmen. -
Hast Du Gradle verstanden?
Weißt Du, was Gradle ist? -
Im Prinzip brauchst Du dafür einen kleinen Schmalspur-HTTP-Client.
Du sendest Dein HTTP Request, Du bekommst einen "401: Authorization required" Header als Response, musst an Hand der übertragenen Informationen dann die korrekte Authentifizierung zusammenstricken und eine entsprechend angepassten Request senden.
(Natürlich könntest Du das Ganze umgehen und gleich einen entsprechend angepassten Request senden. Halte ich aber für eine blöde Idee, fremde Server mit Informationen zu füttern, die er gar nicht haben will.)
Header Deines völlig fiktiven Beispiels:
Zitat von curl -I [url]http://tx.h2371843.stratoserver.net/download/telebook.txt[/url]
HTTP/1.1 401 Unauthorized
Date: Tue, 24 Feb 2015 15:05:21 GMT
Server: Apache
WWW-Authenticate: Basic realm="telexiom Download"
Last-Modified: Fri, 28 Nov 2014 14:16:16 GMT
ETag: "502-508ebe7692883"
Accept-Ranges: bytes
Content-Length: 1282
X-Powered-By: PleskLin
Content-Type: text/htmlDein nächster Request muss dann einen entsprechenden Authentification Header beinhalten:
ZitatAuthorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
(Davon ausgehend, dass Dein Username 'Aladdin' und das Kennwort 'open sesame' sind…)Ansonsten darfst Du Dich mit der RFC2045-MIME Implementierung von Base64 rumschlagen.
(Oben genannter Krams ist das verschlüsselte "Aladdin:open sesame") -
Die Fehlermeldung besagt, das irgendwas (vermutlich mViewPager) null ist.
Und null.setAdapter(mSectionsPagerAdapter) funktioniert* meines Wissens nur unter Objective-C.
Welches Layout auch immer er sich für das Phone zieht, ein View mit der ID R.id.pager dürfte er da schlicht nicht haben.
*) "funktioniert" im Sinne von: Programm läuft weiter statt eine Exception zu werfen. Das Resultat findet natürlich nicht statt und beim Versuch die Änderungen zu lesen bekommt man auch nix zurück.
-
android.os.NetworkOnMainThreadException sagt schon alles.
Dein Fehler ist, dass Du den Code auf Android >2 ausführst.
Um dort Netzwerkaktivität hin zu bekommen, musst Du das in den Hintergrund auslagern.Idealerweise nimmst Du hierfür einen AsyncTask.
Nähere Infos zu den Hintergründen findest Du im Guide zu Prozesse und Threads. -
Letzte Aktualisierung 7.3.15 hätte mich persönlich jetzt aber mehr verwundert.
-
Nö.
Das sollte ohne Google Analytics gehen. Die Verknüpfung bietet Dir nur einen Komfort, wenn Deine App Google Analytics benutzt – was sie hoffentlich nicht tut.
Bei mir hatte das mit den initialen Werten damals ungefähr drei Tage gedauert.
Keine Ahnung warum, hatte mich auch nicht sonderlich interessiert. -
Vielen Dank fürs Lesen
Gern!Für mich irgendwie irrelevant.
Einerseits haben wir nur ein Konto und andererseits gehe ich nie einkaufen. -
Na gut, dann hier.
Ich denke, Du unterschätzt die kleine Aufgabe.
1) Du arbeitest bei der Netzwerkkommunikation nicht mit Strings, sondern mit Binärdaten. (In Android waren das glaube ich Input– und Output Streams.) Sich da zu merken wo man bereits war ist mindestens schwierig, da TCP Kommunikation an sich relativ schwierig ist.
Die Pakete werden synchron erstellt, synchron verschickt und auch synchron an die App weitergeleitet, aber während des Versands können Asynchronitäten auftreten, wenn beispielsweise Paket 8 die Pakete 5-7 überholt und Paket 3 aus ungeklärter Ursache mitten drin verloren geht und noch einmal gesendet werden muss. Zwar kümmert sich die Netzwerkschnittstelle selbst darum, dass in Deiner App nur die Sachen landen, die zusammenhängend sortiert wurden, Annahmen über den tatsächlich verschickten Inhalt sind aber mindestens zufällig.Die Pfade ziehst Du am Bequemsten über das System, da Du eher keine Ahnung haben dürftest, wie sie angelegt sind.
Code// Holt Dir den Ordner für die Bilder File path = Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES); // Holt Dir den Unterordner 'Screenshots' File screenshotsDir = new File(path, "Screenshots");
Näheres in der Dokumentation:
https://developer.android.com/…irectory(java.lang.String)Rekursion ist dann halt so eine Sache.
- Zunächst mal musst Du prüfen, ob Du wirklich in einem Ordner bist. (isDirectory())
- Jetzt wäre es sinnvoll zu wissen, wie tief Du bereits in der Ordnerstruktur bist und ob Du aus Zeit– und Performancegründen nicht ab einer gewissen Tiefe abbrechen möchtest.
- Dann musst Du jede einzelne Datei, die Du hochladen willst, auslesen. Wenn jemand so deppert war ein TXT oder PDF da rein zu legen musst Du das natürlich ignorieren. (listFiles(FileFilter))
- Die Ordnerstruktur müsstest Du Dir intern dann auch noch vorhalten, damit Du nachher beim Upload alles so wiederherstellen kannst.
- Tja, und für jede einzelne Datei fängst Du dann wieder bei 1 an.
Damit kannst Du Dir halt eine Repräsentation des Verzeichnisbaums erstellen, welchen Du dann versuchst hochzuladen.
Gucken welchen Ordner du hast, Webserver sagen er soll den anlegen, gucken welche Dateien Du darin hast, alle Dateien dieser Ebene hochladen, (1) gucken welche Unterordner Du hast, Webserver sagen er soll die anlegen, gucken welche Dateien Du darin hast, alle Dateien dieser Ebene hochladen, weiter bei 1… - Zunächst mal musst Du prüfen, ob Du wirklich in einem Ordner bist. (isDirectory())
-
Wenn Dir Cinema4D zu teuer ist, kannst Du Dich gern mit Blender beschäftigen.
Hohe Lernkurve, brauchbare Ergebnisse. -
Der Client–Server–Ansatz hat nur einen gewissen Nachteil: Klartextkommunikation über das Netzwerk.
Gesetzt dem Fall, der Nutzer betrachtet Internet und Netzwerkkommunikation nicht als Neuland, so kann er einfach die Daten mitschneiden, analysieren und die korrekte Antwort herausfinden. Ergo: mogeln.(Denn seien wir mal realistisch: irgendwie muss aus den übertragenen Daten hervorgehen, welche Antwort die richtige Antwort ist. Eigener Wert 'correctAnswer', XML-Attribut 'isCorrect', irgend ein indizierendes Attribut, immer Antwort an Position 3, eindeutiges Prefix… Woher weiß Deine App sonst, welche Antwort stimmt?)
Ein Ansatz wäre, dass Du jeder Frage eine 'eindeutige' Identifikationsnummer per Zufall zukommen lässt. So eine Art interne TAN–Liste, die der Server vor dem Ausliefern abstreicht…
(Keine Ahnung, ob ihr im Zeitalter von mobileTAN und ChipTAN die alten Listen überhaupt noch kennt… Eine Liste, 99 Zahlen mit je 6 Stellen, wovon immer eine benutze abgestrichen wird.)Der Server hat dann eine generelle TAN Liste mit sagen wir 90 Einträgen. Diese dient lediglich dem Verschleiern, damit jede Antwort eine ID/TAN hat.
Sowohl der Server als auch die App haben eine 'gültige Antwort' TAN Liste mit in dem Fall 30 Einträgen.Wenn der Server eine Frage ausliefert markiert er die Antworten mit Einträgen aus den TAN Listen: den korrekten Eintrag mit den Einträgen aus der 'gültige Antworten' Liste, die anderen zur Verschleierung mit einer TAN aus der generellen TAN Liste.
Wenn die App dann den Feed vom Server bekommt, gleicht sie jede ID mit ihrer internen 'gültige Antwort' TAN Liste ab um herauszufinden, welche Antwort stimmt.Aus den übertragenen Daten kann man selbst dann nicht mehr ersehen, welche Antwort stimmt, die App hingegen kann es aber doch.
(Es wäre natürlich sinnvoll, die Liste nicht im Klartext auf der SD Karte des Geräts abzulegen…)Mal zum Vergleich ein einfaches und ein verschleiertes JSON:
Code
Alles anzeigen{ "Frage":"War dieser Beitrag hilfreich?" "Antworten": ( { "istKorrekt":false "Text":"Ging so" }, { "istKorrekt":false "Text":"Hatte mehr erwartet" }, { "istKorrekt":true "Text":"Du bist der Größte!!!" }, { "istKorrekt":false "Text":"War einigermaßen brauchbar" } ) }
Code
Alles anzeigen{ "Frage":"War dieser Beitrag hilfreich?" "Antworten": ( { "id":12384 "Text":"Ging so" }, { "id":28364 "Text":"Hatte mehr erwartet" }, { "id":30472 "Text":"Du bist der Größte!!!" }, { "id":49821 "Text":"War einigermaßen brauchbar" } ) }
Wo erkennt man auf den ersten Blick, welche Antwort ich erwarte, und wo ist es weniger offensichtlich?
Auf dem Wege ließe sich beispielsweise auch Multiple Choice realisieren, weil Du an Hand der Antwort–IDs ja sehen kannst, wie viele gültig sind.