My Mobile Notes

Some useful tips & tricks for Android & iOS Programming, and Mobile Life

  • Contact

    Mustafa Ferhan Akman, Android Evangelist, Android & iOS Developer, Author, Blogger, Speaker

  • Subscribe

Örnek Bir Rozet Algoritması (Bozuk Yol – Pacman)

Posted by Mustafa Ferhan Akman on January 28th, 2015

Önbilgi

Bozuk Yol ile geçen yıl, Turkcell Geleceği Yazanlar’a katılarak büyük ödülün sahibi olmuş ve Kasım 2014′de Silikon Vadisi’ne gitmiştik. Bozuk Yol lle Android ve iOS‘daki kullanıcılarımız 89bin KM yol yaparak toplamda 38bin bozuk yol bilgisini bize gönderdiler. Bozuk Yol’un çalışması ile küçük bir demoyu buradan izleyebilirsiniz.

device-2014-06-12-163607   device-2014-06-12-163312

İhtiyaç

Bugünkü yazımda, Bozuk Yol’da gamification alt yapısında kullanıcılarımız ve kullanıcılarımıza verdiğimiz Pacman rozetinin alt yapısından bahsetmek istiyorum.

Bozuk Yol bildiğiniz üzere, otomobilinizle trafikte seyir halindeyken, yollardaki bozuklukları otomatik olarak algılayan, bunları crowsourcing yöntemiyle doğrulayan ve ilgili belediyelere bildiren bir sistem.

Her ne kadar temel amacımız yollardaki bozuklukları olabildiğince çok kullanıcılarımıza tespit ettiyor olmayı istesekde, bir kullanıcının arka arkaya çok fazla çukura girmesi, bizim için temelde üç manaya geliyor.

1- Gerçekten çok fazla bozukluğun olduğu bir yol mecvut.

2- Kullanıcı belki bize daha fazla data göndermek için belki de istemeyerek bozuk yollara giriyor ama sonuç olarak bu kadar çok bozuk yola girmesi otomobiline zarar verebilir

3- Bu kadar sıklıkla bozuk yol bilgisinin bize gönderilmesi iyi niyetli olmayan kullanıcılarımız tarafından datalarımızın manipule edildiği anlamına gelebilir.

Basitçe tarif etmek gerekirse, Pacman ismini verdiğimiz rozetimiz, uygulama içerisinde arka tarafta kullanıcıların belli bir kilometre içerisinde girdiği toplam bozuk yol sayısını sürekli olarak kontrol ediyor ve bizim belirlediğimiz bir eşik değerinin üzerine çıkılması durumunda kullanıcımızın ilgili rozeti kazanmasını sağlıyor.

Algoritma

Yukarıda basitçe vermiş olduğum tarifi biraz daha açıp, analiz edecek olursak adım adım şunları yapmamız gerekir;

1- KM cinsinden mesafe eşik değeri olarak 10 km’yi baz alalım. Bu bizim ilk kuralımız. Kullanıcımızın bizden rozet kazanabilmesi en az 10km’lik yol gitmesi  gerekiyor ve 10km gittiğinde ikinci şartı kontrol edeceğiz.

2- Tespit edilecek bozuk yol için eşik değeri olarak 20 adet olarak belirleyelim. Yani kullanıcı 20 adet bozuk yol tespit etmesi, rozet vermek için ikinci şartımız.

Sadece bu iki şart göz önünde bulundurulduğunda şu olacak; kullanıcı ilk 10km’yi gittiğinde algoritmamız 20 adet bozukyol tespitinin olup olmadığına bakacak. Fakat, aşağıdaki şemada da görebileceğiniz üzere, kullanıcın toplam gideceği yol, 75km’lik bir mesafe ise, benim asıl bakmam gereken hep son 10km’lik data olacak. Yani, algoritmanın zor kısmı.

Bozuk Yol pacman badge

