20 Temmuz 2014 Pazar

Cordova/Phonegap ile Ekran görüntüsü almak

Bu yazıda Cordova ile uygulamanın ekran görüntüsünü almak için kullandığım bir plugini anlatacağım.

Kullanımı basit, ilk önce projemize ekleyelim.
$ cordova plugin add https://github.com/gitawego/cordova-screenshot

Kullanımı


Plugin save ve URI metodlarından oluşuyor.

save

navigator.screenshot.save(function(error,res){
  if(error){
    console.error(error);
  }else{
    console.log('dosya yolu: ',res.filePath);
  }
});

Bu metoda 2 parametre alan callback fonksiyon göndermek ekran görüntüsünü alabilmek için yeterli. İlk parametre eğer hata oluşmuşsa onu gösterir, ikincisi de sonucu döner. Dosya yolunu res.filePath  şeklinde alabiliyoruz.

Resimler android için /sdcart/Pictures dizinine kaydediliyor.

Callback fonksiyonun yanında kaydedilecek dosya türü , çözünürlük kalitesi ve dosya ismi  değerlerini de gönderebiliriz.

navigator.screenshot.save(function(error,res){
  if(error){
    console.error(error);
  }else{
    console.log('dosya yolu: ',res.filePath);
  }
},'jpg',50,'resimAdi');

Bu metodu ios ve android de kullanabiliyoruz.

URI

Her zaman ekran görüntüsünü telefona kaydetmek istemeyebilirsiniz.Sadece data URI olarak alıp öyle kullanmanız gerekli olabilir. Bunu da plugine eklediğim URI metodu ile yapıyoruz.


navigator.screenshot.URI(function(error,res){
  if(error){
    console.error(error);
  }else{
    html = '<img src="'+res.URI+'" style="width: 50%;">';
    document.body.innerHTML = html;
  }
},50);

URI metodu bir callback fonksiyonu ve  kalite değerini alıyor. Bize gelen res.URI resim verisini img etiketi ile kullanıcıya gösterebileceğimiz gibi, server'a da bir string değer yolluyormuşuz gibi de yollayabiliriz.

Bu metodu ise şimdilik sadece android de kullanabiliyoruz. Umarım yakın zamanda ios için de implement edecek biri çıkar.

12 Temmuz 2014 Cumartesi

Cordova/Phonegap ile Sqlite3 veritabanı işlemleri

Bir önceki yazıda sqlite veritabanına bağlanmayı anlatmıştım.

Kullandığımız SQLitePlugin, yapı olarak HTML5 SQL API(web sql)  ile birebir aynı olmayı amaçlamış. Tek büyük fark ise veritabanının açılış şekli gibi gözüküyor (window.openDatabase() yerine window.sqlitePlugin.openDatabase() kullanıyoruz.) .

HTML5 SQL API'de dolayısıyla SQLitePlugin'de 3 ana metod bulunmakta.

  1. openDatabase
  2. transaction
  3. executeSql

openDatabase

Bir önceki yazı da openDatabase metodunu kullanarak veritabanını açmıştık. Aslında veritabanını açmak için 2 seçeneğimiz bulunuyor. İlki bir önceki yazıda da kullandığımız ve önerilen yöntem:

  var db = window.sqlitePlugin.openDatabase({name: "databaseAdi.db"});

Birde klasik yöntem var:

   
  var db = window.sqlitePlugin.openDatabase("databaseAdi.db", "1.0", 
                                          "Deneme veritabanı", 2*1024);

Method 4 parametre alıyor:

  1. Veritabanı adı
  2. Versiyon numarası
  3. Açıklama metni
  4. Tahmini veritabanı boyutu

 Özellikle web sql kullanırken 2. yöntemi kullanmak isteyebilirsiniz. Ama SQLitePlugin kullanırken bu kadar detaya gerek kalmıyor.

Veritabanını açmış bulunmaktayız.Burada önemli nokta ise, bu metodu deviceReady olayından sonra çağırmak. Aksi takdir de uygulamanız hata verecektir.

Transactions(İşlemler)

Veritabanımızı açtık. Artık sorgu yazmak veri almak istiyoruz.. Fakat bu sorgularımızı transaction içerisinde yazmamız gerekiyor. Transaction aslında işlem demek. Sorgularımızı işlem altında yapıyoruz  çünkü işlemler bize geri alma yeteneği kazandırıyor. Bu şu demek: Eğer bir işlem içindeki bir yada birkaç sql sorgusu başarısız olursa ( sql sorgusu yada  herhangi bir kod) o işlem altında veritabanına yapılan güncellemeler iptal edilir. Yani, sanki işlem(transaction) hiç çalışmamış gibi olur. Bunun yanında oluşan hatayı da yakalayabiliriz.

Örneğe bakalım:

  var db = window.sqlitePlugin.openDatabase({name: "databaseAdi.db"});

  db.transaction(function (tx) {
    // Burada işlemler..
    // tx nesnesini kullanarak sql sorguları yapıyoruuuz..
  },function(e) {
    console.log("HATA: " + e.message);
  });

