Android기능_Notification&BroadcastReceiver&Service&Alarm

소정·2023년 3월 2일
1

Android_with_Java

목록 보기
19/33

[1]Notification (상태바 알림)

  • status바에 오는 알림.
  • 안드로이드의 13버전(API 33버전 - 티라미수버전)부터 알림에 대한 동적 허가(퍼미션)이 추가되었다

동적 퍼미션이란?
Java에서 퍼미션 요청 다이얼로그를 보여주는 방식

  • 33버전 이하는 퍼미션 무시됨

사용방법

1. 매니패스트에서 퍼미션 등록

2. 이 앱이 알림에 대한 퍼미션을 허용한 상태인지 체크

  • 물어보는 기능 액티비티에 있음 : checkSelfPermission() - 이건 26버전부터 있음 (오레오버전)
  • 운영체제 버전 상관없이 사용가능한 ContextCompat클래스의
    checkSelfPermission()를 쓴다

ContextCompat : 운영체제 호환성(Compat)

3. if문을 사용해 허용되었는지 체크

  • 리턴값 허가o : 0 (PackageManager.PERMISSION_GRANTED) / 허가x : -1 (PackageManager.PERMISSION_DENIED)
  • 13버전 이하는 다 리턴값 0으로 온다

4. 리턴값이 -1 일때 알림 허용을 요청하는 다이얼로그를 보이기

  • 다이얼로그는 안드로이드 자체적으로 갖고있음 - 개발자의 악의적 개발을 막기위해
  • 예전방식 : requestPermissions();
  • 현재방식 : permissionResultLancher 퍼미션 요청 결과를 받아주는 대행사 객체 이용 ( 얜 무조건 멤버변수 로 만들어줘야함 )

4-1) 퍼미션 요청 결과를 받아오는 작업을 대행해주는 객체 생성 및 등록 (멤버변수로 생성)

🔨 ActivityResultLauncher<스트링> permissionResultLancher = registerForActivityResult(어떤 종류의 계약이니?,결과 실행);

ActivityResultLauncher<String> permissionResultLancher = registerForActivityResult(new ActivityResultContracts.RequestPermission(), new ActivityResultCallback<Boolean>() {public void onActivityResult(Boolean result) {}
    });
    //퍼미션 요청 결과를 받아오는 작업을 대행해주는 객체 생성 및 등록
    ActivityResultLauncher<String> permissionResultLancher //퍼미션은 글자 덩어리라서 제네릭 String
            = registerForActivityResult(new ActivityResultContracts.RequestPermission(), new ActivityResultCallback<Boolean>() {
        @Override
        public void onActivityResult(Boolean result) {
            if(result) Toast.makeText(MainActivity.this, "알림 허용", Toast.LENGTH_SHORT).show();
            else Toast.makeText(MainActivity.this, "알림을 보낼 수 없습니다", Toast.LENGTH_SHORT).show();
        }
    });
    //Contracts = 계약
    //registerForActivityResult(어떤 종류의 계약이니?,결과 실행);

4-2) if문 안에서 퍼미션 요청 결과를 받아주는 대행사 객체 이용

permissionResultLancher.launch(Manifest.permission.POST_NOTIFICATIONS);

**5. if문 이후 (알림허용 받은 뒤) 알림(Notification)을 관리하는 관리자 객체 소환 : NotificationManager**
  • 운영체제에서 받아옴
  • 자주쓰는 것이 아니라 바로 못부르고 comtext안에서 찾아야함 : getSystemService(식별자)

**6. 알림 매니저에게 알림을 보이도록 요청 : notificationManager**

6-1) 알림객체 Notification 만들기

  • 건축가(builder)에게 알림객체 생성을 요청해야함

6-2) 알림객체를 생성해주는 건축가(builder)객체 생성

6-3) 알림채널 생성 : 운영체제 26버전 이전과 이후로 나누어 작업

📢 중요도에 따른 알림 화면

1. IMPORTANCE_HIGH : 소리 + 알림표시 + 화면 가리기 + 제일 앞

  1. IMPORTANCE_DEFAULT : 소리 + 알림표시
  2. IMPORTANCE_LOW : 알림표시

Build.VERSION.SDK_INT
사용자의 운영체제 얻어오는 것
Build.VERSION_CODES.O
api 버전

6-4) 빌더에게 알람에 관련된 설정

6-5) Notification notification한테 위에서 만든 빌더를 대입

6-6) 알림을 확인하면 상태표시줄에서 없어지도록 하기

  • 인텐트가 있을때만 쓸수 있는 기능임