3- Üçüncü aşama olarak, Data Structure derslerinden hatırladığımız bir Queue yapısını kullanmam gerekiyor ki, sadece son 10km’yi hesaplayabilelim. Şuan uygulamayı geliştirdiğim platform Android olduğu için yani uygulamayı Java dilinde geliştiriyor olduğum için, ConcurrentLinkedQueue yapısını kullandım.  ConcurrentLinkedQueue temel olarak, FIFO  (first-in-first-out) yapısında çalışacak (yani bir banka kuyruğunu düşünecek olursak, sıraya ilk giren bankadan ilk çıkar ve hep son girenler sıra kendilerine gelinceye kadar sırada beklemeye devam ederler) ve bu sayede her zaman için, birinci km’de tespit ettiğim bozukluklar, onuncu km’ye geldiğimde otomatik olarak listeden silinecek ve onbirinci km’deki bozuklukların listeye girmesi için yer açacak.

Kod

Bu kadar laf salatasından sonra artık koda geçelim;

public class PacmanBadge {

    public static int INITIAL_DISTANCE        = 1;
    public static int DISTANCE_ADDED_TO_QUEUE = 2;
    public static int BADGE_ACHIEVED          = 3;
    public static int POTHOLES_ADDED_TO_QUEUE = 4;

    Queue<PacmanNode> queue = new ConcurrentLinkedQueue<PacmanNode>();
    float indexKM = 0f;
    int indexPotholeCount = 0;
    int thresholdKM = 10;
    int thresholdPothole = 20;

}

Öncelikli olarak, tanımlamaları açıklamamda fayda var. INITIAL_DISTANCE, DISTANCE_ADDED_TO_QUEUE, BADGE_ACHIEVED ve POTHOLES_ADDED_TO_QUEUE; Biraz sonra kendisiyle aşağıda tanışacağınız “calculatePacman()” fonksyionunun return typlerı olarak tanımlanmıştır ve bu fonsiyon gerekli hesaplamaları yaptıktan sonra, yalnızca BADGE_ACHIEVED mesajını geriye döndürdüğünde kullanıcı gerçekten bir rozet kazanmış oluyor.

indexKM ve indexPotholeCount mevcuttaki uzaklık ve bozukluk değerlerini; thresholdKM ve thresholdPothole ise benim eşik değeri olarak belirlediğim mesafe ve bozukyol tespit sayısını göstermektedir.

Bozuk Yol’daki senaryoya göre calculatePacman() fonsksiyonu iki değer geliyor. Birincisi kullanıcının o ana kadar tüm uygulama geçmişi boyunca yapmış olduğu toplam mesafe (km cinsinden) ve toplam bozuk yol tespit sayısı. Bu iki değer calculatePacman() çağırılırken parametre olarak istatistik verileri tutulan modülden anlık olarak sorgulanarak geliyor.

    public int calculatePacman(float currentTotalKM, int currentTotalPotholeCount) {

        float headDistance = currentTotalKM - indexKM;
        int headPotholeCount = currentTotalPotholeCount - indexPotholeCount;

        if(queue.size() == 0) {
            indexKM = headDistance;
            indexPotholeCount = headPotholeCount;

            //first time, set initial index
            queue.add(new PacmanNode(0, 0));
            return INITIAL_DISTANCE;//false;
        }

        // add queue until threshold distance (KM)
        if(headDistance < thresholdKM){
            queue.add(new PacmanNode(headDistance,headPotholeCount));
            return DISTANCE_ADDED_TO_QUEUE; //false;
        }

        // If the user has been gone 'thresholdKM' but not reach required 'threshold pothole'
        if(headDistance >= thresholdKM && headPotholeCount >= thresholdPothole){

            //User badge'i almaya hak kazandı!
            //BadgeUtil.getInstance().setPacmanBadge(context);
            return BADGE_ACHIEVED; //true;
        }

        // User reach threshold distance but there is no threshold pothole.
        // The queue is polling where indexKM less than thresholdKM
        if(headDistance >= thresholdKM && headPotholeCount < thresholdPothole) {

            queue.add(new PacmanNode(headDistance,headPotholeCount));

            do {
                PacmanNode node = queue.poll();

                if(node != null) {
                    indexKM = node.getNewDistance();
                    indexPotholeCount = node.getNewPotholeCount();
                }
            } while (currentTotalKM - indexKM >= thresholdKM);
        }

        return POTHOLES_ADDED_TO_QUEUE;//false;
    }

