Java’da XML dosyası oluşturmam gerektiğinde bulduğum kodu, başkalarının da işine yarar umuduyla buraya da yazayım.
Amaç şu aşağıdaki formatta bir XML dosyası oluşturmak:
<sirket> <calisan id="1"> <ad>İsim</ad> <soyAd>SOYİSİM</soyAd> <maas>1000</maas> </calisan> <calisan id="2"> <ad>İsim2</ad> <soyAd>SOYİSİM2</soyAd> <maas>1000</maas> </calisan> </sirket>
Kodun orijinali üzerinde fazla değişiklik yapmadan aşağıdaki haliyle inceleyelim:
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class CreateXML {
public static void main(String[] args) {
try {
/**
* Kodun kaynağı:
* http://www.mkyong.com/java/how-to-create-xml-file-in-java-dom/
*/
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
/** Şirket */
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement("sirket");
doc.appendChild(rootElement);
/** Çalışan */
Element staff = doc.createElement("calisan");
rootElement.appendChild(staff);
/** Çalışana id özelliği atama */
Attr attr = doc.createAttribute("id");
attr.setValue("1");
staff.setAttributeNode(attr);
/** Şöyle bir de kısayolu var */
// staff.setAttribute("id", "1");
/** Ad */
Element firstname = doc.createElement("ad");
firstname.appendChild(doc.createTextNode("İsim"));
staff.appendChild(firstname);
/** Soyad */
Element lastname = doc.createElement("soyAd");
lastname.appendChild(doc.createTextNode("SOYİSİM"));
staff.appendChild(lastname);
/** Maaş */
Element salary = doc.createElement("maas");
salary.appendChild(doc.createTextNode("1000"));
staff.appendChild(salary);
/** İçeriğin bir XML dosyasına yazılması */
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("file.xml"));
transformer.transform(source, result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Eğer hatasız çalışırsa proje klasörü içinde “file.xml” adında bir dosya oluşacaktır. İçeriği de aşağıdaki gibi:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <sirket> <calisan id="1"> <ad>İsim</ad> <soyAd>SOYİSİM</soyAd> <maas>1000</maas> </calisan> </sirket>
Fazla açıklama da yazmadık ama adamlar zaten güzel yazmışlar, açıklama yazmaya pek gerek kalmamış.
Kaynak: mkyong.com
Üzerinde çalıştığım bir Android projesinde EditText alanına girilen e-mail değerinin gerçekten de bir e-mail adresi mi olduğunun kontrol edilmesi gerekiyordu. Bunun için aşağıdaki kodu bulup kullandım.
boolean isEmailValid(String email) {
String expression = "^[\\w\\-]([\\.\\w])+[\\w]+@([\\w\\-]+\\.)+[A-Z]{2,4}$";
CharSequence inputStr = email;
Pattern pattern = Pattern.compile(expression, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(inputStr);
return matcher.matches();
}
Girilen tüm değerleri doğru test ediyor mu bilemem ama benim işimi görecek kadar iyi çalışıyor. Aşağıdaki kod bloğu ile test ettiğimde;
ArrayList<String> addresses = new ArrayList<String>();
addresses.add(" ");
addresses.add("test");
addresses.add("test.com");
addresses.add("test@com");
addresses.add("test@test.com");
addresses.add("test@test.com.");
addresses.add("test@test.com.tr");
addresses.add("test.test@test.com.tr");
addresses.add("test@türkçe.karakter.tr");
for (int i = 0; i < addresses.size(); i++) {
System.out.println(addresses.get(i) + " :: "
+ isEmailValid(addresses.get(i)));
}
şu aşağıdaki çıktıyı verdi:
:: false
test :: false
test.com :: false
test@com :: false
test@test.com :: true
test@test.com. :: false
test@test.com.tr :: true
test.test@test.com.tr :: true
test@türkçe.karakter.tr :: false
Yeniden anlamış olduk ki regular expressions hayat kurtarır :)
Kaynak: zparacha.com
İlki bir önceki yazım olan ve yalnızca 2 yazıdan oluşan muhteşem yazı dizime (Eclipse & Android SDK kullanırken karşılaştığım hatalar) kaldığım yerden devam ediyorum. Bu sefer uygulamayı cihaz üzerinde çalıştırmak istediğimde aldığım hata ve google amcanın yardımıyla kavuştuğum çözümden bahsedeceğim. Hata aşağıdaki gibi:
Android Launch!
adb is running normally.
Performing com.test.Splash activity launch
Uploading Test.apk onto device 'HT9A4LV01328'
Failed to install Test.apk on device 'HT9A4LV01328': timeout
Launch canceled!
ADB çalışıyor, upload tamam ama uygulama yüklenemeden timeout’a düşüyor. Çözüm için de Eclipse -> Preferences -> Android -> DDMS -> ADB connection time out (ms) yolunu izliyoruz ve orda default 5.000 olarak gelen değeri biraz artırıyoruz. (misal 10.000, yetmezse 15.000 vs)

Yeniden denediğimizde Console çıktısını aşağıdaki gibi görüyorsak olay tamamdır.
Android Launch!
adb is running normally.
Performing com.test.Splash activity launch
Uploading Test.apk onto device 'HT9A4LV01328'
Installing Test.apk...
Success!
Starting activity com.test.Splash on device HT9A4LV01328
Android SDK ve Eclipse ADT Plugin’ini güncelledikten sonra daha önce yaratmış olduğum AVD’lerden bir tanesini çalıştırmak istediğimde aşağıdaki gibi bir hata aldım.
invalid command-line parameter: Files.
Hint: use '@foo' to launch a virtual device named 'foo'.
please use -help for more information

Google amcaya sordum “n’oluyoruz la?” diye, aynı problemle karşılaşmış insanlar gösterdi bana. Meğerse güncellemeden sonra Eclipse artizlik yapıp Windows’un boşluk, parantez vs karakterleri içeren dosya yollarını beğenmiyormuş. O güne kadar sorunsuz çalışan kısım, yani Eclipse -> Window -> Preferences -> Android -> SDK Location kısmında yazılı olan
C:\Program Files (x86)\Android\android-sdk
artık çalışmayacakmış.

“E çözüm neymiş peki?” diye baktığımda da o yolu şu aşağıdakilerden biri ile değiştirmek olduğunu öğrendim.
C:\PROGRA~1\Android\android-sdk
C:\PROGRA~2\Android\android-sdk
İlki şuna;
C:\Program Files\Android\android-sdk
ikincisi de şuna;
C:\Program Files (x86)\Android\android-sdk
ilaçmış. İlgililere duyrulur.
Java’da List, ArrayList, Set vb Collections framework yapıları ve bunların metodları (add, remove, sort vb) sağladığı kolaylıklar sebebiyle bolca kullanır. Örneğin bir ArrayList içinde String ya da Integer tipinde nesneler varsa ve bunları sıralamamız gerekiyorsa Collections.sort(liste_ismi); şeklinde bir kullanımla listeyi sıralı hale getirebiliriz. Buna küçük bir örnek verelim. Aşağıdaki kod parçası bir ArrayList oluşturup içine 5 tane String tipinde eleman ekliyor, elemanları sıra ile konsola yazdırıyor, sıralıyor ve son olarak sıralı listeyi konsola yazdırıyor.
import java.util.ArrayList;
import java.util.Collections;
public class ObjectSort {
/**
* @author Oguz
*/
public static void main(String[] args) {
ArrayList mList = new ArrayList();
mList.add("Black Sabbath");
mList.add("Judas Priest");
mList.add("Jimi Hendrix");
mList.add("Dire Straits");
mList.add("Pink Floyd");
// Sıralanmamış listeyi yazdırıyoruz:
System.out.println("Sıralanmamış dizi:");
listeyiGoster(mList);
// listeyi sıralıyoruz
Collections.sort(mList);
// Sıralanmış diziyi gösteriyoruz
System.out.println("Sıralanmış dizi:");
listeyiGoster(mList);
}
private static void listeyiGoster(ArrayList mList) {
for (int i = 0; i < mList.size(); i++) {
System.out.println(i + " -> " + mList.get(i));
}
}
}
Kodun çıktısı aşağıdakine benzer olur:
Sıralanmamış dizi:
0 -> Black Sabbath
1 -> Judas Priest
2 -> Jimi Hendrix
3 -> Dire Straits
4 -> Pink Floyd
Sıralanmış dizi:
0 -> Black Sabbath
1 -> Dire Straits
2 -> Jimi Hendrix
3 -> Judas Priest
4 -> Pink Floyd
Elemanlarının tipi Integer, String, Double vs olan listeleri sıralamak basit, peki kendi nesnelerimizi nasıl sıralarız? Mesela String tipinde ad, soyad ve int tipinde doğum yılı alanları olan ‘Ogrenci’ tipinde elemanları olan bir liste. Deneyelim..
Önce Ogrenci classımızı yazalım:
public class Ogrenci {
private String ad;
private String soyAd;
private int dogumYili;
public Ogrenci(String ad, String soyAd, int dogumYili) {
super();
this.ad = ad;
this.soyAd = soyAd;
this.dogumYili = dogumYili;
}
public String getAd() {
return ad;
}
public void setAd(String ad) {
this.ad = ad;
}
public String getSoyAd() {
return soyAd;
}
public void setSoyAd(String soyAd) {
this.soyAd = soyAd;
}
public int getDogumYili() {
return dogumYili;
}
public void setDogumYili(int dogumYili) {
this.dogumYili = dogumYili;
}
@Override
public String toString() {
return this.getAd() + " " + this.getSoyAd() + " :: "
+ this.getDogumYili();
}
}
Şimdi main classın içinde elemanlarının tipi Ogrenci olan bir liste oluşturup elemanlar ekleyelim ve konsola yazdıralım.
public static void main(String[] args) {
ArrayList mList = new ArrayList();
mList.add(new Ogrenci("F. Oğuz", "ÖZKEROĞLU", 1988));
mList.add(new Ogrenci("Ad", "SOYAD", 1985));
mList.add(new Ogrenci("İsim", "SOYİSİM", 2000));
mList.add(new Ogrenci("Deneme", "YANILMA", 2011));
// Sıralanmamış listeyi yazdırıyoruz:
listeyiGoster(mList);
}
private static void listeyiGoster(ArrayList<Ogrenci> mList) {
for (int i = 0; i < mList.size(); i++) {
System.out.println(i + " -> " + mList.get(i));
}
}
Kodun çıktısı aşağıdakine benzer olur:
0 -> F. Oğuz ÖZKEROĞLU :: 1988
1 -> Ad SOYAD :: 1985
2 -> İsim SOYİSİM :: 2000
3 -> Deneme YANILMA :: 2011
Şimdi listeyi sıralamaya çalışalım
Collections.sort(mList);
Bu satırda IDE aşağıdaki uyarıyı veriyor:
‘Bound mismatch: The generic method sort(List) of type Collections is not applicable for the arguments (ArrayList). The inferred type Ogrenci is not a valid substitute for the bounded parameter <T extends Comparable<? super T>>’
Biz metoda listeyi sırala diye verdik ama neye göre sıralaması gerektiğini söylemedik. Ad, soyad ve doğum yılına göre sıralanabilir bir liste. Peki böyle durumlarda ne yapacağız? Sıralanacak türü diğer türdaşları ile karşılaştırılabilir bir forma sokacağız. Bunu yapabilmek için ben şöyle bir yöntem kullandım: Collections sınıfının sort metodunun liste ve Comparator türünden nesneleri parametre olarak alan versiyonunu kullandım. Metodu çağırırken Comparator classımı da oluşturdum. Sonunda aşağıdaki gibi bir kod parçası ortaya çıktı:
public class ObjectSort {
/**
* @author Oguz
*/
public static void main(String[] args) {
ArrayList mList = new ArrayList();
mList.add(new Ogrenci("F. Oğuz", "ÖZKEROĞLU", 1988));
mList.add(new Ogrenci("Ad", "SOYAD", 1985));
mList.add(new Ogrenci("İsim", "SOYİSİM", 2000));
mList.add(new Ogrenci("Deneme", "YANILMA", 2011));
// Sıralanmamış listeyi yazdırıyoruz:
System.out.println("Sıralanmamış liste:");
listeyiGoster(mList);
// Listeyi sıralıyoruz
Collections.sort(mList, new Comparator() {
@Override
public int compare(Ogrenci o1, Ogrenci o2) {
String oName1 = o1.getAd();
String oName2 = o2.getAd();
return oName1.compareTo(oName2);
}
});
// Sıralanmamış listeyi yazdırıyoruz:
System.out.println("Sıralanmış liste:");
listeyiGoster(mList);
}
private static void listeyiGoster(ArrayList<Ogrenci> mList) {
for (int i = 0; i < mList.size(); i++) {
System.out.println(i + " -> " + mList.get(i));
}
}
}
‘compare’ metoduna Ogrenci türünde aldığı iki nesnenin adlarını alıp birer String’e atmasını ve karşılaştırmayı bu Stringler arasında yapmasını söyledik. Sonuçta da aşağıdaki gibi bir konsol çıktısı oluştu:
Sıralanmamış liste:
0 -> F. Oğuz ÖZKEROĞLU :: 1988
1 -> Ad SOYAD :: 1985
2 -> İsim SOYİSİM :: 2000
3 -> Deneme YANILMA :: 2011
Sıralanmış liste:
0 -> Ad SOYAD :: 1985
1 -> Deneme YANILMA :: 2011
2 -> F. Oğuz ÖZKEROĞLU :: 1988
3 -> İsim SOYİSİM :: 2000
Metoda aldığı öğrencileri adlarına göre sılaramasını söylediğimiz için konsol çıktısında sıralanmış liste ada göre sıralanmış bir liste oldu. Eğer listenin doğum yılına göre sıralanmasını istiyorsak metodumuzu aşağıdaki gibi değiştirmemiz gerekirdi.
Collections.sort(mList, new Comparator() {
@Override
public int compare(Ogrenci o1, Ogrenci o2) {
Integer oYear1 = o1.getDogumYili();
Integer oYear2 = o2.getDogumYili();
return oYear1.compareTo(oYear2);
}
});
Çıktı da aşağıdaki gibi olur:
Sıralanmamış liste:
0 -> F. Oğuz ÖZKEROĞLU :: 1988
1 -> Ad SOYAD :: 1985
2 -> İsim SOYİSİM :: 2000
3 -> Deneme YANILMA :: 2011
Sıralanmış liste:
0 -> Ad SOYAD :: 1985
1 -> F. Oğuz ÖZKEROĞLU :: 1988
2 -> İsim SOYİSİM :: 2000
3 -> Deneme YANILMA :: 2011
Liste artık dogumYili alanının değerlerine göre sıralı.
Yukarıda yalan – yanlış bilgiler yer alıyor olabilir, okuyanlar böyle bir şeyin farkına varırlarsa lütfen uyarmaktan çekinmesinler.
Android’in veri saklama yöntemleri ile alakalı daha önce Android :: Shared Preferences yazısını yazmıştım. O listedeki external storage cihazın harici hafızasına, yani şimdilik sd karta tekabül ediyor.
Üzerinde çalıştığım projelerin birinde mp3 dosyalarını saklamam gerekiyordu. Sayısı birden fazla ve her birinin ortalama boyutu 10 mb civarında mp3 dosyalarını dahili hafızaya ya da uygulama paketi içinde bir yerlere yazsam kısa süre sonra cihaz kullanılmaz hale gelebilir. Bu durumda çözüm olarak dosyaları sd kart üzerine yazmaya karar verdim (Umarım doğru bir karar vermişimdir :)
Başta direkt sd kart üzerine yazıp uygulamayı çalıştırdım ama kısa süre sonra kart çöplüğe döndü. Her şeyi ana dizin içine atıyordum. İşte tam burda kart üzerinde bir klasör oluşturma ve dosyaları oraya yazma / oradan okuma zorunda kaldım. Bu yazıda da bu olayı nasıl yaptığımı anlatmaya çalışacağım.
Bunun için Java’nın “File” class’ından bir obje yaratıp, parametre olarak yol + klasör ismi verdim ve sonrasında file.mkdir() metodu ile klasörü oluşturdum. Kod aşağıdaki gibi:
File mFile = new File("/sdcard/altKlasor");
mFile.mkdir();
Tabi bu kodun çalışması için yine her zamanki gibi AndroidManifest.xml dosyasına harici hafızaya yazma iznini eklememiz gerekiyor.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Bu sayede direkt sd kart altında klasörü oluşturduk. Aşağıda Eclipse’teki File Explorer’ın kod çalışmadan önceki ve sonraki hali var.
Önce:

Sonra:

Kodu çalıştırdık işimizi gördük ama burda ufak bir sıkıntı var. Sd kartın yolunu elle girdik. İlerde yolun değişebilmesi ya da sd kart yerine başka bir harici hafıza kullanılabilmesi durumlarına karşılık daha iyi bir yöntem kullanmak gerekti. Bunun için de harici hafızanın direkt yolunu alan aşağıdaki kodu buldum.
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
Bu şekilde biraz daha bağımsızlık ve esneklik kazanmış olduk. Dosyayı oluşturan kodun tamamı aşağıdaki gibi şekillendi.
String strNewFolder = "/altKlasor"; String extStorageDirectory = Environment.getExternalStorageDirectory().toString(); File mFile = new File(extStorageDirectory + strNewFolder); mFile.mkdir();
Belki birinin daha işine yarar..
WebView içinde bir web sayfasını göstermek için aşağıdaki kod kullanılıyor.
WebView wv;
wv = (WebView) findViewById(R.id.webview);
wv.loadUrl("http://www.google.com");
Tabi bunu kullanabilmek için uygulamamıza internete erişim iznini vermemiz gerekiyor. Bunun için de AndroidManifest.xml dosyası içinde uygun yere aşağıdaki satırı ekliyoruz.
<uses-permission android:name="android.permission.INTERNET" />
Çalıştırdığımızda aşağıdaki gibi bir görüntü elde ediyoruz.

Buraya kadar bir sıkıntı yok zaten bilinen şeyler. Peki kendi hazırladığımız bir html sayfasını nasıl gösteririz?
Bunun için html içeriğimizi oluşturup bir stringe atıyoruz ve WebView içinde o stringi gösteriyoruz.
String strHtml = "<html><head></head>" + "<body text=\"#444444\" bgcolor=\"#CCCCCC\">" + "<br /><br /><center><h2>" + "Static html content in Android" + "</h2></center></body></html>"; wv.loadData(strHtml, "text/html", "UTF-8");

Artık internet erişimine gerek kalmadığı için Manifest dosyamızdan o izni kaldırabiliriz. Bu string içinde CSS de kullanılabilir. Bunlar yeterli değil, JavaScript de olsun diyorsanız aşağıdaki satırı WebView tanımlamasında sonra eklemeniz gerekir.
wv.getSettings().setJavaScriptEnabled(true);

Örnek uygulamada kullandığım java dosyası:
package com.oguz.example;
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.WebView;
public class WebViewTest extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
setContentView(R.layout.webwiew_test);
WebView wv = (WebView) findViewById(R.id.webkitWebView1);
String strHtml = "<html><head></head>"
+ "<body text=\"#444444\" bgcolor=\"#CCCCCC\">"
+ "<br /><br /><center><h2>"
+ "Static html content in Android</h2>"
+ "<script type=\"text/javascript\">"
+ "document.write(Date());</script>"
+ "</center></body></html>";
wv.getSettings().setJavaScriptEnabled(true);
wv.loadData(strHtml, "text/html", "UTF-8");
}
}
XML dosyası ise:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <android.webkit.WebView android:id="@+id/webkitWebView1" android:layout_width="fill_parent" android:layout_height="fill_parent"> </android.webkit.WebView> </LinearLayout>