참고) 요즘들어 보이는 알림창 style 꾸미기
① 알림창에 큰 이미지 넣기

② 알림에 화면 여러곳 가게 하고 싶은 때

  1. 사운드,진동 작업!! - 26버전 이전과 이후로 나눠줘야함
    26버전 이상 채널한테 set 이전 버전 builder한테 set

🧨 진동은 사용자에게 퍼미션 받아야함


총 코드

package com.bsj0420.ex58notification;

import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioAttributes;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.btn).setOnClickListener(view -> click());

    }

    private void click() {
        //안드로이드의 13버전(API 33버전 - 티라미수버전)부터 알림에 대한 동적 허가(퍼미션)이 추가되었다
        //이 앱이 알림에 대한 퍼미션을 허용한 상태인지 체크
        //물어보는 기능 액티비티에 있음
        //checkSelfPermission() // 이건 26버전부터 있음 (오레오버전) 
        // ContextCompat : 운영체제 호환성(Compat)
        int checkResult=ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS); //운영체제 버전 상관없이 사용가능
        //허가o : 0 허가x : -1 / 13버전 이하는 다 0으로 온다
        if(checkResult == PackageManager.PERMISSION_DENIED) {
            //알림 허용을 요청하는 다이얼로그를 보이기
            //다이얼로그는 안드로이드 자체적으로 갖고있음 - 개발자의 악의적 개발을 막기위해
            //requestPermissions(); //예전방식
            
            //퍼미션 요청 결과를 받아주는 대행사 객체 이용 - 얜 무조건 멤버변수로 옴
            permissionResultLancher.launch(Manifest.permission.POST_NOTIFICATIONS);
            return; //다이아로그 띄우고 멈춰
        }

        //5. 
        //알림(Notification)을 관리하는 관리자 객체 소환 : NotificationManager
        //운영체제에서 받아옴 : 자주쓰는 것이 아니라 바로 못부르고 comtext안에서 찾아야함 getSystemService(식별자)
        NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
        //리턴값이 Object라서 NotificationManager으로 형변환

        //////////////////////////////////////////////////////////////////////////////////////////////
        //6-2
        //알림객체를 생성해주는 건축가(builder)객체 생성
        NotificationCompat.Builder builder = null;

        //6-3 알림채널 생성
        //빌더를 생성하는 문법이 26버전부터 변경 (오레오)
        //알림채널이라는 개념이 도입됨
        //그래서 26버전 이상의 문에서는 알림채널객체를 생성해야하고
        //그 이전버전에서는 알림채널객체 생성없이 빌더를 만들어야함
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // ★ Build.VERSION.SDK_INT 사용자의 운영체제 버전에 따른 분기처리
            // Build.VERSION_CODES.O : api 버전
            
            //알림채널 객체 생성 (채널아이디, "채널에 보여질 글씨, 중요도)
            NotificationChannel channel = new NotificationChannel("ch01","Ex58Channel",NotificationManager.IMPORTANCE_HIGH); //소리 + 알림표시 + 화면 가리기 + 제일 앞
            //NotificationChannel channel = new NotificationChannel("ch01","Ex58Channel",NotificationManager.IMPORTANCE_DEFAULT); //소리 + 알림표시
            //NotificationChannel channel = new NotificationChannel("ch01","Ex58Channel",NotificationManager.IMPORTANCE_LOW); //알림표시

            //7-1) 사운드/진동 설정
            //Uri soundUri = RingtoneManager.getActualDefaultRingtoneUri(this,RingtoneManager.TYPE_NOTIFICATION); //기본소리
            Uri myUri = Uri.parse("android.resource://"+getPackageName() + "/"+ R.raw.s_goodjob); //사운드 경로 지정
            //android.resource : R폴더 지정 + 내 패키지명 + 소리파일
            channel.setSound(myUri, new AudioAttributes.Builder().build());

            //진동
            //진동은 사용자 정적 퍼미션 요구됨

            channel.setVibrationPattern(new long[]{0,2000,1000,3000}); //대기 , 떨기, 대기, 떨기

            //매니저한테 채널을 등록하기 전에 사운드 작업 해야한다
            notificationManager.createNotificationChannel(channel); //매니저한테 등록

            builder = new NotificationCompat.Builder(this,"ch01");

        } else {
            builder = new NotificationCompat.Builder(this,""); //채널이 없으니 id로 그냥 빈 문자열

            Uri myUri
                    = Uri.parse("android.resource://"+getPackageName() + "/"+ R.raw.s_goodjob); //사운드 경로 지정
            builder.setSound(myUri); //이전 버전에선 builder 한테 준다
        }
        
        //6-4
        //빌더에게 알람에 관련된 설정
        //6-4-1) 상태표시줄에 보이는 아이콘
        builder.setSmallIcon(R.drawable.ic_noti);
        //6-4-2) 상태바를 내렸을 때 확장된 알림창 대한 설정
        builder.setContentTitle("정신 똑바로 차려");
        builder.setContentText("알림 보내기가 호락호락한 작업이 아니다...");
        //6-4-3) 이미지 추가
        //이미지를 자바가 읽을 수 있는 객체 : Bitmap
        Resources res = getResources(); //Context능력중 하나인데 자주쓰는 애라 바로 getResources() 있음
        Bitmap bm = BitmapFactory.decodeResource(res,R.drawable.thumb_moana);
        builder.setLargeIcon(bm);
        //builder.setWhen() : 보낸 시간

        //6-4-4) 알림창을 클릭했을 때 새로운 화면(SecondActivity)가 실행되도록
        Intent intent = new Intent(this, SecondActivity.class);
        //intent는 부르자마자 바로 실행해야함
        //하지만 지금  쓰려는 인텐트는 알림을 눌러야만 실행되는 것
        //인텐트 객체에게 바로 실행하지말고 잠시 보류해달라고 해야함
        //보류중인 인텐트 PendingIntent 객체로 생성
        PendingIntent pendingIntent
                = PendingIntent.getActivity(this,10,intent,PendingIntent.FLAG_IMMUTABLE); 
        //(context,보류중인 친구의 번호,intent,보류중인데 또 오면 처리 - 무조건 FLAG_IMMUTABLE)

        builder.setContentIntent(pendingIntent); // PendingIntent : 보류중인...

        //6-6 알림을 확인하면 상태표시줄에서 없어지도록 하기
        builder.setAutoCancel(true); //인텐트가 있을때만 쓸수 있는 기능임

        // 참고) 요즘들어 보이는 알림창 style 꾸미기