calculatePacman() fonksiyonu herhangi bir durum karşısında yukarıda tanımlamış olduğum 4 durumdan bir tanesini döndürmek zorunda. Yani, başka bir deyişle calculatePacman() dört ana parçadan oluşuyor.

Birincisi, İlk gelen yol değişikliğinde, eğer kullanıcımız uygulamamızı ilk defa kullanıyorsa, ilk data girişini yapıyoruz.

if(queue.size() == 0) {
  indexKM = headDistance;
  indexPotholeCount = headPotholeCount;

  //first time, set initial index
  queue.add(new PacmanNode(0, 0));
  return INITIAL_DISTANCE;//false;
}

İkinci durumda, kullanıcının öncelikli olarak, eşik değeri kadar yol gitmesini bekliyoruz.

// add queue until threshold distance (KM)
if(headDistance < thresholdKM){
  queue.add(new PacmanNode(headDistance,headPotholeCount));
  return DISTANCE_ADDED_TO_QUEUE; //false;
}

Üçüncü durumda, kullanıcımız yeteri kadar yol gidip, belirlediğimiz eşik değeri kadar bozuk yol tespiti yapmışsa ona hak ettiği ödülü veriyoruz!

// If the user has been gone 'thresholdKM' but not reach required 'threshold pothole'
if(headDistance >= thresholdKM && headPotholeCount >= thresholdPothole){

  return BADGE_ACHIEVED; //true;
}

Ve son durumda kullanıcının toplam gitmiş olduğu yol mutlak surette eşik değerini geçmiş ve mevcuttaki bozukyol tespit sayısı eşik değerimizin altında ise, aslında bu kişinin pacman badge’ini kazanacak kadar çok sayıda bozuk yollara düşmediğini anladığımızdan, son on kilometreleri kontrol etmeye devam ediyoruz.

// User reach threshold distance but there is no threshold pothole.
// The queue is polling where indexKM less than thresholdKM
if(headDistance >= thresholdKM && headPotholeCount < thresholdPothole) {

    queue.add(new PacmanNode(headDistance,headPotholeCount));

    do {
        PacmanNode node = queue.poll();

        if(node != null) {
            indexKM = node.getNewDistance();
            indexPotholeCount = node.getNewPotholeCount();
        }
    } while (currentTotalKM - indexKM >= thresholdKM);
}

return POTHOLES_ADDED_TO_QUEUE;//false;

 

Badge kontrolü yapan class’ın tamamı:


package com.bozukyol.pacmanbadge;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * @author Mustafa Ferhan Akman
 * @since 04 May 2014 - 23:38
 */
public class PacmanBadge {

 public static int INITIAL_DISTANCE = 1;
 public static int DISTANCE_ADDED_TO_QUEUE = 2;
 public static int BADGE_ACHIEVED = 3;
 public static int POTHOLES_ADDED_TO_QUEUE = 4;

 Queue<PacmanNode> queue = new ConcurrentLinkedQueue<PacmanNode>();
 float indexKM = 0f;
 int indexPotholeCount = 0;
 int thresholdKM = 10;
 int thresholdPothole = 20;

 private static PacmanBadge instance;

 public static PacmanBadge getInstance() {
 if(instance == null) {
 instance = new PacmanBadge();
 }

 return instance;
 }

 private PacmanBadge() {
 }

 public int calculatePacman(float currentTotalKM, int currentTotalPotholeCount) {

 float headDistance = currentTotalKM - indexKM;
 int headPotholeCount = currentTotalPotholeCount - indexPotholeCount;

 if(queue.size() == 0) {
 indexKM = headDistance;
 indexPotholeCount = headPotholeCount;

 //first time, set initial index
 queue.add(new PacmanNode(0, 0));
 return INITIAL_DISTANCE;//false;
 }

 // add queue until threshold distance (KM)
 if(headDistance < thresholdKM){
 queue.add(new PacmanNode(headDistance,headPotholeCount));
 return DISTANCE_ADDED_TO_QUEUE; //false;
 }

 // If the user has been gone 'thresholdKM' but not reach required 'threshold pothole'
 if(headDistance >= thresholdKM && headPotholeCount >= thresholdPothole){

 //User badge'i almaya hak kazandı!
 //BadgeUtil.getInstance().setPacmanBadge(context);
 return BADGE_ACHIEVED; //true;
 }

 // User reach threshold distance but there is no threshold pothole.
 // The queue is polling where indexKM less than thresholdKM
 if(headDistance >= thresholdKM && headPotholeCount < thresholdPothole) {

 queue.add(new PacmanNode(headDistance,headPotholeCount));

 do {
 PacmanNode node = queue.poll();

 if(node != null) {
 indexKM = node.getNewDistance();
 indexPotholeCount = node.getNewPotholeCount();
 }
 } while (currentTotalKM - indexKM >= thresholdKM);
 }

 return POTHOLES_ADDED_TO_QUEUE;//false;
 }

