Veri erişimi denetimi yaparak uygulamanızın ve bağımlılarının kullanıcılardan alınan ö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 tespit etmenizi sağlar. Uygulamanız örnek kaydedebilir
performans gösterebilen AppOpsManager.OnOpNotedCallback
işlem sayısı:
- Uygulamanızın kodu gizli verilere erişiyor. Hangi mantıksal uygulamanızın bir bölümü etkinliği çağırdıysa, veri erişimini ilişkilendirmek için etiketi kullanın.
- Bağımlı kitaplıktaki veya SDK'daki kod gizli verilere erişir.
Veri erişimi denetimi, veri isteğinin gerçekleştiği ileti dizisinde çağrılır. Diğer bir deyişle, uygulamanızdaki bir üçüncü taraf SDK'sı veya kitaplığı gizli verilere erişen bir API'yi çağırırsa veri erişimi denetimi, OnOpNotedCallback
'nin çağrıyla ilgili bilgileri incelemesine olanak tanır. Genellikle bu,
geri çağırma nesnesi, çağrının uygulamanızdan mı yoksa SDK'dan mı geldiğini
uygulamanın mevcut durumuna (ör. mevcut iş parçacığının yığın izlemesi) bakma.
Veri erişimini günlüğe kaydetme
AppOpsManager.OnOpNotedCallback
örneğini kullanarak veri erişimi denetimi yapmak için geri çağırma mantığını, veri erişimini denetlemek istediğiniz bileşene (ör. bir etkinliğin onCreate()
yöntemi veya bir uygulamanın onCreate()
yöntemi) uygulayın.
Aşağıdaki kod snippet'inde, tek bir etkinlikte veri erişimini denetlemek için bir AppOpsManager.OnOpNotedCallback
tanımlanmaktadır:
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) }
@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:
Veri erişimi, uygulamanızın API çağrısı sırasında gerçekleşmezse
onAsyncNoted()
çağrılır. En yaygın örnek, uygulamanızın bir dinleyici kaydetmesi ve dinleyicinin geri araması her çağrıldığında veri erişimi gerçekleşir.onAsyncNoted()
işlevine iletilenAsyncNotedOp
bağımsız değişkeni birgetMessage()
adlı yeni bir yöntem kullanmayı deneyin. Bu yöntem, RACI matrisleri veri erişimidir. Konum geri çağırmalarında mesaj, dinleyicinin sistem-kimlik karması.onSelfNoted()
bir uygulama kendi UID'sini aktardığında,noteOp()
.
Veri erişimini ilişkilendirme etiketine göre denetleyin
Uygulamanızın, kullanıcıların fotoğraf çekmesine ve bu fotoğrafları kişilerinizle paylaşmasına izin verme gibi birkaç birincil kullanım alanı olabilir. Çok amaçlı bir uygulama geliştirirseniz veri erişimini denetlediğinizde uygulamanızın her bölümüne bir ilişkilendirme etiketi uygulayabilirsiniz. attributionTag
bağlamı, onNoted()
çağrılarına iletilen nesnelerde döndürülür.
Bu, veri erişimini kodunuzun mantıksal bölümlerine daha kolay şekilde izlemenize yardımcı olur.
Uygulamanızda ilişkilendirme etiketlerini tanımlamak için aşağıdaki bölümlerdeki adımları tamamlayın.
İlişkilendirme etiketlerini manifest dosyasında bildirme
Uygulamanız Android 12 (API düzeyi 31) veya sonraki bir sürümü hedefliyorsa bunu beyan etmeniz gerekir.
aşağıdaki biçimi kullanarak uygulamanızın manifest dosyasındaki ilişkilendirme etiketlerini destekler:
kod snippet'ini eklemeniz gerekir. Kullanmadığınız bir ilişkilendirme etiketini kullanmaya çalışırsanız
manifest dosyasında belirttiğinizde, sistem sizin için bir null
etiketi oluşturur ve
Logcat'e bir mesaj kaydeder.
<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 etkinliğin onCreate()
yönteminde (ör. konum isteğinde bulunduğunuz veya kullanıcının kişi listesine eriştiğiniz etkinlik) uygulamanızın bir kısmıyla ilişkilendirmek istediğiniz ilişkilendirme etiketini ileterek createAttributionContext()
'i çağırın.
Aşağıdaki kod snippet'i, bir uygulamanın fotoğraf-konum paylaşma bölümü:
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. } }
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 ilişkilendirme etiketlerini dahil et
AppOpsManager.OnOpNotedCallback
geri aramanızı, uygulamanızın günlüklerinin kaydedileceği şekilde güncelleyin
tanımladığınız ilişkilendirme etiketlerinin adlarını içermelidir.
Aşağıdaki kod snippet'inde, ilişkilendirme etiketlerini günlüğe kaydeden güncellenmiş mantık gösterilmektedir:
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) } }
@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); } }