transaction metoduna 2 fonksiyon yolladım gördüğünüz gibi. Biri sql sorgularımızın olacağı fonksiyon, diğeri ise eğer hata oluşursa çalışacak ve hatayı işlememizi sağlayacak diğer bir fonksiyon.

İlk fonksiyon tx adlı bir nesne alıyor. Bu nesne ile beraber artık sql sorgu çalıştırmaya hazırız.

executeSql

executeSql metodu pek çok işimize yarıyor. Bu metodla istediğimiz sql sorgularını yapabiliyoruz, bizi sql injection'a karşı koruyor ve sorgu sonucunu işlemek için bir de callback sağlıyor.

Bir önceki örneği biraz değiştirelim:

   var db = window.sqlitePlugin.openDatabase({name: "databaseAdi.db"});

  db.transaction(function (tx) {
   tx.executeSql("CREATE TABLE kisi (id UNIQUE,ad TEXT)");
   
   tx.executeSql("INSERT INTO kisi VALUES(1,"Halil")");
  });

transaction içerisinde kisi adlı tablo oluşturduk ve içerisine 1 adet veri ekledik. Ama şuanki haliyle adı veya id'yi farklı bir kaynaktan çekmeye çalışırsak (input, hash vs..) sql injection'a davetiye çıkarmış oluruz değil mi ?

Gelin son olarak, hem bu sorunu çözelim hem de eklediğimiz satırı ayrı bir sorguyla alıp işlemeye çalışalım.

  var db = window.sqlitePlugin.openDatabase({name: "databaseAdi.db"});

  db.transaction(function (tx) {
    tx.executeSql("CREATE TABLE kisi (id UNIQUE,ad TEXT)");
   
    tx.executeSql("INSERT INTO kisi VALUES(?,?)",[1,"Halil"]);

    tx.executeSql("SELECT * FROM kisi",[], function(tx, res){
      
      console.log("Toplam çekilen satır sayısı: "+ res.rows.length);
    
      // çekilen satırlardan (şuan bir satır olması gerekiyor gerçi) 
      // ilk satırı alıyoruz
      kisi = res.rows.item(0);
 
      console.log("Kullanıcı adı: " + kisi.ad + " Id'si : " + kisi.id ); 
    });
  });

Örnekte de gördüğünüz gibi SELECT sorgusuyla çektiğimiz verilere ulaşmak çok kolay. executeSql metodunun bize sağladığı 2. argüman olan res ile satırlara erişebiliyoruz. Aynı zaman da veritabanına ekleme yapmak için çağırdığımız executeSql metoduna da bir callback ekleyip res parametresiyle kaç satır etkilendiğini kontrol etmemizi sağlayan res.rowsAffected ve eğer tabloda otomatik artan (auto_increment) bir id var ise eklenen yeni satırın id'sine res.insertId şeklinde erişmemiz mümkün.

Bu yazılık bu kadar. Daha fazla bilgi için aşağıdaki kaynaklara göz atabilirsiniz .

Kaynak : http://html5doctor.com/introducing-web-sql-databases/
              https://github.com/brodysoft/Cordova-SQLitePlugin/blob/master/README.md



5 Temmuz 2014 Cumartesi

Cordova/Phonegap ile Sqlite3 veritabanına bağlanmak

Mevcut sqlite3 veritabanınızı Cordova projenize eklemek varolan pluginleri kullanarak çok kolay bir hal almış.

Hemen anlatayım:

İlk sqlite pluginimizi indiriyoruz (Projenizin olduğu klasör üzerindesiniz varsayıyorum)
$ cordova plugin add https://github.com/brodysoft/Cordova-SQLitePlugin
Maalesef bu yetmiyor, mevcut veritabanınızı uygulama klasörüne kopyalayacak bir plugine daha ihtiyacımız var.
$ cordova plugin add https://github.com/an-rahulpandey/cordova-plugin-dbcopy

Android için veritabanınızı PROJE/platforms/android/assets klasörüne kopyalayın.

IOS için ise Resource klasörüne kopyalayın ve veritabanını Xcode Projenize ekleyin.(Resources klasörüne sağ tık-> Add Files)

Şimdi, deviceready olayına bir dinleyici bağlayacağız.

var db;
document.addEventListener("deviceready", function(){
   function dbcopy()
   {
      // Veritabanını Uygulama Dizinine kopyalar
      // Başarılı olursa openDB fonksiyonunu çağıracak.
      window.plugins.sqlDB.copy("database.db",openDB);
   }

   function openDB()
   {
      db = window.sqlitePlugin.openDatabase({name: "database"});
   }

   if(! window.localStorage.getItem('dbCopied') )
   {
      window.localStorage.setItem('dbCopied',true)
      dbcopy();
   }else
   {
      openDB();
   }
}, false);

Veritabanı adının database.db olduğunu varsaydım, dosya uzantısı .db olmak zorunda , çünkü sqlite plugini öye istiyor. :)

Sonda ise eğer bir kere uygulama dizinine kopyaladıysa, bir daha boşyere kopyalamaya çalışmasın diye bir kontrol yaptık.

Bu yayınlık bu kadar, bir sonraki yayında, javascript üzerinden basit veritabanı işlemleri yapacağız.