Uygulamanızın güvenliğini iyileştirin

Uygulamanızı daha güvenli hale getirerek kullanıcı güvenini ve cihaz bütünlüğünü korumaya yardımcı olursunuz.

Bu sayfada, uygulamanızın güvenliği üzerinde önemli ve olumlu etkisi olan birkaç en iyi uygulama sunulmaktadır.

Güvenli iletişimi zorunlu kılma

Uygulamanız ile diğer uygulamalar veya uygulamanız ile bir web sitesi arasında paylaştığınız verilerin güvenliğini sağladığınızda uygulamanızın kararlılığını artırır, gönderdiğiniz ve aldığınız verileri korursunuz.

Uygulamalar arasındaki iletişimi koruma

Uygulamalar arasında daha güvenli bir şekilde iletişim kurmak için uygulama seçici, imza tabanlı izinler ve dışa aktarılmayan içerik sağlayıcılarla örtülü intent'ler kullanın.

Uygulama seçici gösterme

Örtük bir intent, kullanıcının cihazında en az iki olası uygulamayı başlatabiliyorsa açıkça bir uygulama seçici gösterin. Bu etkileşim stratejisi, kullanıcıların hassas bilgileri güvendikleri bir uygulamaya aktarmalarına olanak tanır.

Kotlin

val intent = Intent(Intent.ACTION_SEND)
val possibleActivitiesList: List<ResolveInfo> =
        packageManager.queryIntentActivities(intent, PackageManager.MATCH_ALL)

// Verify that an activity in at least two apps on the user's device
// can handle the intent. Otherwise, start the intent only if an app
// on the user's device can handle the intent.
if (possibleActivitiesList.size > 1) {

    // Create intent to show chooser.
    // Title is something similar to "Share this photo with."

    <b>val chooser = resources.getString(R.string.chooser_title).let { title ->
        Intent.createChooser(intent, title)
    }
    startActivity(chooser)</b>
} else if (intent.resolveActivity(packageManager) != null) {
    startActivity(intent)
}

Java

Intent intent = new Intent(Intent.ACTION_SEND);
List&lt;ResolveInfo&gt; possibleActivitiesList = getPackageManager()
        .queryIntentActivities(intent, PackageManager.MATCH_ALL);

// Verify that an activity in at least two apps on the user's device
// can handle the intent. Otherwise, start the intent only if an app
// on the user's device can handle the intent.
if (possibleActivitiesList.size() > 1) {

    // Create intent to show chooser.
    // Title is something similar to "Share this photo with."

    <b>String title = getResources().getString(R.string.chooser_title);
    Intent chooser = Intent.createChooser(intent, title);
    startActivity(chooser);</b>
} else if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(intent);
}

İlgili bilgiler:

İmzaya dayalı izinleri uygulama

Kontrol ettiğiniz veya sahibi olduğunuz iki uygulama arasında veri paylaşırken imza tabanlı izinleri kullanın. Bu izinler kullanıcı onayı gerektirmez. Bunun yerine, verilere erişen uygulamaların aynı imzalama anahtarı kullanılarak imzalanıp imzalanmadığını kontrol eder. Bu nedenle, bu izinler daha akıcı ve güvenli bir kullanıcı deneyimi sunar.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">
    <permission android:name="my_custom_permission_name"
                android:protectionLevel="signature" />

İlgili bilgiler:

Uygulamanızın içerik sağlayıcılarına erişimi engelleme

Uygulamanızdan size ait olmayan farklı bir uygulamaya veri göndermeyi planlamıyorsanız diğer geliştiricilerin uygulamalarının, uygulamanızın ContentProvider nesnelerine erişmesine açıkça izin vermeyin. Uygulamanız Android 4.1.1 (API düzeyi 16) veya daha eski sürümleri çalıştıran cihazlara yüklenebiliyorsa bu ayar özellikle önemlidir. Çünkü <provider> öğesinin android:exported özelliği, Android'in bu sürümlerinde varsayılan olarak true değerine sahiptir.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">
    <application ... >
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.example.myapp.fileprovider"
            ...
            android:exported="false">
            <!-- Place child elements of <provider> here. -->
        </provider>
        ...
    </application>
</manifest>

Hassas bilgileri göstermeden önce kimlik bilgilerini sorma