 private class PacmanNode {

 float newDistance;
 int newPotholeCount;

 public PacmanNode(float distance, int pothole){
 newDistance = distance;
 newPotholeCount = pothole;
 }

 public float getNewDistance() {
 return newDistance;
 }

 public int getNewPotholeCount() {
 return newPotholeCount;
 }

 @Override
 public String toString() {
 return "PacmanNode{" +
 "newDistance=" + newDistance +
 ", newPotholeCount=" + newPotholeCount +
 '}';
 }
 }

 public void clearPacmanQueue(){
 queue.clear();
 }

}

Test

Peki bitti mi? Tabi ki hayır. Kullanıcılarımıza badge vermek için bir algoritma kuruyoruz, bu algoritmaya göre 10km yol gidip, aracımızla 20 adet bozuk yola girmemiz gerekiyor. Bu algoritmada her bir değişikliği ya da uyguladığımız 1 satırlık kodu nasıl test edeceğiz?

Test etmek için her defasında otomobilinize binip, yollarda 10km yol gitme fikri kafanıza yatıyorsa yazının devamını okumanıza gerek olmadığını baştan söyleyeyim:)

Test class’ını oluşturuyoruz.

Hatırlayacağınız üzere, dört farklı durumumuz vardı. Yani bu dört farklı return değerlerinin hepsini kontrol edebileceğimiz dört satırlık bir test case’i oluşturmamız lazım. Tabii bu en asgarisi.

Ben biraz durumu abarttım ve farklı farklı senaryolarla, bütün ihtimalleri test etmek istedim. Ortaya 4 adet test çıktı.

Birinci testcase’i  kullanıcının rozet alacak kadar bozukyol tespiti yaptığını ve bunu yaparken aslında çok az mesafe kat ederek yaptığını varsayarak yazdım;

public void testCalculatePacmanScenario1() throws Exception {
    PacmanBadge.getInstance().clearPacmanQueue();

    assertEquals(1,PacmanBadge.getInstance().calculatePacman( 0, 0 ));
    assertEquals(2,PacmanBadge.getInstance().calculatePacman( 0, 0 ));

    assertEquals(2,PacmanBadge.getInstance().calculatePacman( 5f, 3 ));
    assertEquals(2,PacmanBadge.getInstance().calculatePacman( 5f, 3 ));
    assertEquals(2,PacmanBadge.getInstance().calculatePacman( 6f, 25 ));
}

İkinci testcase’i kullanıcımıızn 10km yol gidip, normal birisi gibi 20′den az bozuk yol tespiti yapacağını varsaydım,

public void testCalculatePacmanScenario2() throws Exception {

 PacmanBadge.getInstance().clearPacmanQueue();

 assertEquals(1,PacmanBadge.getInstance().calculatePacman( 1f, 1 ));

 assertEquals(2,PacmanBadge.getInstance().calculatePacman( 4f, 7 ));
 assertEquals(2,PacmanBadge.getInstance().calculatePacman( 5f, 8 ));
 assertEquals(2,PacmanBadge.getInstance().calculatePacman( 9f, 8 ));

 assertEquals(4,PacmanBadge.getInstance().calculatePacman( 11f, 8 ));
 }

 

Üçüncü testcase’de, kullanıcımıızn 10km yol gidip, hakikaten de 20′den fazlaa bozuk yol tespiti yapacağını varsaydım,

 


