Monodroid - Erste Schritte und ein Sprung

Da ich seid neustem auch ein tolles Smartphone (Samsung Galaxy S Plus) besitze, musste ich doch mal schauen was man tolles damit anstellen kann. Da ich nicht mit Java als Sprache anfangen wollte gab es nur eine Alternative: Monodroid!

Monodroid ist Mono auf Android portiert. Die mitgelieferte IDE MonoDevelop macht einem das Entwickeln wirklich leicht. Durch Verknüpfung mit dem Android SDK lassen sich in MonoDroid Emulatoren und Geräte laden, zur Laufzeit debuggen und natürlich Applikationspakete (*.apk) erstellen.

Da ich weiterhin auf meinem Netbook entwickle hatte ich Probleme die Emulatoren zum laufen zu bringen. Da die Trial-Version von MonoDroid aber nur diese Emulatoren unterstützt habe ich schlichtweg die gecrackte Version verwendet. Das hat den Vorteil dass ich das APK-Dateien erstellen kann, wer also ebenfalls ein Android Phone besitzt kann dieses heute entwickelte Programm ebenfalls nutzen.

Nachdem das Hello-World-Programm lief wagte ich mich an die Erweiterung des Programms, bis schließlich ein 9Gag-Picture-Dumper entstanden war:

Das Programm ließt die Website 9Gag Mobile Website aus und holt sich so viele weitere Seiten des 9Gag-Portals wie angegeben (Im Bild die Zahl 3). Aus diesen Seiten werden die Bilder per Regex geparsed und schließlich nacheinander auf die Interne SD-Karte geladen. Zwar gibt es 9Gag Viewer, diese können aber nur die Bilder anzeigen und nicht herrunterladen. Da ich die Bilder aber gerne ohne Internetverbindung anschaue war so ein Dumper das perfekte Projekt.

Das meiste läuft über die Klasse NineGag.cs. Hier werden die Seiten geladen und in einer Liste gespeichert, anschließend die Bilder rausgesucht und runtergeladen. Da sich das ganze in einem überschaubaren Rahmen abspielt hier die Klasse abgedruckt:

public class NineGag
	{
		String CurrentPage;
		System.Net.WebClient WC;
 
		List lstPages;
 
		private Activity1 Activity;
 
		public NineGag(Activity1 Ins)
		{
			lstPages = new List();
 
			WC = new System.Net.WebClient();
			CurrentPage = "";
 
			this.Activity = Ins;
		}
 
		private void UpdateProgress(String Message)
		{
			Activity.RunOnUiThread (() => Activity.FindViewById(Resource.Id.lblProgress).Text = Message);
 
		}
 
		private void UpdateImage (String Path)
		{
			Activity.RunOnUiThread (() => { 
				Activity.FindViewById(Resource.Id.imgPreview).SetImageBitmap(Android.Graphics.BitmapFactory.DecodeFile(Path));
			});
		}
 
		public bool LoadPages (Int32 Amount)
		{
			String NextPage = "http://m.9gag.com";
 
			for (int i = 0; i < Amount; i++) 
			{
				NextPage = LoadPage(NextPage);
 
				UpdateProgress("Download Page: " + i.ToString ());
			}
 
			return true;
		}
 
		private String LoadPage(String URL)
		{
			CurrentPage = WC.DownloadString(URL);
			this.lstPages.Add(CurrentPage);
 
			return "http://m.9gag.com" + new System.Text.RegularExpressions.Regex("(?:href=\")(/hot/id/\\d*)", System.Text.RegularExpressions.RegexOptions.None).Match (CurrentPage).Groups[1].Value;
		}
 
		public List FilterOutImages ()
		{
			List lstReturn = new List ();
 
			System.Text.RegularExpressions.Regex Ex = new System.Text.RegularExpressions.Regex (@"http://.*\b/photo/\b.*.jpg");
			for (int j = 0; j < this.lstPages.Count; j++) {
				System.Text.RegularExpressions.MatchCollection Collection = Ex.Matches (this.lstPages[j]);
 
				for (int i = 0; i < Collection.Count; i++) {
					lstReturn.Add (Collection [i].Value);
				}
			}
 
			return lstReturn;
		}
 
		public List DownloadAndSaveFiles (List Images)
		{
			String OutputDir = Android.OS.Environment.ExternalStorageDirectory + "/NineGAG";
			String CurrentFilename = "";
			List lstReturn = new List();
 
			if (!System.IO.Directory.Exists(OutputDir))
				System.IO.Directory.CreateDirectory(OutputDir);
 
			int iCounter = 0x00;
 
			foreach (var Image in Images) 
			{
				iCounter ++;
				UpdateProgress(String.Format("Download Image: {0}/{1}", iCounter, Images.Count));
				UpdateProgessBar(Images.Count, iCounter);
 
				CurrentFilename = OutputDir + "/" + System.IO.Path.GetFileName(Image);
 
				if (System.IO.File.Exists(CurrentFilename))
					System.IO.File.Delete(CurrentFilename);
 
				WC.DownloadFile(Image, CurrentFilename);
				UpdateImage(CurrentFilename);
 
				lstReturn.Add(CurrentFilename);
			}
 
			return lstReturn;
		}
	}

