Android 13’e geçiş (API 33)

Bildiğiniz üzere 10 Şubat 2022’de Android 13 duyuruldu. Bu haberin ardından hepimiz uygulamalarımızı en son sürüme güncellemek için kollarımızı sıvadık. Elbette Google’da bu sırada boş durmuyor ve sürekli kütüphanelerini yeniliyor. Eski sürüm kod kitaplıklarına artık destek verilmediği için, kodlarınızı güncel tutmanız son derece önemli.

Eğer sizde şu projemi bir güncelleyeyim deyip, o tozlu rafların arasından eski bir projeyi Android Studio‚da açmaya çalıştıysanız muhtemelen pek çok hatayla karşılaştınız. Çözmek için internete başvurduğunuzda da onca içerik arasından buraya, ta benim bloguma kadar geldiğiniz. 😊

Öyleyse gelin hataları adım adım çözelim.

Jetifier Nedir?

Jetifier, AndroidX’i kullanmak için üçüncü taraf bağımlılıklarının taşınmasına yardımcı olur. Jetifier, AndroidX kullanan projelerle uyumlu hale getirmek için bu bağımlılıkların bayt kodunu değiştirir. Ancak Jetifier kaynak kodunuzu değiştirmez veya oluşturulan kodunuzu taşımaz.

Bu yüzden bazı işlemleri manuel olarak, kendimiz yapmalıyız. Öncelikle:

Uygulamanızda Jetifier’ı etkinleştirmek için gradle.properties dosyanıza şu iki satırı ekleyin :

android.useAndroidX=true
android.enableJetifier=true
Java

Proje düzeyinde build.gradle (Project: UygulamaAdı) dosyanızı kontrol edin; (şuna benzer şekilde olmalı)

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:7.3.1'  // Güncel gradle sürümü
        classpath 'com.google.gms:google-services:4.3.10' // Google Hizmetleri
        classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.0' // Firebase Hata Bildirimleri
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}
Java

Uygulama düzeyinde build.gradle (Module: UygulamaAdi.app) dosyanızın da bi‘ gözden geçmesi gerek; Dikkat ! Ciddi hatalardan kaçınmak için tüm kodu kendi projenize kopyalamayın, sadece gerekli alanları güncelleyin.

apply plugin: 'com.android.application'

android {
    compileSdkVersion 33
    buildToolsVersion "33.0.0"
    defaultConfig {
        applicationId "com.paketadi.ornekuygulama"
        minSdkVersion 19
        targetSdkVersion 33
        versionCode 1
        versionName "v1.0.0"
        multiDexEnabled true
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            shrinkResources true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        targetCompatibility JavaVersion.VERSION_11
        sourceCompatibility JavaVersion.VERSION_11
    }
    namespace 'com.paketadi.ornekuygulama'
    ndkVersion '24.0.8215888'
}

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    // Android X
    implementation 'androidx.appcompat:appcompat:1.4.2'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    implementation 'androidx.core:core:1.9.0-alpha05'

    implementation "com.google.android.gms:play-services-games-v2:+"        // Google Play Game services
    implementation 'com.google.android.gms:play-services-location:19.0.1'
    implementation 'com.google.android.gms:play-services-ads:21.0.0'        // Google Mobile Ads
    implementation 'com.google.android.gms:play-services-plus:17.0.0'       // Google+
    implementation 'com.google.android.gms:play-services-auth:20.2.0'      // Google Account Login
    implementation 'com.google.android.gms:play-services-base:18.0.1'      // Google Actions, Base Client Library
    implementation 'com.google.android.gms:play-services-identity:18.0.1'  // Google Address API
    implementation 'com.google.android.gms:play-services-nearby:18.2.0'    // Google Nearby

    // Firebase
    implementation platform('com.google.firebase:firebase-bom:30.1.0')
    implementation 'com.google.firebase:firebase-analytics'
    implementation 'com.google.firebase:firebase-crashlytics'

    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'

Java

Eğer daha önce projenizde „FirebaseCrash“ kullandıysanız, burdada bi‘ takım değişikler oldu. Gelin bakalım;

(Eğer ilk defa duydum o ne diyorsanız bir sonraki adıma geçebilirsiniz 🙂 )

// Eski kullanım
FirebaseCrash.logcat(Log.ERROR, getString(R.string.app_name), "Hata Mesaji.");
FirebaseCrash.report(ex);

// Yeni kullanım
FirebaseCrashlytics.getInstance().log("Hata Mesaji");
Java

Tabi Google Sign In için kullandığımız sınıflar da, siz ortalıkta yokken değişti.

Eskiden şu şekilde tanımlıyorduk;

//-----------------API Ayarı---------------------------------
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(Games.API).addScope(Games.SCOPE_GAMES)
                .build();
//----------------------------------------------------------
Java

Bu sınıf tamamen kullanımdan kaldırıldı. Bunun yerine artık PlayGamesSdk’sını kullanacağız. Önce kütüphanelerimizi ekleyelim;

import com.google.android.gms.games.PlayGames;
import com.google.android.gms.games.PlayGamesSdk;
Java

Şimdi onCreate() metodunuzun içerisine şu kod bloğunu ekleyebilirsiniz.

        //-----------------Google Play Games---------------------------------
        PlayGamesSdk.initialize(this);
        GamesSignInClient gamesSignInClient = PlayGames.getGamesSignInClient(this);
        gamesSignInClient.isAuthenticated().addOnCompleteListener(isAuthenticatedTask -> {
            boolean isAuthenticated = (isAuthenticatedTask.isSuccessful() && isAuthenticatedTask.getResult().isAuthenticated());
            if (isAuthenticated) {
                Log.d(TAG, "isAuthenticated : true => Giriş zaten yapıldı !");
                //...
            } else {
                // Play Games Hizmetleriyle entegrasyonunuzu devre dışı bırakın veya
                // oyunculardan oturum açmalarını istemek için bir oturum açma düğmesi gösterin.
                // Üzerine tıklamak, Oyun Oturum Açma İstemcisini çağırmalıdır.
                Log.e(TAG, "isAuthenticated : false => Oturum açılıyor..");
                gamesSignInClient.signIn().addOnSuccessListener(this);
            }
        });
Java

Şimdi nihayet Play Games Hizmetlerini kullanabiliriz, ancak hala başarım kilidi açma (Achievements) ve skor tablosunu (Leaderboard) nasıl göstereceğimizi çözmemiz gerekiyor. Hatırlarsanız önceden başarımlar ekranını açmak için şöyle yapıyorduk;

if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
        startActivityForResult(Games.Achievements.getAchievementsIntent(mGoogleApiClient), REQUEST_ACHIEVEMENTS);
} else {
        Toast.makeText(getApplicationContext(), R.string.signin_not, Toast.LENGTH_LONG).show();
}
Java

Tahmin edebileceğiniz gibi artık bu yöntem işe yaramayacaktır. Bunun yerine bir showAchievements() isimli bir metot oluşturalım;

    public void showAchievements() {
        PlayGames.getAchievementsClient(this)
                .getAchievementsIntent()
                .addOnSuccessListener(new OnSuccessListener<Intent>() {
                    @Override
                    public void onSuccess(Intent intent) {
                        startActivityForResult(intent, RC_ACHIEVEMENT_UI);
                    }
                });
    }
Java

İşte oldu! Göstermek istediğiniz butonun Click event’inde çağırmanız yeterli olacaktır.

Şimdi sırada skor tablosunu yani Leaderboard‚ı kullanıcıya göstermek var. Önce eski günleri yad edmek için şu kod satırını bulalım;

startActivityForResult(Games.Leaderboards.getAllLeaderboardsIntent(mGoogleApiClient), REQUEST_LEADERBOARD);
Java

Evet bulduğumuza göre, vedalaşın (silin) ve yerine showLeaderboard(); metodunu çağıralım.

Çağırdık ama kimse gelmedi. 😅 Öyleyse bu metodun kodlarını da yazalım.

    private void showLeaderboard() {
        PlayGames.getLeaderboardsClient(this)
                .getLeaderboardIntent(getString(R.string.leaderboard))
                .addOnSuccessListener(new OnSuccessListener<Intent>() {
                    @Override
                    public void onSuccess(Intent intent) {
                        startActivityForResult(intent, RC_LEADERBOARD_UI);
                    }
                }).addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Log.e(TAG, "showLeaderboard() => " + e);
                        crashlytics.recordException(e);
                    }
                });
    }
Java

Buraya kadar hazırız. Sıra geldi başarımlara. Bir olay gerçekleştiğinde kullanıcımıza nasıl başarım açarız?

// Eski kullanım
Games.Achievements.unlock(mGoogleApiClient, getString(R.string.achievement_vote_us));

// Yeni kullanım
PlayGames.getAchievementsClient(this).unlock(getString(R.string.achievement_vote_us));
Java

Bu oldukça kolaydı. Bazı başarımlarsa direk açılmaz, ulaşılması gerekilen hedefler vardır.

Bunlara artırımlı başarımlar denir ve peki uzatmıyorum işte kodlarımız;

// Eski kullanım
Games.Achievements.increment(MainActivity.mGoogleApiClient, getString(R.string.achievement_x), turSayisi);

// Yeni kullanım
PlayGames.getAchievementsClient(this).increment(getString(R.string.achievement_x), turSayisi);
Java

Oyun bittiğinde kullanıcının oyundaki skorunu güncellemeniz gerekir. Örneğin kullanıcımız yeni bir „High Score“ yaptığında bunu Play Games sunucularında da güncellemeliyiz. Hadi buna da hızlıca bi‘ bakalım;

// Eski kullanım
Games.Leaderboards.submitScore(MainActivity.mGoogleApiClient, getString(R.string.leaderboard_kolay), turSayisi);

// Yeni kullanım
PlayGames.getLeaderboardsClient(this).submitScore(getString(R.string.leaderboard_kolay), turSayisi);
Java

Evet Google Play Game Services ’ne yeniden kavuşmuş olduk. Hepsi bu kadardı.

Gelelim Google AdSense ayarlarımıza, biraz yorulduk farkındayım. Fakat çok az kaldı.

Eski kodumuz muhtemelen şu şekildeydi;

        // ----------------- Google AdSense ---------------------
        AdView adView = (AdView) this.findViewById(R.id.adView);
        AdRequest adRequest = new AdRequest.Builder()
                .addTestDevice("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
                .addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
                .build();
        if (adView != null) {
            adView.loadAd(adRequest);
        }
Java

Yeni kodumuz ise şu şekilde olacak;

    try {
        mAdView = findViewById(R.id.adView);
        configuration = new RequestConfiguration.Builder().setTestDeviceIds(Arrays.asList(testDeviceIds)).build();
        MobileAds.setRequestConfiguration(configuration);
        MobileAds.initialize(this, new OnInitializationCompleteListener() {
            @Override
            public void onInitializationComplete(InitializationStatus initializationStatus) {
                Log.d(TAG, "MobileAds => onInitializationComplete()");
                mAdView.setAdSize(AdSize.BANNER);
                mAdView.setAdUnitId("ca-app-pub-XXXXXXXXXXXXXXXX/XXXXXXXXXX");
                adRequest = new AdRequest.Builder().build();
                mAdView.loadAd(adRequest);
            }
        });
    } catch (Exception ex) {
        Log.e(TAG, "Google AdSense => " + ex);
        crashlytics.recordException(ex);
    }
Java

Burda şunlara dikkat etmeniz gerekiyor. Aksi takdirde Google AdMob üyeliğiniz feshedilebilir veya askıya alınabilir.

  1. Google AdMob hesabınıza giriş yapın.
  2. Sol taraftaki menüden Ayarlar -> Test cihazları alanına gidin.
  3. Test Cihazı Ekle butonuna tıklayın.
  4. Formu eksiksiz doldurun.
  5. Tüm emulatörleriniz veya test cihazlarınız için aynı işlemi tekrarlayın.

Google AdMob hakkında daha fazla bilgi için, Google AdMob yazımı inceleyebilirsiniz.

Evet sonunda bitti. 🎉 Yukarıda ki tüm ayarları uyguladığınız halde hâlâ hata alıyorsanız, eski ve yeni sürümü kontrol edebilmeniz için aşağıya bir tablo bırakıyorum. Yapmanız gereken CTRL + R tuşlarına basarak eski kodları yenisi ile değiştirmek.

Android (Eski)Android X
import android.support.v7.app.AppCompatActivity;import androidx.appcompat.app.AppCompatActivity;
import android.support.v4.app.Fragment;import androidx.fragment.app.Fragment;
import android.support.annotation.NonNull;import androidx.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;import com.google.android.material.bottomnavigation.BottomNavigationView;
import android.arch.lifecycle.ViewModelProvider;import androidx.lifecycle.ViewModelProvider;
dependencies
compile fileTree(dir: ‚libs‘, include: [‚*.jar‘])implementation fileTree(dir: „libs“, include: [„*.jar“])
compile ‚com.android.support.constraint:constraint-layout:2.0.4‘implementation ‚androidx.constraintlayout:constraintlayout:2.1.4‘
compile ‚com.android.support:appcompat-v7:25.3.1‘implementation ‚androidx.appcompat:appcompat:1.4.2‘
testCompile ‚junit:junit:4.12‘testImplementation ‚junit:junit:4.13.2‘
Tablo Android X – Sınıflar ve Kütüphaneler

Buraya kadar okuduğunuz ve benimle kaldığınız için teşekkür ederim.

👋 Tekrar görüşmek üzere, hoşçakalın.

administrator

Leave A Comment