public void testCalculatePacmanScenario3() throws Exception {
 PacmanBadge.getInstance().clearPacmanQueue();

assertEquals(1,PacmanBadge.getInstance().calculatePacman( 1f, 1 ));

assertEquals(2,PacmanBadge.getInstance().calculatePacman( 4f, 7 ));
 assertEquals(2,PacmanBadge.getInstance().calculatePacman( 5f, 15 ));
 assertEquals(2,PacmanBadge.getInstance().calculatePacman( 9f, 19 ));

assertEquals(3,PacmanBadge.getInstance().calculatePacman( 12f,21 ));
}

Son ve en karışık olan testcase’de ise,  birisinin aslında gerçekten günlük hayatta karşısına gelebieceği bir senaryoyu modellemeye çalıştım. Ortaya çıkan senaryo biraz karışık gelebilir ama yine de anlatmaya çalışayım;

Kullanıcımız, öncelikle 16km’lik bir yol gitti. Bu 19km’lik yolun ilk 9km’sinde, 8 bozukyol tespit etti. Sonraki 4km’de ise 11 tane daha bozukyol tespit etti. Ara toplamda, 13km içerisinde 19 adet tespitte bulundu. Kullanıcımız yolda giderken benzin ihtiyacunı farketti ve benzinlikte durdu. Dolayısıyla, belli aralıklarla kullanıcının istatistiklerini kontrol ettiğimizde toplam gidilen yol miktarını hep aynı görmeye başladık. X dakika sonra benzinlikten ayrılan kullanıcımız yoluna devam etti. İlk 3km içerisindeyken  11 bozukyola daha girdi. Yani toplamda 16km için 30 bozukyol yakalamış oldu!

Son 10km’yi bulmak için kullanıcımınz ilk 6km’de yakalamış olduğu 8 tane bozukyol bilgisini düşersek,  son 10km’de 22 adet bozukyol bildirimi yaparak “pacman” rozetini kazanmaya hak kazandı!

public void testCalculatePacmanHavuzProblemi() throws Exception {

 PacmanBadge.getInstance().clearPacmanQueue();

 assertEquals(1,PacmanBadge.getInstance().calculatePacman( 0f, 0 ));
 assertEquals(2,PacmanBadge.getInstance().calculatePacman( 1f, 1 ));

 assertEquals(2,PacmanBadge.getInstance().calculatePacman( 4f, 7 ));
 assertEquals(2,PacmanBadge.getInstance().calculatePacman( 6f, 8 ));
 assertEquals(2,PacmanBadge.getInstance().calculatePacman( 9f, 8 ));

 assertEquals(4,PacmanBadge.getInstance().calculatePacman( 13f, 19 ));

 assertEquals(2,PacmanBadge.getInstance().calculatePacman( 13f, 19 ));
 assertEquals(3,PacmanBadge.getInstance().calculatePacman( 16f, 30 ));
}

Herhangi bir testi çalıştırmak isterseniz, testcase’i sağ tıklayıp, “run” demeniz yeterli.

Eğer test sonuçları beklediğimiz gibi çıkarsa, aşağıdaki gibi yeşil renkte testimizin geçtiğini görebileceğiz.

Screen Shot 2015-01-28 at 23.02.24

Kötü Niyetli Kullanımın Tespit Edilmesi

Dikkatli okuyucu fark etmiştir; test senaryolarından bir tanesi aslında potansiyel bir kötü niyetli kullanım senaryosudur. Bir numaralı test senaryosunu kullanıcının eşik değeri adedince rozet alabilecek kadar bozukyol tespiti yaptığını ve bunu yaparken mesela datayı bir şekilde manipule ederek, evde oturduğu yerden (mesela bilgisayarındaki android emülatörü üzerinden) yaptığını varsayarak yazdım.

Buradaki testcasede, kullanıcı bir çok bozukyol tespit ediyor ama yeteri kadar mesafe gitmeden bunu yapıyorsa, bu kötü niyetli kullanımlardan bir tanesi olabileceği anlamına geliyor. Eğer istersek burada sucumuza bu kötü niyetli kullanımı bildirerek, bu kullanıcıdan gelen dataları “şüpheli” olarak işaretleyebilir ve kullanıcının gönderdiği dataları hesaplama işlerimize katmayabiliriz.

