브로드캐스트 개요

Android 앱은 Android 시스템에서 브로드캐스트 메시지를 보내거나 받을 수 있으며 다른 Android 앱의 경우 게시-구독 설계 패턴입니다. 관심 있는 이벤트가 발생할 때 이러한 브로드캐스트가 전송됩니다. 예를 들어 Android 시스템은 다양한 시스템 이벤트가 발생할 때 브로드캐스트를 전송합니다. 발생할 수 있습니다. 앱 또한 맞춤 브로드캐스트를 전송하여 다른 앱에 관심을 가질 만한 콘텐츠 (예: 일부 새로운 데이터에는 다운로드됨).

시스템에서는 방송 전송을 최적화하여 최적의 시스템 상태 따라서 방송 전송 시간은 보장 지연 시간이 짧은 프로세스 간 통신이 필요한 앱은 바인드된 서비스를 고려합니다.

앱은 특정 브로드캐스트를 수신하도록 등록할 수 있습니다. 방송이 전송될 때 시스템은 자동으로 브로드캐스트를 특정 유형의 방송을 수신할 수 있습니다.

일반적으로 브로드캐스트는 여러 앱에서 메시징 시스템으로 사용될 수 있습니다. 일반적인 사용자 플로우를 벗어나면 됩니다. 하지만 악용하지 않도록 주의해야 합니다. 브로드캐스트에 응답하고 시스템 성능 저하에 영향을 줄 수 있습니다

시스템 브로드캐스트 정보

시스템은 다양한 시스템 이벤트가 발생하면 자동으로 브로드캐스트를 전송합니다. 시스템이 비행기 모드로 전환할 때와 같은 상황에서 발생합니다. 시스템 이 브로드캐스트는 수신 동의한 모든 앱으로 전송되어 이벤트를 처리합니다.

브로드캐스트 메시지 자체는 Intent에 래핑됩니다. 작업 문자열이 발생한 이벤트를 식별하는 객체 (예: android.intent.action.AIRPLANE_MODE). 인텐트에는 다음이 포함될 수도 있습니다. 추가 필드에 함께 제공됩니다. 예를 들어 비행기 모드 인텐트에 비행기인지 여부를 나타내는 불리언 추가 항목이 포함되어 있습니다. 모드를 사용 중입니다.

인텐트를 읽고 작업 문자열을 자세한 내용은 인텐트 및 인텐트 필터.

시스템 브로드캐스트 작업의 전체 목록은 다음을 참조하세요. BROADCAST_ACTIONS.TXT 파일을 엽니다. 각 브로드캐스트 작업에는 상수 필드가 필요합니다. 예를 들어 상수의 값은 ACTION_AIRPLANE_MODE_CHANGED: android.intent.action.AIRPLANE_MODE입니다. 각 브로드캐스트 작업에 대한 문서 는 연결된 상수 필드에서 사용할 수 있습니다.

시스템 브로드캐스트 변경사항

Android 플랫폼이 발전함에 따라 시스템 브로드캐스트 방식이 주기적으로 변경됩니다. 있습니다. 모든 Android 버전을 지원하려면 다음 변경사항에 유의하세요.

Android 14

앱이 캐시되는 동안 상태 - 브로드캐스트 전송은 시스템 상태에 맞게 최적화되었습니다. 예를 들어, ACTION_SCREEN_ON가 지연 시간을 측정합니다. 앱이 캐시된 데이터 세트에서 활성 프로세스로 전환할 수 있습니다 수명 주기에 따라 시스템을 모든 지연된 브로드캐스트를 차단합니다

매니페스트를 사용하여 캐시된 파일에서 상태를 지정합니다

Android 9

Android 9 (API 수준 28)부터 NETWORK_STATE_CHANGED_ACTION 드림 사용자의 위치나 개인 정보를 받지 않을 때 식별할 수 있습니다.

