Arka Planda Sürekli Takip Mekanizması (Foreground Service) Kılavuzu
Android sistemlerinden en temel özelliklerinden biri, arka planda gizlice çalışan uygulamaları kapatma yeteneğidir. Ancak kullanıcıya bir bildirim göstererek "Ben arka planda çalışıyorum" diyen Foreground Service yapılarına dokunmazlar. Bu makalede, arka planda sürekli takip mekanizmasını oluşturacak adımları ve önemli noktaları inceleyeceğiz.
1. AndroidManifest.xml Güncellemesi
Servisimizin arka planda çalışabilmesi için gerekli izinleri ve servis tanımını manifest dosyasına ekliyoruz. Modern Android sürümleri (Android 14 ve sonrası) için servis türünü belirtmek zorunludur.
xml<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" /> <application ...> <service android:name=".AppTrackerService" android:foregroundServiceType="specialUse" android:enabled="true" android:exported="false" /> </application>
2. AppTrackerService.java Sınıfının Oluşturulması
Bu servis, arka planda bir thread (iş parçacığı) başlatacak ve her saniye kullanıcının hangi uygulamada olduğunu kontrol edip log katmanına yazacaktır.
javaimport android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.Service; import android.content.Intent; import android.os.Build; import android.os.IBinder; import androidx.core.app.NotificationCompat; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class AppTrackerService extends Service { private static final String CHANNEL_ID = "AppTrackerChannel"; private ScheduledExecutorService scheduler; @Override public void onCreate() { super.onCreate(); createNotificationChannel(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { // 1. Servisi ön plana çıkar ve kullanıcıya bildirim göster (Zorunlu) Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle("Uygulama Takibi Aktif") .setContentText("Arka planda uygulama kullanımı analiz ediliyor.") .setSmallIcon(android.R.drawable.ic_dialog_info) .build(); startForeground(1, notification); // 2. Takip döngüsünü başlat (Her 1.5 saniyede bir kontrol eder) startTrackingLoop(); return START_STICKY; // Servis sistem tarafından kapatılırsa yeniden başlasın } private void startTrackingLoop() { scheduler = Executors.newSingleThreadScheduledExecutor(); scheduler.scheduleAtFixedRate(new Runnable() { @Override public void run() { // Önceki adımda yazdığımız fonksiyonları çağırıyoruz String currentPackage = getForegroundApp(getApplicationContext()); if (currentPackage != null) { String appName = getAppNameFromPackage(getApplicationContext(), currentPackage); // Burada yakaladığımız uygulama adını loglayabilir veya sunucuya atabilirsiniz android.util.Log.d("AppTracker", "Şu an açık olan uygulama: " + appName); } } }, 0, 1500, TimeUnit.MILLISECONDS); // 1500 ms = 1.5 saniye } private void createNotificationChannel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel serviceChannel = new NotificationChannel( CHANNEL_ID, "Uygulama Takip Servisi Kanalı", NotificationManager.IMPORTANCE_LOW ); NotificationManager manager = getSystemService(NotificationManager.class); if (manager != null) { manager.createNotificationChannel(serviceChannel); } } } @Override public void onDestroy() { super.onDestroy(); // Servis kapatıldığında döngüyü durdur ki bataryayı sömürmesin if (scheduler != null && !scheduler.isShutdown()) { scheduler.shutdown(); } } @Override public IBinder onBind(Intent intent) { return null; } // NOT: getForegroundApp() ve getAppNameFromPackage() metotlarını // buraya eklemeyi unutmayın (Bir önceki kodlarınız). }
3. Servisi Ana Activity İçinden Başlatma
Kullanıcı uygulamanızı açıp kullanım istatistikleri iznini verdikten sonra, bu servisi tek bir tetiklemeyle başlatabilirsiniz. Servis başladıktan sonra kullanıcı ana ekrana dönse bile takip devam edecektir.
javaimport android.content.Intent; import android.os.Build; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { @Override protected void bundle(Bundle savedInstanceState) { super.bundle(savedInstanceState); setContentView(R.layout.activity_main); // İzin kontrolü yapıldıktan sonra servisi başlatıyoruz if (checkUsageStatsPermission(this)) { Intent serviceIntent = new Intent(this, AppTrackerService.class); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { startForegroundService(serviceIntent); // Android 8.0+ için } else { startService(serviceIntent); // Eski sürümler için } } else { requestUsageStatsPermission(this); } } }
Performans ve Batarya Uyarısı
Önemli Not: Arka planda sürekli çalışan ScheduledExecutorService gibi döngüler cihazın işlemcisini uyanık tutacağı için batarya tüketimini artırır. Zaman aralığını (örneğin 1.5 saniye yerine 3-5 saniye) uygulamanızın kritiklik seviyesine göre optimize etmeniz, kullanıcı deneyimi açısından oldukça önemlidir.
"Batarya tüketimini minimize etmek için, arka planda çalışan döngülerin zaman aralığını optimize etmek ve gereksiz işlemleri azaltmak önemlidir. Zaman aralığını artırmak, kullanıcı deneyimini iyileştirmek ve batarya tüketimini minimize etmek için ideal bir yol olabilir."
Konuyu Yanıtla
Markdown destekler · Alıntı, kod, liste kullanabilirsinizKonuyu yanıtlamak için giriş yapmalısınız.