Veri erişimi denetimi yaparak uygulamanızın ve bağımlılıklarının kullanıcılardan gelen özel verilere nasıl eriştiği hakkında bilgi edinebilirsiniz. Android 11 (API düzeyi 30) ve sonraki sürümleri çalıştıran cihazlarda kullanılabilen bu işlem, beklenmedik veri erişimini daha iyi belirlemenizi sağlar. Uygulamanız, aşağıdaki etkinliklerden biri her gerçekleştiğinde işlem yapabilen bir AppOpsManager.OnOpNotedCallback
örneği kaydedebilir:
- Uygulamanızın kodu, özel verilere erişiyor. Uygulamanızın hangi mantıksal bölümünün etkinliği çağırdığını belirlemenize yardımcı olması için ilişkilendirme etiketiyle veri erişimini denetleyebilirsiniz.
- Bağımlı bir kitaplık veya SDK'daki kod, özel verilere erişiyor.
Veri erişimi denetimi, veri isteğinin gerçekleştiği iş parçacığında çağrılır. Bu, uygulamanızdaki bir üçüncü taraf SDK'sı veya kitaplığı, özel verilere erişen bir API'yi çağırırsa veri erişimi denetiminin OnOpNotedCallback
çağrı hakkındaki bilgileri incelemesine olanak tanıdığı anlamına gelir. Genellikle bu geri çağırma nesnesi, mevcut iş parçacığının yığın izi gibi uygulamanın mevcut durumuna bakarak çağrının uygulamanızdan mı yoksa SDK'dan mı geldiğini söyleyebilir.
Veri erişimini günlüğe kaydetme
AppOpsManager.OnOpNotedCallback
örneğini kullanarak veri erişimi denetimi gerçekleştirmek için geri çağırma mantığını, veri erişimini denetlemeyi planladığınız bileşende (ör. bir etkinliğin onCreate()
yöntemi veya bir uygulamanın onCreate()
yöntemi içinde) uygulayın.
Aşağıdaki kod snippet'i, tek bir etkinlikteki veri erişimini denetlemek için bir AppOpsManager.OnOpNotedCallback
tanımlar:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { val appOpsCallback = object : AppOpsManager.OnOpNotedCallback() { private fun logPrivateDataAccess(opCode: String, trace: String) { Log.i(MY_APP_TAG, "Private data accessed. " + "Operation: $opCode\nStack Trace:\n$trace") } override fun onNoted(syncNotedAppOp: SyncNotedAppOp) { logPrivateDataAccess( syncNotedAppOp.op, Throwable().stackTrace.toString()) } override fun onSelfNoted(syncNotedAppOp: SyncNotedAppOp) { logPrivateDataAccess( syncNotedAppOp.op, Throwable().stackTrace.toString()) } override fun onAsyncNoted(asyncNotedAppOp: AsyncNotedAppOp) { logPrivateDataAccess(asyncNotedAppOp.op, asyncNotedAppOp.message) } } val appOpsManager = getSystemService(AppOpsManager::class.java) as AppOpsManager appOpsManager.setOnOpNotedCallback(mainExecutor, appOpsCallback) }
Java
@Override public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { AppOpsManager.OnOpNotedCallback appOpsCallback = new AppOpsManager.OnOpNotedCallback() { private void logPrivateDataAccess(String opCode, String trace) { Log.i(MY_APP_TAG, "Private data accessed. " + "Operation: $opCode\nStack Trace:\n$trace"); } @Override public void onNoted(@NonNull SyncNotedAppOp syncNotedAppOp) { logPrivateDataAccess(syncNotedAppOp.getOp(), Arrays.toString(new Throwable().getStackTrace())); } @Override public void onSelfNoted(@NonNull SyncNotedAppOp syncNotedAppOp) { logPrivateDataAccess(syncNotedAppOp.getOp(), Arrays.toString(new Throwable().getStackTrace())); } @Override public void onAsyncNoted(@NonNull AsyncNotedAppOp asyncNotedAppOp) { logPrivateDataAccess(asyncNotedAppOp.getOp(), asyncNotedAppOp.getMessage()); } }; AppOpsManager appOpsManager = getSystemService(AppOpsManager.class); if (appOpsManager != null) { appOpsManager.setOnOpNotedCallback(getMainExecutor(), appOpsCallback); } }
onAsyncNoted()
ve onSelfNoted()
yöntemleri belirli durumlarda çağrılır:
onAsyncNoted()
Veri erişimi, uygulamanızın API çağrısı sırasında gerçekleşmezse çağrılır. En yaygın örnek, uygulamanızın bir dinleyici kaydettiği ve dinleyicinin geri çağırması her çağrıldığında veri erişiminin gerçekleştiği durumdur.onAsyncNoted()
'ye iletilenAsyncNotedOp
bağımsız değişkeni,getMessage()
adlı bir yöntem içeriyor. Bu yöntem, veri erişimi hakkında daha fazla bilgi sağlar. Konum geri aramaları söz konusu olduğunda, iletide dinleyicinin system-identity-hash değeri bulunur.onSelfNoted()
bir uygulamanın kendi UID'sininoteOp()
içine ilettiği çok nadir durumlarda çağrılır.
İlişkilendirme etiketine göre veri erişimini denetleme
Uygulamanızın, kullanıcıların fotoğraf çekmesine ve bu fotoğrafları kişileriyle paylaşmasına izin vermek gibi çeşitli temel kullanım alanları olabilir. Çok amaçlı bir uygulama geliştiriyorsanız veri erişimini denetlerken uygulamanızın her bölümüne bir ilişkilendirme etiketi uygulayabilirsiniz. attributionTag
bağlamı, onNoted()
çağrılarına iletilen nesnelerde geri döndürülür.
Bu sayede, veri erişimini kodunuzun mantıksal bölümlerine daha kolay şekilde geri izleyebilirsiniz.
Uygulamanızda ilişkilendirme etiketlerini tanımlamak için aşağıdaki bölümlerdeki adımları tamamlayın.
Manifest dosyasında ilişkilendirme etiketlerini bildirme
Uygulamanız Android 12 (API düzeyi 31) veya sonraki sürümleri hedefliyorsa aşağıdaki kod snippet'inde gösterilen biçimi kullanarak uygulamanızın manifest dosyasında ilişkilendirme etiketlerini beyan etmeniz gerekir. Uygulamanızın manifest dosyasında beyan etmediğiniz bir ilişkilendirme etiketini kullanmaya çalışırsanız sistem sizin için bir null
etiketi oluşturur ve Logcat'te bir mesaj günlüğe kaydedilir.
<manifest ...> <!-- The value of "android:tag" must be a literal string, and the value of "android:label" must be a resource. The value of "android:label" is user-readable. --> <attribution android:tag="sharePhotos" android:label="@string/share_photos_attribution_label" /> ... </manifest>
İlişkilendirme etiketleri oluşturma
Verilere eriştiğiniz etkinlik yönteminde (ör. konum isteğinde bulunduğunuz veya kullanıcının kişi listesine eriştiğiniz etkinlik) onCreate()
yöntemini çağırın ve uygulamanızın bir bölümüyle ilişkilendirmek istediğiniz ilişkilendirme etiketini iletin.createAttributionContext()
Aşağıdaki kod snippet'inde, bir uygulamanın fotoğraf-konum paylaşımı bölümü için nasıl ilişkilendirme etiketi oluşturulacağı gösterilmektedir:
Kotlin
class SharePhotoLocationActivity : AppCompatActivity() { lateinit var attributionContext: Context override fun onCreate(savedInstanceState: Bundle?) { attributionContext = createAttributionContext("sharePhotos") } fun getLocation() { val locationManager = attributionContext.getSystemService( LocationManager::class.java) as LocationManager // Use "locationManager" to access device location information. } }
Java
public class SharePhotoLocationActivity extends AppCompatActivity { private Context attributionContext; @Override public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { attributionContext = createAttributionContext("sharePhotos"); } public void getLocation() { LocationManager locationManager = attributionContext.getSystemService(LocationManager.class); if (locationManager != null) { // Use "locationManager" to access device location information. } } }
Erişim günlüklerine atıf etiketlerini dahil etme
AppOpsManager.OnOpNotedCallback
geri aramanızı, uygulamanızın günlüklerine tanımladığınız ilişkilendirme etiketlerinin adları dahil edilecek şekilde güncelleyin.
Aşağıdaki kod snippet'inde, ilişkilendirme etiketlerini kaydeden güncellenmiş mantık gösterilmektedir:
Kotlin
val appOpsCallback = object : AppOpsManager.OnOpNotedCallback() { private fun logPrivateDataAccess( opCode: String, attributionTag: String, trace: String) { Log.i(MY_APP_TAG, "Private data accessed. " + "Operation: $opCode\n " + "Attribution Tag:$attributionTag\nStack Trace:\n$trace") } override fun onNoted(syncNotedAppOp: SyncNotedAppOp) { logPrivateDataAccess(syncNotedAppOp.op, syncNotedAppOp.attributionTag, Throwable().stackTrace.toString()) } override fun onSelfNoted(syncNotedAppOp: SyncNotedAppOp) { logPrivateDataAccess(syncNotedAppOp.op, syncNotedAppOp.attributionTag, Throwable().stackTrace.toString()) } override fun onAsyncNoted(asyncNotedAppOp: AsyncNotedAppOp) { logPrivateDataAccess(asyncNotedAppOp.op, asyncNotedAppOp.attributionTag, asyncNotedAppOp.message) } }
Java
@Override public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { AppOpsManager.OnOpNotedCallback appOpsCallback = new AppOpsManager.OnOpNotedCallback() { private void logPrivateDataAccess(String opCode, String attributionTag, String trace) { Log.i("MY_APP_TAG", "Private data accessed. " + "Operation: $opCode\n " + "Attribution Tag:$attributionTag\nStack Trace:\n$trace"); } @Override public void onNoted(@NonNull SyncNotedAppOp syncNotedAppOp) { logPrivateDataAccess(syncNotedAppOp.getOp(), syncNotedAppOp.getAttributionTag(), Arrays.toString(new Throwable().getStackTrace())); } @Override public void onSelfNoted(@NonNull SyncNotedAppOp syncNotedAppOp) { logPrivateDataAccess(syncNotedAppOp.getOp(), syncNotedAppOp.getAttributionTag(), Arrays.toString(new Throwable().getStackTrace())); } @Override public void onAsyncNoted(@NonNull AsyncNotedAppOp asyncNotedAppOp) { logPrivateDataAccess(asyncNotedAppOp.getOp(), asyncNotedAppOp.getAttributionTag(), asyncNotedAppOp.getMessage()); } }; AppOpsManager appOpsManager = getSystemService(AppOpsManager.class); if (appOpsManager != null) { appOpsManager.setNotedAppOpsCollector(appOpsCollector); } }