//        Notification.BigPictureStyle style = new Notification.BigPictureStyle();
//        style.bigPicture(BitmapFactory.decodeResource(res,R.drawable.moana04));
//        builder.setStyle(style); //BigPictureStyle 매개변수에 빌더주면 setStyle안해도됨
        
        //알림창 클릭 액션에 의해 실행될 화면이 여러개 일때 실행하는 기능
        builder.addAction(R.drawable.ic_noti, "setting", pendingIntent);
        builder.addAction(R.drawable.ic_noti, "Impormation", pendingIntent);

        //6-1 알림객체 Notification 만들기
        //건축가(builder)에게 알림객체 생성을 요청해야함
        //6-5 위에서 만든 빌더를 대입해준다
        Notification notification = builder.build();

        //6.
        //알림 매니저에게 알림을 보이도록 요청
        notificationManager.notify(100,notification); //notify(식별번호(누구의 알림인지),알림객체)
        
        /////////////////////////////////////////////////////////////////////////////////

        //7. 사운드,진동 작업!! - 채널별로 해줘야함
        
    }

    //4-1) 퍼미션 요청 결과를 받아오는 작업을 대행해주는 객체 생성 및 등록
    ActivityResultLauncher<String> permissionResultLancher //퍼미션은 글자 덩어리라서 제네릭 String
            = registerForActivityResult(new ActivityResultContracts.RequestPermission(), new ActivityResultCallback<Boolean>() {
        @Override
        public void onActivityResult(Boolean result) {
            if(result) Toast.makeText(MainActivity.this, "알림 허용", Toast.LENGTH_SHORT).show();
            else Toast.makeText(MainActivity.this, "알림을 보낼 수 없습니다", Toast.LENGTH_SHORT).show();
        }
    });
    //Contracts = 계약
    //registerForActivityResult(어떤 종류의 계약이니?,결과 실행);
}



[2] Broadcast Receiver

  • 4대 구성요소중 하나
  • 방송 수신기
  • 디바이스의 특정 상태(문자수신, 배터리 부족, 부팅완료, gps 상태정보 등등..]를 OS 에서 방송해주면 이를 수신할 때 사용
  • 내 폰의 상황을 모든 앱들한테 정보 공유
  • Intent로 실행함

💡 방송(Broadcast)이란?

Intent객체가 날아가는것이다
실제 전파를 쏜다는 것이 아니라 Intent 객체가 모든 앱에게 전달되는 모습
방송을 보낸다는 것은 Intent를 모든 앱에게 보내는 것임

1. 내가 만들어서 보내보기 - 어떻게 동작하는지 알기 위해 해보기

인텐트 보내는 2가지 방법