Kaynak Kodlar – GitHub

Badge hesaplama kodlarının bulunduğu class’ın ve test senaryosunun olduğu hazır projeyi GitHub’daki https://github.com/MustafaFerhan/Pacman adresten indirebilirsiniz. Bu arada bu kadar Pacman’den bahsetmişken, oyunu buradan oynayabilirsiniz:)

 

Tags: , , ,
Posted in Android, General, iOS | No Comments »

Uygulamam Google Play’den neden silinir?

Posted by Mustafa Ferhan Akman on December 7th, 2014

Bunun bir çok nedeni olabiliyormuş. Google tarafından güzel hazırlanmış bir yardım sayfası;

https://support.google.com/googleplay/android-developer/answer/113474?rd=1&hl=tr

Tags: , , , ,
Posted in Android | No Comments »

Silikon Vadisi'ne Gidiyoruz…

Posted by Mustafa Ferhan Akman on October 27th, 2014

Turkcell’in düzenlediği Geleceği Yazanlar Maraton yarışmasını geçtiğimiz haftalarda tamamlanmış ve yarışmaya katıldığımız Bozuk Yol ile ipi göğüsleyerek büyük ödülü kazandık.

Geçtiğimiz haftalarda basın https://melbournerx.com/buy-cialis-melbourne.html bülteni ile birlikte kamuoyuna duyurulan yarışma sonucu başta Anadolu Ajansı, Webrazzi gibi bir çok yerli haber ve teknoloji sitelerinde ve Yahoo Finance, Business Wire gibi yabancı sitelerde yer aldı.

turkcell-gelecegi-yazanlar-maratonu

 

Turkcell’in organize ettiği Silikon Vadisi turumuza 1 Kasım’da başlıyor olacağız. Hem Turkcell’in networkünde olan şirketlere Bozuk Yol’u anlatmayı hem de fırsat bulabilirsek San Francisco’yu ve  Los Angeles’ı, San Diego taraflarını gezmeyi istiyoruz.

Posted in General | Comments Off

Unutulan Android-Keystore (.keystore .jks) dosyasının şifresini bulmak

Posted by Mustafa Ferhan Akman on August 16th, 2014

Geçtiğimiz günlerde geliştirdiğim bir uygulamanın KeyStore şifresini kaybettim:) ilk defa başıma böyle birşey geldi. Aslında tam bir kaybetme sayılmaz, elimde keystore dosyamın şifresi var fakat yanlış:)

Şifre ile ilgili farklı kombinasyonlar denemiş olsam da, bir türlü bulamadım. Android Studio’da, apk sign ederken 1 kez master şifre belirledikten sonra her defasında tekrar tekrar şifre girmenize gerek kalmıyor. Android Studio ilgili keystore şifresini kendi bünyesinde saklıyor. Fakat benim durumunda, ilgili master şifrem elimde olmasına rağmen, Android Studio’yu update ettikten sonra keystore şifremi hatırlamamaya başlamasıydı. Doğal olarak ben de keystore şifemi elle girmeye çalıştım ve elimdeki şifremin hatalı olduğunu anladım.

Screen Shot 2014-08-16 at 13.47.53

Kombinasyonlar sonucunda şifremi elde edemediğim için ümitlerim tükenirken Musa Ülker arkadaşımında yardımıyla şu yöntemleri izleyerek şifreme geri kavuştum.

Eğer master şifrenizi hatırlıyorsanız aşağıdaki adımları izleyerek şifrenizi öğrenebilirsiniz;

  1. Eğer Android Studio’da 1 kez bile şifrenizi store etmişsseniz, Android Studio tüm şifreleri security.xml dosyası içerisinde saklıyor
  2. Bu dosyanın yeri
    • MacOS için: ~/Library/Preferences/AndroidStudioPreview/options/security.xml
    • Linux için: ~/.AndroidStudioPreview/config/security.xml
    • Windows için: <User home>\.AndroidStudioPreview\config\security.xml
  3. security.xml dosyasına eriştikten sonra şifremizi öğrenebilmek için açık kaynak kodlu intellij-decrypt isimli kütüphaneyi kullanacağız. Tüm repoyu indirmek istemiyorsanız yalnızca intellij-decrypt.jar dosyasını indirmeniz yeterli.
  4. Terminal'i, açarak aşağıdaki komutu çalıştırıyoruz.
    java -classpath .:intellij-decrypt.jar:lib/commons-codec-1.9.jar org.corneliudascalu.intellijdecrypt.Main -f security.xml -p &lt;MASTERŞİFRESİ&gt;
  5. Ve işte şifrelerimiz