또한 앱이 Android 9 이상을 실행하는 기기에 설치된 경우 Wi-Fi의 시스템 브로드캐스트에는 SSID, BSSID, 연결이 포함되지 않음 스캔할 수 있습니다. 이 정보를 확인하려면 getConnectionInfo() 드림 하세요.

Android 8.0

Android 8.0 (API 레벨 26)부터 시스템은 매니페스트 선언 수신기에 관한 제한입니다.

앱이 Android 8.0 이상을 타겟팅하는 경우 매니페스트를 사용하여 대부분의 암시적 브로드캐스트( 있습니다. 이 경우에도 컨텍스트 등록 수신기를 알 수 있습니다.

Android 7.0

Android 7.0 (API 수준 24) 이상에서는 다음 시스템을 전송하지 않습니다. 브로드캐스트:

또한 Android 7.0 이상을 타겟팅하는 앱은 CONNECTIVITY_ACTION 브로드캐스트를 등록해야 합니다. (registerReceiver(BroadcastReceiver, IntentFilter) 사용) manifest에 수신자를 선언해도 작동하지 않습니다.

브로드캐스트 수신

앱은 두 가지 방식, 즉 매니페스트에서 선언된 수신자를 통해 브로드캐스트를 수신할 수 있습니다. 컨텍스트 등록 수신자입니다

manifest에 선언된 수신자

매니페스트에서 broadcast receiver를 선언하면 시스템에서 app (앱이 아직 실행되고 있지 않은 경우)을 전달할 수 있습니다.

manifest에서 broadcast receiver를 선언하려면 다음 단계를 따르세요.

  1. <receiver>를 지정합니다. 요소를 지정할 수 있습니다.

    <!-- If this receiver listens for broadcasts sent from the system or from
         other apps, even other apps that you own, set android:exported to "true". -->
    <receiver android:name=".MyBroadcastReceiver" android:exported="false">
        <intent-filter>
            <action android:name="APP_SPECIFIC_BROADCAST" />
        </intent-filter>
    </receiver>
    

    인텐트 필터는 수신자가 구독할 브로드캐스트 작업을 지정합니다.

  2. BroadcastReceiver 서브클래스를 선언하고 onReceive(Context, Intent)를 구현합니다. 이 다음 예의 broadcast receiver는 입니다.

    Kotlin

    private const val TAG = "MyBroadcastReceiver"
    
    class MyBroadcastReceiver : BroadcastReceiver() {
    
        override fun onReceive(context: Context, intent: Intent) {
            StringBuilder().apply {
                append("Action: ${intent.action}\n")
                append("URI: ${intent.toUri(Intent.URI_INTENT_SCHEME)}\n")
                toString().also { log ->
                    Log.d(TAG, log)
    
                    val binding = ActivityNameBinding.inflate(layoutInflater)
                    val view = binding.root
                    setContentView(view)
    
                    Snackbar.make(view, log, Snackbar.LENGTH_LONG).show()
                }
            }
        }
    }
    

    자바

    public class MyBroadcastReceiver extends BroadcastReceiver {
            private static final String TAG = "MyBroadcastReceiver";
            @Override
            public void onReceive(Context context, Intent intent) {
                StringBuilder sb = new StringBuilder();
                sb.append("Action: " + intent.getAction() + "\n");
                sb.append("URI: " + intent.toUri(Intent.URI_INTENT_SCHEME).toString() + "\n");
                String log = sb.toString();
                Log.d(TAG, log);
    
                ActivityNameBinding binding =
                        ActivityNameBinding.inflate(layoutInflater);
                val view = binding.root;
                setContentView(view);
    
                Snackbar.make(view, log, Snackbar.LENGTH_LONG).show();
            }
        }
    

    뷰 결합을 사용 설정하려면 다음 안내를 따르세요. 모듈 수준에서 viewBinding을 구성합니다. build.gradle 파일에 추가합니다.

앱이 설치될 때 시스템 패키지 관리자가 수신자를 등록합니다. 그러면 수신기가 앱으로 들어오는 별도의 진입점이 되어 시스템이 앱을 시작하고 앱이 브로드캐스트를 전달하지 않는 경우 확인할 수 있습니다

시스템에서 새 BroadcastReceiver 구성요소를 생성 객체를 사용하여 수신하는 각 브로드캐스트를 처리합니다. 이 객체는 onReceive(Context, Intent) 호출 기간 동안 유지됩니다. 코드가 반환되면 시스템은 구성요소가 더 이상 유효하지 않은 것으로 활성화됨.

컨텍스트에 등록된 수신자

컨텍스트 등록 수신기는 등록하는 동안 브로드캐스트를 수신합니다. 문맥이 유효합니다. 예를 들어 Activity 컨텍스트에서 활동이 소멸되지 않는 한 브로드캐스트를 수신합니다. 만약 애플리케이션 컨텍스트에 등록하면 앱이 확인할 수 있습니다

수신자를 컨텍스트에 등록하려면 다음 단계를 따르세요.

  1. 앱의 모듈 수준 빌드 파일에 AndroidX 핵심 라이브러리:

    Groovy

    dependencies {
        def core_version = "1.13.1"
    
        // Java language implementation
        implementation "androidx.core:core:$core_version"
        // Kotlin
        implementation "androidx.core:core-ktx:$core_version"
    
        // To use RoleManagerCompat
        implementation "androidx.core:core-role:1.0.0"
    
        // To use the Animator APIs
        implementation "androidx.core:core-animation:1.0.0"
        // To test the Animator APIs
        androidTestImplementation "androidx.core:core-animation-testing:1.0.0"
    
        // Optional - To enable APIs that query the performance characteristics of GMS devices.
        implementation "androidx.core:core-performance:1.0.0"
    
        // Optional - to use ShortcutManagerCompat to donate shortcuts to be used by Google
        implementation "androidx.core:core-google-shortcuts:1.1.0"
    
        // Optional - to support backwards compatibility of RemoteViews
        implementation "androidx.core:core-remoteviews:1.1.0"
    
        // Optional - APIs for SplashScreen, including compatibility helpers on devices prior Android 12
        implementation "androidx.core:core-splashscreen:1.2.0-alpha01"
    }
    

    Kotlin

    dependencies {
        val core_version = "1.13.1"
    
        // Java language implementation
        implementation("androidx.core:core:$core_version")
        // Kotlin
        implementation("androidx.core:core-ktx:$core_version")
    
        // To use RoleManagerCompat
        implementation("androidx.core:core-role:1.0.0")
    
        // To use the Animator APIs
        implementation("androidx.core:core-animation:1.0.0")
        // To test the Animator APIs
        androidTestImplementation("androidx.core:core-animation-testing:1.0.0")
    
        // Optional - To enable APIs that query the performance characteristics of GMS devices.
        implementation("androidx.core:core-performance:1.0.0")
    
        // Optional - to use ShortcutManagerCompat to donate shortcuts to be used by Google
        implementation("androidx.core:core-google-shortcuts:1.1.0")
    
        // Optional - to support backwards compatibility of RemoteViews
        implementation("androidx.core:core-remoteviews:1.1.0")
    
        // Optional - APIs for SplashScreen, including compatibility helpers on devices prior Android 12
        implementation("androidx.core:core-splashscreen:1.2.0-alpha01")
    }
    
  2. 인스턴스 만들기 BroadcastReceiver:

    Kotlin

    val br: BroadcastReceiver = MyBroadcastReceiver()
    

    자바

    BroadcastReceiver br = new MyBroadcastReceiver();
    
  3. 인스턴스 만들기 IntentFilter:

    Kotlin

    val filter = IntentFilter(APP_SPECIFIC_BROADCAST)
    

    자바

    IntentFilter filter = new IntentFilter(APP_SPECIFIC_BROADCAST);
    
  4. broadcast receiver를 내보내야 하는지 여부를 선택합니다. 액세스할 수 있습니다. 이 수신기가 전송된 브로드캐스트를 수신 대기하는지 여부 시스템이나 다른 앱, 심지어는 소유하고 있는 다른 앱에서 데이터를 캡처하려면 RECEIVER_EXPORTED 플래그. 대신 이 수신기가 브로드캐스트를 수신 대기하려면 RECEIVER_NOT_EXPORTED 플래그를 사용합니다.

    Kotlin

    val listenToBroadcastsFromOtherApps = false
    val receiverFlags = if (listenToBroadcastsFromOtherApps) {
        ContextCompat.RECEIVER_EXPORTED
    } else {
        ContextCompat.RECEIVER_NOT_EXPORTED
    }
    

    자바

    boolean listenToBroadcastsFromOtherApps = false;
    if (listenToBroadcastsFromOtherApps) {
        receiverFlags = ContextCompat.RECEIVER_EXPORTED;
    } else {
        receiverFlags = ContextCompat.RECEIVER_NOT_EXPORTED;
    }
    
  5. 다음을 호출하여 수신자를 등록합니다. registerReceiver():

    Kotlin

    ContextCompat.registerReceiver(context, br, filter, receiverFlags)
    

    자바

    ContextCompat.registerReceiver(context, br, filter, receiverFlags);
    
  6. 브로드캐스트 수신을 중지하려면 unregisterReceiver(android.content.BroadcastReceiver)를 호출합니다. 수신기가 더 이상 필요하지 않으면 수신기 등록을 취소해야 합니다. 컨텍스트가 더 이상 유효하지 않습니다.

    수신자를 등록 및 등록 취소하는 위치에 유의해야 합니다. 예를 들어 활동의 컨텍스트를 사용하여 onCreate(Bundle)에 수신자를 등록하면 onDestroy()에서 등록을 취소해야 수신기가 활동 컨텍스트에서 유출되지 않도록 방지합니다. 등록하는 경우 onResume()에 수신기를 사용하는 경우 onPause()에서 등록 취소하여 여러 번 등록 (브로드캐스트를 수신하고 싶지 않은 경우 불필요한 시스템 오버헤드를 줄일 수 있습니다. 금지사항 onSaveInstanceState(Bundle)에서 등록 취소 사용자가 기록 스택으로 돌아가도 이 메서드가 호출되지 않기 때문입니다.

프로세스 상태에 미치는 영향

BroadcastReceiver 애플리케이션이 작동하거나 영향을 미치지 않아 통제된 프로세스에 시스템 종료 가능성. 포그라운드 프로세스는 수신자의 onReceive() 메서드를 실행합니다. 이 극단적인 메모리 압력이 발생하는 경우를 제외하고 시스템은 프로세스를 실행합니다.

BroadcastReceiver는 onReceive() 후에 비활성화됩니다. 수신자의 호스트 프로세스는 앱 구성 요소만큼 중요합니다. 이 프로세스에서 호스트만 매니페스트 선언 수신기 (사용자가 한 번도 호출하지 않은 앱이 최근에 상호작용하지 않은 경우) 시스템에서 onReceive() 후에 종료할 수 있습니다. 더 중요한 프로세스에 사용할 수 있습니다.

따라서 broadcast receiver는 장기 실행 백그라운드 스레드를 시작해서는 안 됩니다. 시스템은 onReceive() 이후 언제든지 프로세스를 중지하여 회수할 수 있습니다. 사용하여 생성된 스레드를 종료합니다. 프로세스를 유지하려면 JobService JobScheduler를 사용하여 수신기에서 시스템이 프로세스가 아직 작동하고 있음을 알게 됩니다 백그라운드 작업 개요에서 자세한 내용을 확인할 수 있습니다.

브로드캐스트 전송

Android는 다음과 같이 앱에서 브로드캐스트를 전송하는 방법을 세 가지 제공합니다.

  • sendOrderedBroadcast(Intent, String) 메서드는 한 번에 하나의 수신기에 브로드캐스트를 보냅니다. 각 수신기가 실행될 때 결과를 다음 수신자에게 전파하거나 다른 사람에게 전달되지 않도록 브로드캐스트를 완전히 중단 있습니다 수신기가 실행되는 순서는 일치하는 인텐트 필터의 android:priority 속성 새 리시버를 같은 우선순위가 임의의 순서로 실행됩니다
  • sendBroadcast(Intent) 메서드는 정의되지 않은 순서로 모든 수신기에 브로드캐스트합니다. 이를 정상 상태라고 방송 이는 더 효율적이지만 수신자가 브로드캐스트로부터 수신한 데이터를 전파하거나 브로드캐스트를 취소합니다.

다음 코드 스니펫은 인텐트와 sendBroadcast(Intent) 호출

Kotlin

Intent().also { intent ->
    intent.setAction("com.example.broadcast.MY_NOTIFICATION")
    intent.putExtra("data", "Nothing to see here, move along.")
    sendBroadcast(intent)
}

자바

Intent intent = new Intent();
intent.setAction("com.example.broadcast.MY_NOTIFICATION");
intent.putExtra("data", "Nothing to see here, move along.");
sendBroadcast(intent);

브로드캐스트 메시지는 Intent 객체에서 래핑됩니다. 인텐트의 작업 문자열은 앱의 Java 패키지 이름 구문을 제공해야 하며 방송 이벤트를 고유하게 식별합니다. 추가 정보를 첨부할 수 있습니다. putExtra(String, Bundle)를 사용하여 인텐트에 추가합니다. 또한 인텐트에서 setPackage(String)를 호출합니다.

권한으로 브로드캐스트 제한

권한을 사용하면 특정 권한을 부여하기만 하면 됩니다 발신자 또는 브로드캐스트의 수신자입니다.

권한을 사용하여 전송

sendBroadcast(Intent, String)를 호출하거나 sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)를 사용하는 경우 권한 매개변수를 지정합니다. 다음과 같이 권한을 요청한 수신자만 태그를 권한)이 브로드캐스트를 수신할 수 있습니다. 예를 들어 다음 코드는 브로드캐스트를 전송합니다.