Uygulamanızdaki hassas bilgilere veya premium içeriğe erişebilmeleri için kullanıcılardan kimlik bilgisi isterken PIN/şifre/desen ya da yüz tanıma veya parmak izi tanıma gibi biyometrik kimlik bilgisi isteyin.

Biyometrik kimlik bilgisi isteme hakkında daha fazla bilgi edinmek için biyometrik kimlik doğrulama ile ilgili kılavuzu inceleyin.

Ağ güvenliği önlemleri uygulama

Aşağıdaki bölümlerde, uygulamanızın ağ güvenliğini nasıl iyileştirebileceğiniz açıklanmaktadır.

TLS trafiğini kullanma

Uygulamanız, iyi bilinen ve güvenilir bir sertifika yetkilisi (CA) tarafından verilmiş sertifikaya sahip bir web sunucusuyla iletişim kuruyorsa aşağıdaki gibi bir HTTPS isteği kullanın:

Kotlin

val url = URL("https://www.google.com")
val urlConnection = url.openConnection() as HttpsURLConnection
urlConnection.connect()
urlConnection.inputStream.use {
    ...
}

Java

URL url = new URL("https://www.google.com");
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.connect();
InputStream in = urlConnection.getInputStream();

Ağ güvenliği yapılandırması ekleme

Uygulamanız yeni veya özel CA'lar kullanıyorsa ağınızın güvenlik ayarlarını bir yapılandırma dosyasında beyan edebilirsiniz. Bu işlem, herhangi bir uygulama kodunu değiştirmeden yapılandırmayı oluşturmanıza olanak tanır.

Uygulamanıza ağ güvenliği yapılandırma dosyası eklemek için aşağıdaki adımları uygulayın:

  1. Uygulamanızın manifest dosyasında yapılandırmayı beyan edin:
  2. <manifest ... >
        <application
            android:networkSecurityConfig="@xml/network_security_config"
            ... >
            <!-- Place child elements of <application> element here. -->
        </application>
    </manifest>
  3. res/xml/network_security_config.xml konumunda bulunan bir XML kaynak dosyası ekleyin.

    Düz metni devre dışı bırakarak belirli alanlara giden tüm trafiğin HTTPS kullanması gerektiğini belirtin:

    <network-security-config>
        <domain-config cleartextTrafficPermitted="false">
            <domain includeSubdomains="true">secure.example.com</domain>
            ...
        </domain-config>
    </network-security-config>

    Geliştirme sürecinde, kullanıcı tarafından yüklenen sertifikalara açıkça izin vermek için <debug-overrides> öğesini kullanabilirsiniz. Bu öğe, uygulamanın sürüm yapılandırmasını etkilemeden hata ayıklama ve test sırasında uygulamanızın güvenlikle ilgili kritik seçeneklerini geçersiz kılar. Aşağıdaki snippet'te, bu öğenin uygulamanızın ağ güvenliği yapılandırması XML dosyasında nasıl tanımlanacağı gösterilmektedir:

    <network-security-config>
        <debug-overrides>
            <trust-anchors>
                <certificates src="user" />
            </trust-anchors>
        </debug-overrides>
    </network-security-config>

İlgili bilgiler: Ağ güvenliği yapılandırması

Kendi güven yöneticinizi oluşturma

TLS denetleyiciniz her sertifikayı kabul etmemelidir. Kullanım alanınız için aşağıdaki koşullardan biri geçerliyse bir güven yöneticisi oluşturmanız ve ortaya çıkan tüm TLS uyarılarını ele almanız gerekebilir:

  • Yeni veya özel bir CA tarafından imzalanmış sertifikası olan bir web sunucusuyla iletişim kuruyorsunuz.
  • Bu CA, kullandığınız cihaz tarafından güvenilir olarak kabul edilmiyor.
  • Ağ güvenliği yapılandırması kullanamazsınız.

Bu adımların nasıl tamamlanacağı hakkında daha fazla bilgi edinmek için bilinmeyen sertifika yetkilisi ile ilgili tartışmaya bakın.

İlgili bilgiler:

WebView nesnelerini dikkatli kullanma

Uygulamanızdaki WebView nesneleri, kullanıcıların kontrolünüz dışındaki sitelere gitmesine izin vermemelidir. Mümkün olduğunda, uygulamanızın WebView nesneleri tarafından yüklenen içeriği kısıtlamak için bir izin verilenler listesi kullanın.