sifreler

 

Tags: , , , , , ,
Posted in Android | 4 Comments »

Bilkent ve UKÜ'deydim

Posted by Mustafa Ferhan Akman on August 16th, 2014

Geçtiğimiz cheap canadian viagra günlerde Bilkent Üniversitesi’nin düzenlediği Mobil günler ve kendi mezun olduğum; Uluslararası Kıbrıs Üniversitesi’nin düzenlemiş olduğu Mobil Trendler eetkinliklerinde Android’de gelir etme üzerine yaşadığım tecrübelerimi ve yaklaşık 3 ay süren bir cheap canadian viagra kullanıcı&gelir testimin sonuçlarını paylaştım.

uku-seminer uku2

 

 

Posted in Android | Comments Off

Google'ın düzenlemiş olduğu Grow your App Business etkinliğindeydik

Posted by Mustafa Ferhan Akman on August 16th, 2014

Sefa ile birlikte Google’ın İstanbul’daki Grow your App Business with Google etkinliğindeydik. Genel olarak güzel bir etkinlikti, özellikle Google Analytics ve AppEngine ile ilgili http://www.viagrabelgiquefr.com/ sunumlar etkileyiciydi.

google1

Posted in Android | Comments Off

Türkiye için bir OS versiyon istatistiği

Posted by Mustafa Ferhan Akman on June 29th, 2014

17bin aktif kullanıcısı olan ve sadece Türk vatandaşlarını hedef alan bir uygulamamın OS bazında buy viagra online dağılımı;

(kullanıcıların %80′i Türkiye’den)

Türkiye Android version dağılımı

Posted in Android | Comments Off

BozukYol.com Yayında!

Posted by Mustafa Ferhan Akman on June 12th, 2014

BozukYol, 2 yıl önce sadece bir fikirdi.

Musa ve Süleyman ile birlikte geliştirdiğimiz BozukYol, bir kaç hafta önce Turkcell app markette yayınlandı. Uygulama Maratonu yarışması kapsamında dereceye girdi. Şimdi ise yeni özellikler ile Google Play‘de!

BozukYol’dan kısaca bahsedecek olursam, yollarda giderken cheap cialis online karşılaştığımız yol bozukluklarını otomatik olarak track ediyor, algoritmamız sayesinde onun bir yol bozukluğu olup olmadığını anlıyor ve farklı kullanıcılardan gelen dataları harmanladıktan sonra gerçek bir yol bozukluğu olup olmadığını anlayabiliyor. Sonrasında ise, twitter üzerinden ilgili belediyelere bildirip, düzeltilene kadar takipçisi oluyor.

Android uygulamasına ait bazı ekran görüntüleri;

device-2014-05-12-161324device-2014-05-12-161052   device-2014-06-12-163206

Yolda giderken, real-time analiz ekranını inceleyebiliyorsunuz.

device-2014-06-12-163607

 

Twitter http://tgwb.org/cheap-generic-cialis/ hesabınızla login olup, çeşitli badge kazanmaya başlayabiliyorsunuz. Çok yakın bir zamanda “gerçek ödüller” kazanabileceksiniz.

device-2014-06-12-163434

 

BozukYol’un gelişmiş bir çok özelliği bulunuyor.

  • Tamamen arkaplanda  çalışmak,
  • Yolda bozuk yol tespiti yaparken, çağrı gelmesi durumunda tespiti durdumak,
  • Uygulamayı arkaplanda unutmanız durumunda otomatik olarak uygulamayı duraklatmak,
  • İnternetsiz olarak yolları track edebilmek ve kablosuz ağa bağlandığınızda otomatik olarak senkronize etmek

gibi.

device-2014-06-12-163353

 