Kotlin

sendBroadcast(Intent(BluetoothDevice.ACTION_FOUND),
              Manifest.permission.BLUETOOTH_CONNECT)

자바

sendBroadcast(new Intent(BluetoothDevice.ACTION_FOUND),
              Manifest.permission.BLUETOOTH_CONNECT)

브로드캐스트를 수신하려면 수신 앱이 다음과 같습니다.

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

다음과 같은 기존 시스템 권한을 지정할 수 있습니다. BLUETOOTH_CONNECT 또는 <permission> 요소 대상 자세히 알아보려면 시스템 권한을 참고하세요.

권한을 사용하여 수신

broadcast receiver를 등록할 때 권한 매개변수를 지정하는 경우 (registerReceiver(BroadcastReceiver, IntentFilter, String, Handler) 포함 또는 <receiver> 태그를 권한이 부여된 브로드캐스터만 <uses-permission> 태그 나중에 해당 권한이 부여된 경우 위험한 경우)는 수신자에게 인텐트를 보낼 수 있습니다.

예를 들어 수신 앱에 다음과 같이 매니페스트에 선언된 수신기가 있다고 가정해 보겠습니다. 다음과 같습니다.

<receiver android:name=".MyBroadcastReceiver"
          android:permission="android.permission.BLUETOOTH_CONNECT">
    <intent-filter>
        <action android:name="android.intent.action.ACTION_FOUND"/>
    </intent-filter>