Ayrıca, uygulamanızın WebView nesnelerindeki içeriği tamamen kontrol etmediğiniz ve bu içeriğe güvenmediğiniz sürece JavaScript arayüzü desteğini hiçbir zaman etkinleştirmeyin.

HTML mesaj kanallarını kullanma

Uygulamanızın Android 6.0 (API düzeyi 23) ve sonraki sürümleri çalıştıran cihazlarda JavaScript arayüzü desteğini kullanması gerekiyorsa bir web sitesi ile uygulamanız arasında iletişim kurmak yerine aşağıdaki kod snippet'inde gösterildiği gibi HTML mesaj kanallarını kullanın:

Kotlin

val myWebView: WebView = findViewById(R.id.webview)

// channel[0] and channel[1] represent the two ports.
// They are already entangled with each other and have been started.
val channel: Array&lt;out WebMessagePort&gt; = myWebView.createWebMessageChannel()

// Create handler for channel[0] to receive messages.
channel[0].setWebMessageCallback(object : WebMessagePort.WebMessageCallback() {

    override fun onMessage(port: WebMessagePort, message: WebMessage) {
        Log.d(TAG, "On port $port, received this message: $message")
    }
})

// Send a message from channel[1] to channel[0].
channel[1].postMessage(WebMessage("My secure message"))

Java

WebView myWebView = (WebView) findViewById(R.id.webview);

// channel[0] and channel[1] represent the two ports.
// They are already entangled with each other and have been started.
WebMessagePort[] channel = myWebView.createWebMessageChannel();

// Create handler for channel[0] to receive messages.
channel[0].setWebMessageCallback(new WebMessagePort.WebMessageCallback() {
    @Override
    public void onMessage(WebMessagePort port, WebMessage message) {
         Log.d(TAG, "On port " + port + ", received this message: " + message);
    }
});

// Send a message from channel[1] to channel[0].
channel[1].postMessage(new WebMessage("My secure message"));

İlgili bilgiler:

Doğru izinleri verme

Uygulamanızın düzgün çalışması için yalnızca gereken minimum sayıda izin isteyin. Mümkün olduğunda, uygulamanızın artık ihtiyaç duymadığı izinleri iptal edin.

İzinleri ertelemek için intent'leri kullanma

Mümkün olduğunda, başka bir uygulamada tamamlanabilecek bir işlemi tamamlamak için uygulamanıza izin eklemeyin. Bunun yerine, isteği gerekli izne sahip farklı bir uygulamaya ertelemek için bir intent kullanın.

Aşağıdaki örnekte, kullanıcıları READ_CONTACTS ve WRITE_CONTACTS izinlerini istemek yerine bir Kişiler uygulamasına yönlendirmek için intent'in nasıl kullanılacağı gösterilmektedir:

Kotlin

// Delegates the responsibility of creating the contact to a contacts app,
// which has already been granted the appropriate WRITE_CONTACTS permission.
Intent(Intent.ACTION_INSERT).apply {
    type = ContactsContract.Contacts.CONTENT_TYPE
}.also { intent ->
    // Make sure that the user has a contacts app installed on their device.
    intent.resolveActivity(packageManager)?.run {
        startActivity(intent)
    }
}

Java

// Delegates the responsibility of creating the contact to a contacts app,
// which has already been granted the appropriate WRITE_CONTACTS permission.
Intent insertContactIntent = new Intent(Intent.ACTION_INSERT);
insertContactIntent.setType(ContactsContract.Contacts.CONTENT_TYPE);

// Make sure that the user has a contacts app installed on their device.
if (insertContactIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(insertContactIntent);
}

Ayrıca, uygulamanızın depolama alanına erişme veya dosya seçme gibi dosya tabanlı G/Ç işlemleri yapması gerekiyorsa sistem bu işlemleri uygulamanız adına tamamlayabildiğinden özel izinlere gerek yoktur. Daha da iyisi, kullanıcı belirli bir URI'deki içeriği seçtikten sonra, arayan uygulamaya seçilen kaynak için izin verilir.

İlgili bilgiler:

Uygulamalar arasında güvenli veri paylaşımı

Uygulamanızın içeriğini diğer uygulamalarla daha güvenli bir şekilde paylaşmak için aşağıdaki en iyi uygulamaları izleyin:

Aşağıdaki kod snippet'i, bir uygulamanın PDF dosyasını ayrı bir PDF görüntüleyici uygulamasında görüntülemek için URI izni verme işaretlerinin ve içerik sağlayıcı izinlerinin nasıl kullanılacağını gösterir:

Kotlin

// Create an Intent to launch a PDF viewer for a file owned by this app.
Intent(Intent.ACTION_VIEW).apply {
    data = Uri.parse("<b>content:</b>//com.example/personal-info.pdf")

    // This flag gives the started app read access to the file.
    <b>addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)</b>
}.also { intent ->
    // Make sure that the user has a PDF viewer app installed on their device.
    intent.resolveActivity(packageManager)?.run {
        startActivity(intent)
    }
}

Java

// Create an Intent to launch a PDF viewer for a file owned by this app.
Intent viewPdfIntent = new Intent(Intent.ACTION_VIEW);
viewPdfIntent.setData(Uri.parse("<b>content://</b>com.example/personal-info.pdf"));

// This flag gives the started app read access to the file.
<b>viewPdfIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);</b>

// Make sure that the user has a PDF viewer app installed on their device.
if (viewPdfIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(viewPdfIntent);
}

Not: Yazılabilir uygulama ana dizininden dosya yürütmek W^X ihlalidir. Bu nedenle, Android 10 (API düzeyi 29) ve sonraki sürümleri hedefleyen güvenilmeyen uygulamalar, uygulamanın ana dizinindeki dosyalarda exec() işlevini çağıramaz. Bu işlev yalnızca uygulamanın APK dosyasına yerleştirilmiş ikili kodda çağrılabilir. Ayrıca, Android 10 ve sonraki sürümleri hedefleyen uygulamalar, dlopen() ile açılan dosyalardaki yürütülebilir kodu bellekte değiştiremez. Metin yer değiştirmeleri içeren tüm paylaşılan nesne (.so) dosyaları buna dahildir.

İlgili bilgiler: android:grantUriPermissions

Verileri güvenli bir şekilde depolama

Uygulamanızın hassas kullanıcı bilgilerine erişmesi gerekebilir ancak kullanıcılar, verilerini düzgün bir şekilde koruyacağınıza güvenirlerse uygulamanızın verilerine erişmesine izin verirler.

Özel verileri dahili depolama alanında saklama

Tüm özel kullanıcı verilerini, her uygulama için korumalı alana alınmış olan cihazın dahili depolama alanında saklayın. Uygulamanızın bu dosyaları görüntülemek için izin istemesi gerekmez ve diğer uygulamalar dosyalara erişemez. Ek bir güvenlik önlemi olarak, kullanıcı bir uygulamayı kaldırdığında cihaz, uygulamanın dahili depolama alanına kaydettiği tüm dosyaları siler.

Aşağıdaki kod snippet'i, dahili depolama alanına veri yazmanın bir yolunu gösterir:

Kotlin

// Creates a file with this name, or replaces an existing file
// that has the same name. Note that the file name cannot contain
// path separators.
val FILE_NAME = "sensitive_info.txt"
val fileContents = "This is some top-secret information!"
File(filesDir, FILE_NAME).bufferedWriter().use { writer ->
    writer.write(fileContents)
}

Java

// Creates a file with this name, or replaces an existing file
// that has the same name. Note that the file name cannot contain
// path separators.
final String FILE_NAME = "sensitive_info.txt";
String fileContents = "This is some top-secret information!";
try (BufferedWriter writer =
             new BufferedWriter(new FileWriter(new File(getFilesDir(), FILE_NAME)))) {
    writer.write(fileContents);
} catch (IOException e) {
    // Handle exception.
}

Aşağıdaki kod snippet'i, dahili depolama alanından veri okuma işlemini gösterir:

Kotlin

val FILE_NAME = "sensitive_info.txt"
val contents = File(filesDir, FILE_NAME).bufferedReader().useLines { lines ->
    lines.fold("") { working, line ->
        "$working\n$line"
    }
}

Java

final String FILE_NAME = "sensitive_info.txt";
StringBuffer stringBuffer = new StringBuffer();
try (BufferedReader reader =
             new BufferedReader(new FileReader(new File(getFilesDir(), FILE_NAME)))) {

    String line = reader.readLine();
    while (line != null) {
        stringBuffer.append(line).append('\n');
        line = reader.readLine();
    }
} catch (IOException e) {
    // Handle exception.
}