Turkcell’in düzenlediği ve dereceye giren uygulamaların basına tanıtıldığı toplantıdan bir kare;

buyuk

 

Uygulamamızın canlı demosuna ait bir video:

 

Yakın zamanda gelir modelimiz ile ilgili kurguladıklarımızı hayata geçirmeye ve kullanıcılarımıza ödüller/hediyeler vermeye başlıyor olacağız.

Uygulamayı indirmek için;

https://play.google.com/store/apps/details?id=com.bozukyol

Türkiye’nin bozuk yol haritası için;

Screen Shot 2014-06-13 at 10.16.26

http://www.bozukyol.com

 

Posted in Android | Comments Off

SourceTree aracını herhangi bir Git reposu ile kullanmak

Posted by Mustafa Ferhan Akman on March 19th, 2014

SourceTree mac üzerinde kullandığım en güzel git ve mercurial aracı. Command-line kullanmaya devam etmek istiyorsanız yazının geri kalanını okumak acheter cialis zorunda değilsiniz. Fakat ben basit işlerimi UI’dan halletmeyi seviyorum.

SourceTree resmi olarak bitbucket, github, stash’ı destekliyor. Fakat viagra prescription online mesela GitLab’ı eklemek istediğinizde çeşitli gıcıklıklar yapabiliyor. Bitbucket ve github repolarında olduğu gibi direkt olarak eklenemiyor  ama aşağıdaki adımlarla problem çözülüyor.

1- gitlab’da mevcut olan git repo’yu command-line’dan çekiyoruz.

2- SourTree’de    Add Repo -> Add Working Copy -> projemizin git klasörünü seçiyoruz

3- Eklediğimiz repo’yu açıp,

Settings -> Edit Config File  dedikten gitlab’daki user’ımızı eklememiz gerekiyor. (bazı durumlarda)

[user]
name = Mustafa Ferhan Akman
email = mustafa.ferhan.akman@eba.gov.tr

gibi. Bu kadar.

Posted in General | Comments Off

Android DebugLog [GitHub]

Posted by Mustafa Ferhan Akman on March 5th, 2014

Yakın zamanda MFCalendarView isimli kütüphaneyi github’da paylaştığımı aktarmıştım. Şimdi, yaklaşık 2 yıldır kullandığım, çok işime yarayan ve geçmişte yaşadığım tecrübelere dayanarak hazırladığım bir kütüphane var: DebugLog.

Neden DebugLog?

DebugLog kütüphanesinin 2 temel amacı var;

  1. Uygulama geliştirilirken DebugLog aracılığı ile yazdığımız tüm logları App release edildiğimde otomatik buy viagra olarak kapatmak.
  2. DDMS’e otomatik olarak daha anlaşılabilir log kayıtları düşmek.

DebugLog ile uygulama geliştirirken herhangi bir log düşmek için sadece mesajınızı yazmanız yeterli;

<br />
 DebugLog.e(message);<br />

Mesela, aşağıdaki gibi myFunc() isimli fonksiyonun içerisinde DebugLog’u kullanırsanız,

<br />
void myFunc(){<br />
   DebugLog.e(simple log from myFunc());<br />
}<br />

DebugLog aşağıdaki gibi, Tag kısmına log’un yazıldğı class ismini, log mesajının başına parantez içerisinde fonksiyonun ismini otomatik olarak yazar.

DebugLog output

Veya örnek olarak başka bir fonksiyonun içerisindeyken;

DebugLog output

android.util.Log‘un desteklediği tüm formatlarda DebugLog’u kullanabilirsiniz:

<br />
DebugLog.e(log);<br />
DebugLog.i(i log);<br />
DebugLog.d(d log);<br />
DebugLog.v(v log);<br />
DebugLog.w(w log);<br />
DebugLog.wtf(wtf log);<br />

Kaynak kodlarına ve örnek uygulamaya https://github.com/MustafaFerhan/DebugLog adresinden ulaşabilirsiniz.

Posted in Android | Comments Off

 
canakkale canakkale canakkale truva search canakkale vergi mevzuati bagimsiz denetim bagimsiz denetim web security ozurluler bilisim teknoloji sgk bagimsiz denetim bagimsiz denetim