</receiver>

또는 아래와 같이 컨텍스트에 등록된 수신자가 수신 앱에 있습니다.

Kotlin

var filter = IntentFilter(Intent.ACTION_FOUND)
registerReceiver(receiver, filter, Manifest.permission.BLUETOOTH_CONNECT, null )

자바

IntentFilter filter = new IntentFilter(Intent.ACTION_FOUND);
registerReceiver(receiver, filter, Manifest.permission.BLUETOOTH_CONNECT, null );

그런 다음 이러한 수신기에 브로드캐스트를 보내려면 전송 앱이 아래와 같이 권한을 요청합니다.

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

보안 고려사항 및 권장사항

다음은 메일 전송 시 보안 고려사항 및 권장사항입니다. 수신하기:

  • 많은 앱이 동일한 브로드캐스트를 수신하도록 등록했다면 실행할 경우 시스템에서 많은 앱을 실행하여 기기 성능과 사용자 환경에 모두 상당한 영향을 미칠 수 있습니다. 피해야 할 사항 매니페스트 선언보다 컨텍스트 등록을 사용하는 것이 좋습니다. 때때로 Android 시스템 자체에서 목록에 등록된 컨텍스트 기반 앱의 사용을 있습니다 예를 들어 CONNECTIVITY_ACTION 브로드캐스트가 전달됩니다. 컨텍스트 등록 수신기에만 적용됩니다

  • 암시적 인텐트를 사용하여 민감한 정보를 브로드캐스트하지 않아야 합니다. 이 정보는 브로드캐스트를 수신하도록 등록한 모든 앱에서 읽을 수 있습니다. 브로드캐스트를 수신할 수 있는 대상을 제어할 수 있는 방법은 다음과 같이 세 가지가 있습니다.

    • 브로드캐스트를 전송할 때 권한을 지정할 수 있습니다.
    • Android 4.0 이상에서는 패키지setPackage(String) 전송 시 있습니다. 시스템은 브로드캐스트를 패키지와 일치해야 합니다
  • 수신자를 등록하면 모든 앱이 잠재적으로 악성 콘텐츠를 앱의 수신기에 브로드캐스트할 수 있습니다. 다음 브로드캐스트를 수신할 수 있습니다.

    • broadcast receiver를 등록할 때 권한을 지정할 수 있습니다.
    • 매니페스트가 선언된 수신자의 경우 다음과 같이 android:exported 속성을 'false'로 설정 선언됩니다 수신자가 메시지를 받지 못함 앱 외부의 소스에서 브로드캐스트를 수신하게 됩니다.
  • 브로드캐스트 작업의 네임스페이스는 전역입니다. 작업 이름이 다른 문자열은 내가 소유한 네임스페이스에 작성됩니다. 그렇지 않으면 다른 앱과의 충돌을 일으키지 않습니다.

  • 수신자의 onReceive(Context, Intent) 메서드가 빠르게 실행되고 반환되어야 합니다. 필요한 경우 장기 실행 작업을 수행하고, 스레드 생성이나 시작에 주의하기 전체 프로세스를 종료할 수 있기 때문에 onReceive()가 반환됩니다. 자세한 내용은 프로세스에 미치는 영향 장기 실행 작업을 수행하기 위해 추천:

    • 다음에서 goAsync()에 전화: 수신자의 onReceive() 메서드를 호출하고 BroadcastReceiver.PendingResult를 백그라운드 스레드에 전달합니다. 이렇게 하면 onReceive()의 반환 후 브로드캐스트가 활성 상태로 유지됩니다. 그러나 이 접근 방식을 사용하더라도 시스템은 매우 빠르게 (10초 미만) 브로드캐스트합니다. 이 도구를 사용하면 다른 스레드에 전달하여 기본 스레드의 글리치를 방지합니다.
    • JobScheduler를 사용하여 작업을 예약합니다. 자세한 내용은 자세한 내용은 지능형 작업 일정 예약.
  • broadcast receiver에서 활동을 시작하지 않음 거슬립니다. 특히 두 개 이상의 수신자가 있는 경우에 그렇습니다. 대신 알림을 표시합니다.