728x90

Android background 실행 제한

https://developer.android.com/about/versions/oreo/background?hl=ko 의 내용을 발췌 요약했다.


Android 8.0는 사용자 경험을 개선하기 위해 백그라운드에서 실행되면서 앱의 동작을 제한한다.
잘 동작하던 발신자정보 팝업창이 Android 8.0 에서 잠시 보여주고 사라져 버린다.
- 백그라운드 서비스 제한: 앱이 유휴 상태인 경우 백그라운드 서비스의 사용이 제한된다.
  마치 앱이 서비스의 Service.stopSelf() 메서드를 호출한 것처럼 시스템이 앱의 백그라운드 서비스를 중지시킨다.
  . 액티비티가 시작되거나 일시 중지되거나 상관없이 보이는 액티비티가 있는 경우 앱이 포그라운드에 있는 것으로 간주
  . 포그라운드 서비스가 있는 경우 앱이 포그라운드에 있는 것으로 간주
- 브로드캐스트 제한: 앱이 암시적 브로드캐스트에 등록하기 위해 자체 매니페스트를 사용할 수 없다.
  그렇지만 여전히 앱이 런타임에 브로드캐스트에 등록할 수 있으며,
  특정 앱을 대상으로 하는 명시적 브로드캐스트에 등록하기 위해 매니페스트를 사용할 수 있다.
앱은 JobScheduler 작업을 사용하여 이러한 제한을 해결할 수 있다.
Android 8.0에서는 JobScheduler에 대한 여러 가지 개선 사항을 제공하며 이를 통해 서비스와 브로드캐스트 수신기를 예약된 작업으로 쉽게 바꿀 수 있다.

앱이 허용 목록에 있는 동안에는 제한없이 서비스를 시작
- 우선순위가 높은 Firebase 클라우드 메시징(FCM) 메시지 처리
- SMS/MMS 메시지와 같은 브로드캐스트 수신
- 알림에서 PendingIntent 실행

Android 8.0에서는 새 서비스를 포그라운드에서 시작하는 새로운 메서드 Context.startForegroundService()를 소개
- 시스템이 서비스를 생성한 후, 앱은 5초 이내에 해당 서비스의 startForeground() 메서드를 호출하여 새 서비스의 알림을 사용자에게 표시해야 한다.
- 앱이 이 시간 한도 내에 startForeground()를 호출하지 않으면 시스템이 서비스를 중단하고 이 앱을 ANR로 선언한다.
- 오디오를 재생하는 서비스는 항상 포그라운드 서비스여야 한다.
  startService() 대신 NotificationManager.startServiceInForeground()를 사용하여 서비스를 생성한다.


- Foreground service 의 경우 반드시 noficiation 을 제공해야 한다.
  Foreground service 는 보통 Music Player 와 같이 interactive 한 service 에 사용한다.
  foreground 는 startForeground() 로 시작시킨다. 이 때 Notification ID 와 notification을 함께 전달한다.
  parameter로 stopForeground() 로 stop 시키는데 parameter 로 notification 도 함께 제거할지를 boolean 값으로 넘기게 된다.

// 서비스를 실행할 때
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    context.startForegroundService(new Intent(context, ServedService.class));
} else {
    context.startService(new Intent(context, ServedService.class));
}

// 서비스 파일 내에서
@Override
public void onCreate() {
    super.onCreate();
    startForeground(1,new Notification()); // 추가 (9.0에서는 변경해야 함)
}

@Override
public void onDestroy() {
    // 서비스가 종료될 때 실행
    super.onDestroy();
    stopForeground(true);
}


2019.4.6일 추가 내용


Android 9.0 에서는 아래와 같이 변경해야 제대로 동작한다.

AndroidManifest.xml 파일에 한줄 추가해야 한다.

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />


startForeground(1,new Notification()); // 대신에 아래 코드로 변경한다.


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
            startMyOwnForeground();

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void startMyOwnForeground() {
        String NOTIFICATION_CHANNEL_ID = "com.link2me.android.Phone";
        String channelName = "Incoming Calling Service";
        NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
        chan.setLightColor(Color.BLUE);
        chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        assert manager != null;
        manager.createNotificationChannel(chan);

        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
        Notification notification = notificationBuilder.setOngoing(true)
                .setSmallIcon(R.drawable.icon)
                .setContentTitle("App is running in background")
                .setPriority(NotificationManager.IMPORTANCE_MIN)
                .setCategory(Notification.CATEGORY_SERVICE)
                .build();
        startForeground(2, notification);
    }
 


전화번호 액세스 제한

https://developer.android.com/about/versions/pie/android-9.0-changes-all?hl=ko




블로그 이미지

Link2Me

,