İlgili bilgiler:

Verileri kullanım alanına göre harici depolama alanında saklama

Uygulamanıza özel büyük, hassas olmayan dosyaların yanı sıra uygulamanızın diğer uygulamalarla paylaştığı dosyalar için harici depolama alanını kullanın. Kullandığınız API'ler, uygulamanızın uygulamaya özel dosyalara mı yoksa paylaşılan dosyalara mı erişecek şekilde tasarlandığına bağlıdır.

Bir dosya özel veya hassas bilgiler içermiyor ancak kullanıcıya yalnızca uygulamanızda değer sağlıyorsa dosyayı harici depolama alanındaki uygulamaya özel bir dizinde saklayın.

Uygulamanızın diğer uygulamalara değer katan bir dosyaya erişmesi veya bu dosyayı depolaması gerekiyorsa kullanım alanınıza bağlı olarak aşağıdaki API'lerden birini kullanın:

Depolama biriminin kullanılabilirlik durumunu kontrol etme

Uygulamanız çıkarılabilir bir harici depolama cihazıyla etkileşimde bulunuyorsa uygulamanız erişmeye çalışırken kullanıcının depolama cihazını çıkarabileceğini unutmayın. Depolama cihazının kullanılabilir olduğunu doğrulamak için mantık ekleyin.

Verilerin geçerliliğini kontrol etme

Uygulamanız harici depolama alanındaki verileri kullanıyorsa verilerin içeriğinin bozulmadığından veya değiştirilmediğinden emin olun. Artık kararlı biçimde olmayan dosyaları işlemek için mantık ekleyin.

Aşağıdaki kod snippet'inde bir karma doğrulayıcı örneği yer alır:

Kotlin

val hash = calculateHash(stream)
// Store "expectedHash" in a secure location.
if (hash == <var>expectedHash</var>) {
    // Work with the content.
}

// Calculating the hash code can take quite a bit of time, so it shouldn't
// be done on the main thread.
suspend fun calculateHash(stream: InputStream): String {
    return withContext(Dispatchers.IO) {
        val digest = MessageDigest.getInstance("SHA-512")
        val digestStream = DigestInputStream(stream, digest)
        while (digestStream.read() != -1) {
            // The DigestInputStream does the work; nothing for us to do.
        }
        digest.digest().joinToString(":") { "%02x".format(it) }
    }
}

Java

Executor threadPoolExecutor = Executors.newFixedThreadPool(4);
private interface HashCallback {
    void onHashCalculated(@Nullable String hash);
}

boolean hashRunning = calculateHash(inputStream, threadPoolExecutor, hash -&gt; {
    if (Objects.equals(hash, <var>expectedHash</var>)) {
        // Work with the content.
    }
});

if (!hashRunning) {
    // There was an error setting up the hash function.
}

private boolean calculateHash(@NonNull InputStream stream,
                              @NonNull Executor executor,
                              @NonNull HashCallback hashCallback) {
    final MessageDigest digest;
    try {
        digest = MessageDigest.getInstance("SHA-512");
    } catch (NoSuchAlgorithmException nsa) {
        return false;
    }

    // Calculating the hash code can take quite a bit of time, so it shouldn't
    // be done on the main thread.
    executor.execute(() -&gt; {
        String hash;
        try (DigestInputStream digestStream =
                new DigestInputStream(stream, digest)) {
            while (digestStream.read() != -1) {
                // The DigestInputStream does the work; nothing for us to do.
            }
            StringBuilder builder = new StringBuilder();
            for (byte aByte : digest.digest()) {
                builder.append(String.format("%02x", aByte)).append(':');
            }
            hash = builder.substring(0, builder.length() - 1);
        } catch (IOException e) {
            hash = null;
        }

        final String calculatedHash = hash;
        runOnUiThread(() -> hashCallback.onHashCalculated(calculatedHash));
    });
    return true;
}

Hassas önbellek verileri için dahili depolama alanını kullanma

