Nexus 10: Bild von URL herunterladen + anzeigen

  • Antworten:25
  • OffenNicht stickyNicht beantwortet
  • Forum-Beiträge: 141

23.03.2013 02:05:56 via Website

Hallo zusammen.

Wie im Betreff erwähnt möchte ich gerne in der App die ich für mein Nexus 10 schreibe ein Bild aus dem Internet herunterladen und dieses in einer activity die über einen Button aktiviert wird anzeigen.

Ich habe mich durch sämtliche Beispiele im Internet gewühlt aber keines davon wollte mir ein Bildchen anzeigen.
Ein Bild aus dem res/drawable Ordner anzuzeigen ist kein Problem.

Was meine App bisher fertig bringt:
- Nach AP scannen, alle Informationen aus dem empfangenen Broadcast auflisten.
- Auf einen AP connecten.
- Wechsel des AP per Auswahl von einer Liste
- Netzwerkinfo's zu allen gespeicherten Netzwerken anzeigen

Kann mir jemand bitte (ich weiß es klingt faul...) ein Codeschnippsel an den Kopf werfen der funktioniert?
Ich komm mir nämlich so langsam echt zu dumm vor und die Motivation sinkt ins unermesslich Tiefe :(

Ich hoffe ihr könnt mir hier weiterhelfen :)
Danke mal im Vorraus.
  • Forum-Beiträge: 1.793

23.03.2013 08:36:05 via App

Wo ist denn dein Problem? Was funktioniert nicht?

Generell würde ich das so machen: Download der Datei auf die SD-Karte, dann über das ImageView von der SD-Karte lesen.

Hier noch, wie man ein Bild von der SD-Karte ins ImageView bringt: http://stackoverflow.com/questions/4181774/show-image-view-from-file-path-in-android

Hier noch ein deutsches Tut, wie man eine Datei herunterlädt. Allerdings würde ich die Methoden onPostExecute und onPreExecute leer lassen.
http://graetzer.org/index.php/2011/07/android-httpclient-download-einer-datei-mit-notification/

Gruß und viel Erfolg
PS: wofür steht AP?

Liebe Grüße impjor.

Für ein gutes Miteinander: Unsere Regeln
Apps für jeden Einsatzzweck
Stellt eure App vor!

Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 9.201

23.03.2013 12:58:46 via Website

1Uri uri = Uri.parse("file:///data/data/project/file.jpg");
2image.setImageURI(uri);

Ich habe den Code nicht getestet.
Villeicht ist das noch hilfreich:
http://stackoverflow.com/questions/2471935/how-to-load-an-imageview-by-url-in-android

http://stackoverflow.com/questions/3657587/android-how-to-download-an-image-and-use-it-as-new-resource

LG Pascal //It's not a bug, it's a feature. :) ;)

  • Forum-Beiträge: 141

24.03.2013 06:51:32 via Website

Danke schonmal für die Antworten. Werde die Links durchchecken sobald ich Montag auf der Arbeit bin. Das Tablet liegt dort eingeschlossen in nem Schrank ;)

AP steht für Access Point. In dem Falle nen Router .
  • Forum-Beiträge: 141

25.03.2013 23:53:21 via Website

Habe heute den ganzen Tag versucht das hinzubekommen, bin wieder gescheitert. Hier mal ein Beispiel, welches mir keinen Fehler ausspuckt aber einfach auch kein Bild auf den Bildschirm wirft. Hierzu der code. Vielleicht kann mir ja jemand von euch sagen wo bei diesem Beispiel der Fehler liegt. Mir wird jedenfalls kein Bild angezeigt :(

In der MainActivity wird das ganze aufgerufen über nen Button:
1if(v==downloadDisplayMap){
2 Intent displayMap = new Intent(MainActivity.this, ImageFromUrlExample.class);
3 startActivity(displayMap);
4 }

So sieht meine Manifest xml aus:
1<?xml version="1.0" encoding="utf-8"?>
2<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3 package="com.example.broadcast"
4 android:versionCode="1"
5 android:versionName="1.0" >
6
7 <uses-sdk
8 android:minSdkVersion="15"
9 android:targetSdkVersion="17" />
10 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
11 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
12 <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
13 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
14
15
16 <application
17 android:allowBackup="true"
18 android:icon="@drawable/ic_launcher"
19 android:label="@string/app_name"
20 android:theme="@style/AppTheme" >
21 <activity
22 android:name="com.example.broadcast.MainActivity"
23 android:label="@string/app_name" >
24 <intent-filter>
25 <action android:name="android.intent.action.MAIN" />
26
27 <category android:name="android.intent.category.LAUNCHER" />
28 </intent-filter>
29 </activity>
30 <activity android:name=".ImageFromUrlExample"></activity>
31 </application>
32
33</manifest>

Und hier haben wir den Code der nicht macht was ich will:
1public class ImageFromUrlExample extends Activity {
2@Override
3public void onCreate(Bundle savedInstanceState) {
4 super.onCreate(savedInstanceState);
5 setContentView(R.layout.download);
6 ImageView imgView =(ImageView)findViewById(R.id.ImageView01);
7 Log.d("", "Rufe Load Image auf");
8 Drawable drawable = LoadImageFromWebOperations("http://www.androidpeople.com/wp-content/uploads/2010/03/android.png");
9 imgView.setImageDrawable(drawable);
10}
11
12private Drawable LoadImageFromWebOperations(String url)
13{
14 try{
15 Log.d("", "Image URL: "+ url);
16 InputStream is = (InputStream) new URL(url).getContent();
17 Drawable d = Drawable.createFromStream(is, "src name");
18 return d;
19 }catch (Exception e) {
20 System.out.println("Exc="+e);
21 return null;
22 }
23}
24}
  • Forum-Beiträge: 2.545

26.03.2013 09:32:41 via Website

Was sagt dein Logcat?

Wahrscheinlich, das du a) keine Internet-Permission hast und b) "Network in MainThread" betreibst.
  • Forum-Beiträge: 33

26.03.2013 11:47:29 via Website

Oder einfach mit einer WebView.

1WebView webView = (WebView) findViewById(R.id.mywebview);
2webView.setInitialScale(getScale());
3webView.getSettings().setBuiltInZoomControls(true);
4webView.getSettings().setLoadWithOverviewMode(true);
5webView.getSettings().setUseWideViewPort(true);
6webView.getSettings().setSupportZoom(true);
7webView.loadUrl("<URL zum Bild>");

Damit hast du sogar gleich Zoomfunktionalitäten. :)

Beste Grüße,
knucKles
  • Forum-Beiträge: 141

26.03.2013 16:31:35 via Website

Die Internet permission waren ursprünglich drin. Mir hats nur warum auch immer das Manifeste zerschossen gehabt. Hab ich wohl vor dem Posten vergessen hinzuzufügen. Hier der LogCat auszug ab dem Punkt bevor ich auf den Button klicke der mir das Image holen soll:

103-26 08:28:13.749: I/GTalkService/c(719): [GTalkConnection@1117032272] connect: acct=1, state=CONNECTING
203-26 08:28:23.255: I/ActivityManager(394): START u0 {cmp=com.example.broadcast/.ImageFromUrlExample} from pid 2281
303-26 08:28:23.310: D/dalvikvm(394): GC_FOR_ALLOC freed 931K, 16% free 18286K/21608K, paused 40ms, total 41ms
403-26 08:28:23.350: D/(2281): Rufe Load Image auf
503-26 08:28:23.350: D/(2281): Image URL: http://www.androidpeople.com/wp-content/uploads/2010/03/android.png
603-26 08:28:23.355: I/System.out(2281): Exc=android.os.NetworkOnMainThreadException
703-26 08:28:23.385: D/mali_winsys(2281): new_window_surface returns 0x3000
803-26 08:28:23.440: I/ActivityManager(394): Displayed com.example.broadcast/.ImageFromUrlExample: +122ms

@knuckles: werds gleich mal ausprobieren :)
  • Forum-Beiträge: 141

26.03.2013 16:43:38 via Website

knuckles: Deins funktioniert :) Danke dafür, das ist wahrscheinlich das unkomplizierteste und werd ich so verwenden.

Trotzdem würds mich interessiern wieso das "alte" nicht geht...
Was genau hattest du denn mit "Netzwerk in Main betreiben" gemeint?

— geändert am 26.03.2013 16:49:13

  • Forum-Beiträge: 2.545

26.03.2013 18:36:12 via Website

I/System.out(2281): Exc=android.os.NetworkOnMainThreadException

Siehste.


Was genau hattest du denn mit "Netzwerk in Main betreiben" gemeint?

Das man Netzwerk-Aktivitäten seit geraumer Zeit nicht mehr im MainThread (oder auch UI-Thread) durchführen darf, d.h. man muss sie in einem eigenen Thread laufen lassen; ein hilfreiches Werkzeug wäre etwa AsyncTask.

— geändert am 26.03.2013 18:39:09

  • Forum-Beiträge: 141

26.03.2013 19:03:19 via Website

Das bedeutet dann auch, dass ich solche Dinge wie zu einem Wlan Netzwerk connecten in einen AsyncTasks packen muss?
Weil diese Funktionen tut meine App nach wie vor und LogCat bringt mir keine Meldung diesbezüglich.

— geändert am 26.03.2013 19:03:34

  • Forum-Beiträge: 2.545

26.03.2013 19:21:37 via Website

Wenn du keine Meldung erhältst, dann bedeutet es das offensichtlich nicht ;-)

Bei der Änderung ging es Google darum, das die Oberfläche benutzbar bleibt, auch wenn eine App mal eben ein paar MB aus dem Internet herunterlädt.
"connecten zu einem WLAN" wird wohl nicht als zeitaufwändig eingestuft, wenn du keine Meldung bekommst.
  • Forum-Beiträge: 1.525

26.03.2013 19:24:34 via Website

Wenn es um runterladen von Daten geht oder sachen die länger dauern im Hintergrund, solltest oder musst du das in einen extra Thread packen.

Also AsyncTask.


LG
  • Forum-Beiträge: 141

26.03.2013 19:51:54 via Website

Im Prinzip wäre es für mich sinnvoller die Datei greifbar zu haben / sprich runterzuladen.
Es gibt ja ein paar Beispiele dafür im Netz, aber alle speichern auf die SD-Karte.
Dann hab ich mir gedacht ich ersetze den Pfad Environment.getExternalStorageState() eben durch die Sache mit dem "Context". Was aber auch nicht klappen wollte.

Hat jemand von euch schonmal ein File in den internen speicher heruntergeladen?

— geändert am 26.03.2013 19:52:14

  • Forum-Beiträge: 141

26.03.2013 20:12:37 via Website

Oh Wunder, ich habe es geschafft ein Beispiel im Internet so umzumodeln, dass es mit dem Download funktioniert.

Das Problem ist so lächerlich, dass ihr mich sicher für dähmlich halten werdet :grin:
Ich hatte zwar eine Verbindung zum Router, jedoch kein Internet Access weil das erst per MAC Adresse freigegeben werden musste.
Laptop hatte, aber Tablet nicht. Grml......2 Tage ärger wegen sowas :(

Allerdings habe ich den Pfad "manuell" eingetragen.
1OutputStream output = new FileOutputStream("/data/data/com.example.broadcast/Map.jpg");

Und wieder manuell nach dem Bild gesucht:
1String imagePath = "/data/data/com.example.broadcast/Map.jpg";


Aber immerhin klappt das mit dem herunterladen...
Kann ich dieses Verzeichnis irgendwie einsehen/Daten löschen damit ich mein Tablet nicht unnötig zumülle während ich hier am rumtesten mit downloads bin?
  • Forum-Beiträge: 2.545

26.03.2013 20:33:16 via Website

Kann ich dieses Verzeichnis irgendwie einsehen

So wäre es "richtig", auch für User mit "älteren" Geräten mit wenig internem Speicher geeignet:

String path = Environment.getExternalStorageDirectory().toString()+"/Android/data/"+getPackageName()+"/files/";
File f = new File(path);
f.mkdirs();

Den Ordner kannst du einsehen, und die Dateien darin werden bei der Deinstallation deiner App vom System automatisch ebenfalls entsorgt.
  • Forum-Beiträge: 141

26.03.2013 21:47:44 via Website

Bekomme von LogCat folgenden Error:

103-26 13:36:05.335: E/Error:(3018): /storage/emulated/0/Android/data/com.example.broadcast/files: open failed: ENOENT (No such file or directory)
203-26 13:36:05.335: E/BitmapFactory(3018): Unable to decode stream: java.io.FileNotFoundException: /storage/emulated/0/Android/data/com.example.broadcast/files/map.jpg: open failed: ENOENT (No such file or directory)
map.mkdirs() gibt mir false zurück ... O.o

Muss ich noch irgendwelche permissions angeben damit das funktioniert?
Ich hoffe ich hab keinen Bockmist in meinem Code gebaut. Zur Sicherheit hier nochmal den Code aus dem Asynctask:

1protected String doInBackground(String... f_url) {
2 int count;
3 try {
4 URL url = new URL(f_url[0]);
5 URLConnection conection = url.openConnection();
6 conection.connect();
7
8 InputStream input = new BufferedInputStream(url.openStream(), 8192);
9
10 // Output stream ALT
11 // OutputStream output = new FileOutputStream("/data/data/com.example.broadcast/Map.jpg");
12
13 String path = Environment.getExternalStorageDirectory().toString()+"/Android/data/"+getPackageName()+"/files/";
14 File map = new File(path);
15 map.mkdirs();
16
17 OutputStream output = new FileOutputStream(map);
18 byte data[] = new byte[1024];
19
20 while ((count = input.read(data)) != -1) {
21 output.write(data, 0, count);
22 }
23
24 output.flush();
25 output.close();
26 input.close();
27
28 } catch (Exception e) {
29 Log.e("Error: ", e.getMessage());
30 }
31
32 return null;
33 }

— geändert am 26.03.2013 22:12:03

  • Forum-Beiträge: 2.545

26.03.2013 22:56:14 via Website

Muss ich noch irgendwelche permissions angeben damit das funktioniert?

Natürlich diese hier:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

und um ganz up to date zu sein, kannst dudie hier auch gleich noch ergänzen:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />


Ich hoffe ich hab keinen Bockmist in meinem Code gebaut.
Naja...
zwischen dem mkdirs(), mit dem du den Pfad als Serie von Ordnern anlegst, und dem "new FileOutputStream(map);" scheint mir noch irgendwo die Ergänzung eines Dateinamens zu fehlen ;-)
  • Forum-Beiträge: 141

26.03.2013 23:17:50 via Website

/Edit: Meinst du das hier?

1File map = new File(path, "map");

Das file wird angezeigt, allerdings finde ich es nicht in den Ordnern

— geändert am 26.03.2013 23:27:52