1) 명시적 인텐트

  • 특정한 한 놈(리시버)한테만 보내는 방송
  • 본인 앱에서만 수신할 수 있다 (블루투스나 nfc 작업 할때나 쓴다)

2) 암시적 인텐트

  • 특별한 식별(action)을 이용해 intent-filter로 내가 듣고싶은 식별자만 받음
  • 디바이스에 설치된 모든 앱 안에 있는 리시버가 듣는 방송
  • 안드로이드 운영체제에서 보내는 방송은 대부분 암시적 인텐트임
  • 오레오 버전부터 암시적 인텐트방송은 System만 할수 있다

사용방법

1) 명시적 인텐트

방송을 받으면 토스트 띄워보기


main.java

package com.bsj0420.ex59broadcastreceiver;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.btn).setOnClickListener(view -> clickBtn());

    }

    private void clickBtn() {
        //브로드캐스트 보내기
        //원래 브로드캐스트는 안드로이드라는 운영체제가 보내는 것이다
        //이 예제에서는 실습 목적으로 보내보기

        //방송이란?
        //실제 전파를 쏜다는 것이 아니라 **Intent** 객체가 **모든 앱에게 **전달되는 모습
        //방송을 보낸다는 것은 Intent를 모든 앱에게 보내는 것임
        
        //인텐트 보내는 2가지 방법
        //1. 명시적 인텐트 - 특정한 한 놈(리시버)한테만 보내는 방송
        //1-1) 새로운 리시버 생성(BroadcastReceiver 상속받은 클래스를 만들어서 인텐트로 실행)
        Intent intent = new Intent(this, MyReceiver.class);
        sendBroadcast(intent);

    }
}

MyReceiver.java

  • BroadcastReceiver를 상속받은 클래스파일 생성
  • 4대 컴포넌트 : 반드시 매니패스트에 등록
package com.bsj0420.ex59broadcastreceiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

//안드로이드의 4대 컴포넌트 클래스들은 반드시 매니패스트에 꼭 반드시 등록해야만한다

public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) { //intent = 방송으로 온애
        //방송을 수신했을 때 자동으로 실행하는 콜백메소드

        Toast.makeText(context, "Receive", Toast.LENGTH_SHORT).show();

    }
}


2) 암시적 인텐트

  • 모두에게 방송 보내고 받는 애들이 선별적으로 받기

  • 보내는 인텐트 식별자(action)을 붙여주고 매니패스트에서 받을 애만 필터에 액션 네임을 추가해준다

  • 오레오 버전부터 암시적 인텐트방송은 System만 할수 있다

  • 그럼에도 꼭 암시적 인텐트를 보내고싶다면 리시버를 매니패스트가 아닌

  • 자바에서 동적으로 등록하면 테스트 가능


아래 작업은 테스트 목적으로 한 것

main.java

package com.bsj0420.ex59broadcastreceiver;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.btn).setOnClickListener(view -> clickBtn());

    }

    private void clickBtn() {
        //2. 암시적 인텐트 - 특별한 식별(action)을 이용해
        // 디바이스에 설치된 모든 앱 안에 있는 리시버가 듣는 방송
        // 안드로이드 운영체제에서 보내는 방송은 대부분 암시적 인텐트임
        // 오레오 버전부터 암시적 인텐트방송은 System만 할수 있다
        //그럼에도 꼭 암시적 인텐트를 보내고싶다면 리시버를 매니패스트가 아닌 
        //자바에서 동적으로 등록하면 테스트 가능
        Intent intent = new Intent();
        intent.setAction("aaa"); //방송을 구별하는 식별자(action)
        sendBroadcast(intent);
        
    }
    
    //멤버변수로 마이리시버 만든다
    MyReceiver myReceiver;
    
    //액티비티가 화면에 보여질때 자동으로 실행되는 콜백 메소드
    @Override
    protected void onResume() { //액티비티가 화면에 보여질때 얘가 불러짐
        super.onResume();

        //리시버를 등록
        //동적 등록
        myReceiver = new MyReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction("aaa");

        //리시버를 등록하면서 필터도 설정
        registerReceiver(myReceiver,filter);
    }

    //액티비티가 화면에서 안보이기 시작할 때 자동으로 실행되는 콜백메소드
    @Override
    protected void onPause() {
        super.onPause();

        //화면이 꺼지면 리시버 등록 해제
        unregisterReceiver(myReceiver);

    }
}

MyReceiver.java

리시버는 명시적 마이리시버와 같음


2. 실제로 시스템이 보내는 리시버 해보기!!(여기가 중요)

사용방법

MyReceiver.java

package com.bsj0420.ex60broadcastreceiverbooting;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

//4대 컴포넌트 반드시 매니패스트에 등록
public class MyBootingReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //안드로이드 13버전부터 액티비티가 없으면 Toast의 발동을 제한함
        Log.i("Ex60", "BootingReceiver");
    }
}

부팅완료 리시버 사용하기 위해
안드로이드의 N 버전(api 25) 부터 부팅완료를 들으려면
앱을 설치한 후 적어도 1회 사용자가 직접 런처 화면(앱 목록)에서
앱을 실행한 이력이 있는 앱만 부팅완료를 들을 수 있다
해커들을 막기위해(앱을 몰래 심는것을 방지하기 위해서)

부팅 완료되면 MainActivity 화면이 실행되도록 업그레이드 해보기

  • 안드로이드 10버전(api29) 부터 리시버에서 직접 액티비티 실행 금지
    => 폰 켜자마자 얍 홍보한다고 띄우니까 사용자 열받음....앱 홍보 금지하기 위해
  • 대신 알림(Notification)을 통해 사용자에게 신호를 주고 액티비티 실행할지 여부 선택하도록 변경됨
package com.bsj0420.ex60broadcastreceiverbooting;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.util.Log;

import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationChannelCompat;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;

//4대 컴포넌트 반드시 매니패스트에 등록
public class MyBootingReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //안드로이드 13버전부터 액티비티가 없으면 Toast의 발동을 제한함
        Log.i("Ex60", "BootingReceiver");

        //안드로이드의 N 버전(api 25) 부터 부팅완료를 들으려면 
        //앱을 설치한 후 적어도 1회 사용자가 직접 런처 화면(앱 목록)에서  
        //앱을 실행한 이력이 있는 앱만 부팅완료를 들을 수 있다 - 해커들을 막기위해(앱을 몰래 심는것을 방지하기 위해서)

        //부팅 완료되면 MainActivity 화면이 실행되도록
        //단, 리시버가 여러개면 내가 받으려는것을 구분하기 위해 액션값을 받아 구분
        String action = intent.getAction();
        if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {

            //안드로이드 10버전(api29) 부터 리시버에서 직접 액티비티 실행 금지
            // => 폰 켜자마자 얍 홍보한다고 띄우니까 사용자 열받음....앱 홍보 금지하기 위해
            //대신 알림(Notification)을 통해 사용자에게 신호를 주고 액티비티 실행할지 여부 선택하도록 변경됨
            if (Build.VERSION.SDK_INT >= 29) {

                //1.알람매니저
                NotificationManagerCompat manager = NotificationManagerCompat.from(context);

                //3.채널 생성
                NotificationChannelCompat channel
                        = new NotificationChannelCompat.Builder("ch01", NotificationManagerCompat.IMPORTANCE_HIGH).setName("Ex60").build();

                //4.채널 등록
                manager.createNotificationChannel(channel);

                //2.알림객체를 만들어주는 빌더 필요
                NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "ch01");

                //5.
                builder.setSmallIcon(R.drawable.ic_stat_name);
                builder.setContentText("부팅완료 됨");
                builder.setContentTitle("부팅완료");

                //6. 매니저에 notify 
                if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
                    return;
                } //퍼미션 없음 멈춰라고 하는 거
                manager.notify(100, builder.build()); //안드로이드 13버전부터 알림 동적퍼미션 생김 그래서 오류
                // => 매니패스트에 퍼미션 등록

                //7. 동적 퍼미션 + 팬딩인텐트 달기
                

            } else {
                //29버전 이하는 바로 액티비티로 변경 가능
                Intent intentForActivity = new Intent(context, MainActivity.class);
                //addFlags() : 백스택에 현재 아무것도 쌓여있지않아 필요한 설정
                intentForActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(intentForActivity);
            }

        }
    }
}

addFlags()
백스택에 현재 아무것도 쌓여있지않아 필요한 설정


매니패스트

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <!-- 부팅완료 듣는 퍼미션 2 : 앱 전체한테 등록 -->
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

    <!-- 알림을 보여주는 파미션 -->
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Ex60BroadcastReceiverBooting"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- 부팅완료 방송을 수신하는 리시버 등록
            인텐트 필터를 쓰면 암시적으로 부르겠단 뜻이고 꼭 exported="true"
            부팅완료 듣는 퍼미션 내 앱에도 등록**
        -->
        <receiver android:name=".MyBootingReceiver"
            android:exported="true"
            android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>
    </application>

</manifest>



profile
보조기억장치

0개의 댓글