Uygulama verilerine daha hızlı erişim sağlamak için verileri cihazın önbelleğinde saklayın. 1 MB veya daha küçük önbellekler için getCacheDir() kullanın. 1 MB'tan büyük önbellekler için getExternalCacheDir() kullanın. Her iki yöntem de uygulamanızın önbelleğe alınmış verilerini içeren File nesnesini sağlar.

Dahili önbellek dizini (getCacheDir() tarafından sağlanır) uygulamanıza özelken harici önbellek dizini özel değildir.

Aşağıdaki kod snippet'i, uygulamanızın yakın zamanda indirdiği bir dosyanın nasıl önbelleğe alınacağını gösterir:

Kotlin

val cacheFile = File(myDownloadedFileUri).let { fileToCache ->
    File(cacheDir.path, fileToCache.name)
}

Java

File cacheDir = getCacheDir();
File fileToCache = new File(myDownloadedFileUri);
String fileToCacheName = fileToCache.getName();
File cacheFile = new File(cacheDir.getPath(), fileToCacheName);

Not: Uygulamanızın önbelleğini paylaşılan depolama alanına yerleştirmek için getExternalCacheDir() kullanırsanız kullanıcı, uygulamanız çalışırken bu depolama alanını içeren medyayı çıkarabilir. Bu kullanıcı davranışının neden olduğu önbellekte yok durumunu düzgün bir şekilde ele alacak mantığı ekleyin.

Dikkat: Harici önbellek dizinindeki dosyalarda güvenlik uygulanmaz. Bu nedenle, Android 10 (API düzeyi 29) veya önceki sürümleri hedefleyen ve WRITE_EXTERNAL_STORAGE iznine sahip olan tüm uygulamalar bu önbelleğin içeriğine erişebilir.

İlgili bilgiler: Veri ve dosya depolamaya genel bakış

SharedPreferences'ı gizli modda kullanma

Uygulamanızın SharedPreferences nesnelerini oluşturmak veya bunlara erişmek için getSharedPreferences() kullanırken MODE_PRIVATE kullanın. Bu sayede, paylaşılan tercihler dosyasındaki bilgilere yalnızca uygulamanız erişebilir.

Uygulamalar arasında paylaşılan verileri paylaşmak istiyorsanız SharedPreferences nesnelerini kullanmayın. Bunun yerine, verileri uygulamalar arasında güvenli bir şekilde paylaşma adımlarını uygulayın.

İlgili bilgiler:

Hizmetleri ve bağımlılıkları güncel tutma

Çoğu uygulama, özel görevleri tamamlamak için harici kitaplıkları ve cihaz sistemi bilgilerini kullanır. Uygulamanızın bağımlılıklarını güncel tutarak bu iletişim noktalarını daha güvenli hale getirirsiniz.

Google Play Hizmetleri güvenlik sağlayıcısını kontrol etme

Not: Bu bölüm yalnızca Google Play Hizmetleri'nin yüklü olduğu cihazları hedefleyen uygulamalar için geçerlidir.

Uygulamanız Google Play Hizmetleri'ni kullanıyorsa uygulamanızın yüklü olduğu cihazda güncellendiğinden emin olun. Kontrolü, kullanıcı arayüzü iş parçacığından bağımsız olarak eşzamansız şekilde gerçekleştirin. Cihaz güncel değilse yetkilendirme hatası tetiklenir.

Uygulamanızın yüklü olduğu cihazda Google Play Hizmetleri'nin güncel olup olmadığını belirlemek için SSL açıklarına karşı koruma sağlamak için güvenlik sağlayıcınızı güncelleme ile ilgili kılavuzdaki adımları uygulayın.

İlgili bilgiler:

Tüm uygulama bağımlılıklarını güncelleme

Uygulamanızı dağıtmadan önce tüm kitaplıkların, SDK'ların ve diğer bağımlılıkların güncel olduğundan emin olun:

  • Android SDK gibi birinci taraf bağımlılıklar için Android Studio'da bulunan SDK Manager gibi güncelleme araçlarını kullanın.
  • Üçüncü taraf bağımlılıkları için uygulamanızın kullandığı kitaplıkların web sitelerini kontrol edin ve mevcut güncellemeleri ve güvenlik yamalarını yükleyin.

İlgili bilgiler: Derleme bağımlılıkları ekleme

Daha fazla bilgi

Uygulamanızı daha güvenli hale getirme hakkında daha fazla bilgi edinmek için aşağıdaki kaynakları inceleyin: