Arka Planda Sürekli Takip Mekanizması (Foreground Service) Kılavuzu

Konuyu başlatankyr karacaMod·
Yanıt
0
Görüntülenme
3
Oy
0
Son yanıt
Henüz yok
3 görüntülenme

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.

java
import 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.

java
import 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."

0 yanıt3

Konuyu Yanıtla

Markdown destekler · Alıntı, kod, liste kullanabilirsiniz

Konuyu yanıtlamak için giriş yapmalısınız.

Hızlı yanıt yazmak için giriş yapın.