[Android N] Background Optimizations - CONNECTIVITY_ACTION
CONNECTIVITY_ACTION 브로드캐스트는 네트워크 연결 상태 변화를 알려줍니다. LTE 모바일 네트워크에서 Wi-Fi로 변경되는 경우 등이죠. Android 6.0까지는 애플리케이션의 manifest 파일에 CONNECTIVITY_ACTION 브로드캐스트를 등록할 수 있었지만 N 부터는 허용하지 않습니다.
왜 그럴까요? 네트워크 연결 상태가 변할 때 마다 CONNECTIVITY_ACTION을 받기 위해 등록된 앱들이 실행되면 메모리, 배터리 등의 자원을 낭비하게 되겠죠. 막상 실행된 앱이 할일도 없는데 말이죠. 대신 Android N의 경우 아래 3가지 방법을 이용하여 네트워크 상태 변화를 확인할 수 있습니다.
왜 그럴까요? 네트워크 연결 상태가 변할 때 마다 CONNECTIVITY_ACTION을 받기 위해 등록된 앱들이 실행되면 메모리, 배터리 등의 자원을 낭비하게 되겠죠. 막상 실행된 앱이 할일도 없는데 말이죠. 대신 Android N의 경우 아래 3가지 방법을 이용하여 네트워크 상태 변화를 확인할 수 있습니다.
- Context.registerReceiver()로 CONNECTIVITY_ACTION 브로드캐스트를 받도록 등록할 수 있습니다
- JobScheduler를 이용하여 특정 조건이 되면 JobService의 onStartJob()이 호출 되도록 합니다
- ConnectivityManager를 이용하여 특정 조건의 네트워크 상태가 되면 콜백이 불리도록 합니다
getApplicationContext().registerReceiver(new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
Log.d(LOG_TAG, "onReceive");
}
}, new IntentFilter(android.net.ConnectivityManager.CONNECTIVITY_ACTION));
registerReceiver 를 호출하여 CONNECTIVITY_ACTION 브로드캐스트를 받도록 합니다. 네트워크의 상태가 변할 때 마다 onReceive가 호출됩니다. (예: LTE => Wi-Fi로 전환 혹은 Wi-Fi => LTE로 전환). 현재 네트워크의 상태는 ConnectivityManager에서 확인 할수 있습니다.
ConnectivityManager cm =
(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
if (ni != null) {
Log.d(tag, ni.toString());
}
JobScheduler를 이용하면 특정 조건들이 맞아 떨어질때 서비스가 실행되도록 만들 수 있습니다. 아래 예제 코드의 경우는 기기가 충전 중이고 비과금(무료) 네트워크에 연결된 경우 MyJobService 클래스에 구현된 서비스를 실행합니다.
final Context context = getApplicationContext(); JobScheduler js = (JobScheduler)context.getSystemService( Context.JOB_SCHEDULER_SERVICE); JobInfo job = new JobInfo.Builder( MY_BACKGROUND_JOB, new ComponentName(context, MyJobService.class)) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) .setRequiresCharging(true) .build(); js.schedule(job);
조건이 맞으면 JobService의 onStartJob이 호출됩니다.
public class MyJobService extends JobService { private final String LOG_TAG = "MyJobService"; @Override public boolean onStartJob(JobParameters jobParameters) { Log.d(LOG_TAG, "onStartJob"); return false;
} @Override public boolean onStopJob(JobParameters jobParameters) { return false; }
}
JobService를 상속받아 구현한 클래스는 아래와 같이 manifest 파일에 서비스로 등록해 주어야 합니다. (exported는 true로 변경할 수 있습니다.)
<service android:name=".MyJobService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false">
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false">
</service>
마지막으로 ConnectivityManager의 registerNetworkCallback()을 이용하여 특정 조건의 네트워크를 쓸 수 있는 상태가 되면 콜백이 호출되도록 할 수도 있습니다. 아래 예제는 비과금 Wi-Fi 네트워크에 연결되면 onAvailable이 호출되도록 합니다.
final Context context = getApplicationContext(); ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkRequest request = new NetworkRequest.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED) .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .build(); cm.registerNetworkCallback(request, new ConnectivityManager.NetworkCallback() { public void onAvailable (Network network) { Log.d(LOG_TAG, "onAvailable"); } });
https://github.com/wonkim/BackgroundOptimizations에서 전체 예제 코드를 받으세요.