Eine Activity ist wie eine Windows-Form zu verstehen, um Zugriff auf die UI zu haben muss eine Instanz der Activity übergeben werden. Die Activity stellt auch eine Funktion namens “RunOnUIThread” bereit, damit kann einfach auf den UI-Thread zugegriffen werden um Bilder zu laden und Texte zu aktualisieren. Richtig cool, oder?

Leider kann man nicht direkt über die Activity auf Controls zugreifen, diese Logik ist streng voneinander getrennt. Daher muss man jeweils FindViewByID<T>(Ressource.Id.DEINEID) verwenden, man gewöhnt sich aber dran. Sonst ist alles genau wie im .NET Framework!

Leider ist die finale Datei ziemlich groß, da jeweils das Mono Framework mitgeliefert wird. Gespeichert werden die Bilder im Ordner /sdcard/NineGAG, die Bildernamen sind wie auf der Website, kam noch nicht zum rausparsen des Titles eines Bilds. Ein “Bug” ist, dass die App abbricht die UI zu aktualisieren sobald man das Gerät in den Landscape-Modus bringt, also damit ein bisschen aufpassen ;-)

Das komplette Projekt gibts natürlich zum Download, ich würde mich freuen wenn jemand mal die fertige App ausprobieren würde. Dazu müsst ihr zunächst die Installation von Apps, die nicht aus dem PlayStore stammen erlauben ;-)

Download der App: NineGagDumper.apk (130)

Download des Sources: Source des 9Gag Dumpers (166)

Greez Easy

9 people like this post.
    • li0nsar3c00l
    • 30. Sep. 2012 9:46pm

    wusste nicht, dass man so einfach apk erstellen kann. werd mich damit mal beschäftigen
    btw im app store nach infinity gag oder 9gag suchen hätte dir ein bisschen arbeit abgenommen :’D

  1. Hey wirklich coole Sache und sieht super einfach aus. Wieder einmal C# FTW :D

    • streppel
    • 4. Okt. 2012 12:50pm

    Entwickel momentan auch eine App mittels Mono(iOS und Android) und kann es wirklich nur empfehlen. Zwar wäre das ganze auch via Objective-C oder Java möglich, die vorteile die C# hat haben mich aber zum Kauf bewogen, und es hat sich bisher gelohnt.

    Weiter so mit dem Blog, gefällt mir echt super :)

    • short
    • 2. Jan. 2013 3:51am

    Moin, hast du zufällig mal einen Link für Monodroid?
    Wäre nett.

    mfg

      • Easysurfer
      • 6. Jan. 2013 4:32pm

      Nur als Torrent: thepiratebay.se/torrent/7658056/Mono_for_Android_4.2.6_Windows_Crack
      Viel Erfolg!

  1. Noch keine TrackBacks.


− 5 = vier