84일차(2)/Android App(48) : Notification(1)
새 모듈 생성- empty activity
step21notification
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="메세지 입력..."
android:id="@+id/inputMsg"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="자동 취소 되는 알림"
android:id="@+id/notiBtn"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="수동 취소 되는 알림"
android:id="@+id/notiBtn2"/>
</LinearLayout>
MainActivity
package com.example.step21notification;
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.os.Build;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
public class MainActivity extends AppCompatActivity {
//알림 체널의 이름 정하기
public static final String CHANNEL_NAME = "com.example.step21notification.MY_CHANNEL";
//필요한 필드
EditText inputMsg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
inputMsg = findViewById(R.id.inputMsg);
//Auto Cancel 버튼을 눌렀을때 동작
Button notiBtn = findViewById(R.id.notiBtn);
notiBtn.setOnClickListener(v -> {
makeAutoCancelNoti();
});
}
public void makeAutoCancelNoti(){
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
//권한이 필요한 목록을 배열에 담는다.
String[] permissions={Manifest.permission.POST_NOTIFICATIONS};
//배열을 전달해서 해당 권한을 부여하도록 요청한다.
ActivityCompat.requestPermissions(this,
permissions,
0); //요청의 아이디
return;
}
//입력한 문자열을 읽어온다.
String msg = inputMsg.getText().toString();
createNotificationChannel();
//알림을 클릭했을때 활성화시킬 액티비티 정보를 담고 있는 Intent 객체
Intent intent = new Intent(this, DetailActivity.class);
//액티비티를 실행하는데 새로운 태스크에서 실행되도록 한다(기존에 onStop() 에 머물러 있다면 제거하고 새로 시작)
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK);
//intent에 msg라는 키값으로 String type을 담는다. 새로 시작된 액티비티에서 읽어낼 수 있다.
intent.putExtra("msg", msg);
//알림의 아이디 얻어내기 (값이 겹치지않게)
int currentId = (int) (System.currentTimeMillis() / 1000);
//인텐트 전달자 객체
PendingIntent pendingIntent = PendingIntent.getActivity(this, currentId, intent, PendingIntent.FLAG_MUTABLE);
//띄울 알림을 구성하기
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_NAME)
.setSmallIcon(android.R.drawable.ic_btn_speak_now) //알림의 아이콘
.setContentTitle("얘들아 나야~") //알림의 내용
.setContentText(msg) //알림의 내용
.setPriority(NotificationCompat.PRIORITY_DEFAULT) //알림의 우선순위
.setContentIntent(pendingIntent) //인텐트 전달
.setAutoCancel(true); //자동 취소되는 알림인지 여부
//알림 만들기
Notification noti=builder.build();
//알림 매니저를 이용해서 알림을 띄운다.
NotificationManagerCompat.from(this).notify(currentId, noti);
}
//앱의 사용자가 알림을 직접 관리 할수 있도록 알림 채널을 만들어야한다.
public void createNotificationChannel(){
//알림 채널을 지원하는 기기인지 확인해서
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//알림 채널을 만들기
//셈플 데이터
String name="삼성카드";
String text="테스트!";
//알림 채널 객체를 얻어내서
NotificationChannel channel=
new NotificationChannel(CHANNEL_NAME, name, NotificationManager.IMPORTANCE_DEFAULT);
//채널의 설명을 적고
channel.setDescription(text);
//알림 매니저 객체를 얻어내서
NotificationManager notiManager=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
//알림 채널을 만든다.
notiManager.createNotificationChannel(channel);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case 0:
//권한을 부여 했다면
if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
//자동 취소 알림 띄우기
makeAutoCancelNoti();
}else{//권한을 부여 하지 않았다면
Toast.makeText(this, "알림을 띄울 권한이 필요합니다.",
Toast.LENGTH_SHORT).show();
}
break;
}
}
}
- 폰에 알림 띄우기!
- 자동 취소되는 알림 / 수동 취소되는 알림 띄우는 방법
- static final 상수로 "패키지명+채널명" 을 정의해준다.
- 패키지명은 모듈이 만들어진 패키지를 정확히 / 채널명은 마음대로 정하면 된다.
- 알림 채널을 지원하는 기기인지 확인해서 알림 채널을 만들어주기
(if문 부분의 Build.version을 확인하는 코드)
- inputText 안에 msg라는 키값으로 들어온 값을 intent에 전달한다!
- 알림을 클릭했을 때 활성화시킬 액티비티 정보를 담고 있는 Intent 객체
- 이렇게 여러번 호출해서 쓸 수 있는 것은 리턴타입이 this이기 때문이다!
- NotificationCompat.Builder 객체를 사용한다.
- 클릭시 자동으로 사라지는 알림
- 권한 체크 요청(requestPermission) 을 하고, 승인되면
- 아래에서 이 메소드를 다시 호출하도록 한다.
- 그러면 inputMsg의 문자열을 읽어내고, 알림채널을 만들고 intent 객체로 전달한다.
- 지금은 MainActivity로 이동하도록 했는데 나중엔 다른 액티비티로 이동하도록 해볼 것!
- intent에 플래그 옵션을 지정해준 것이다.
- putExtra로 키값을 담으면 MainActivity에서 읽어낼 수 있다. (getStringExtra로)
- 알림의 아이디는 왜 필요할까?
→ 나중에 수동으로 취소하려면 알림별로 아이디를 지정해주어야 한다.
→ 그래서 값이 겹치면 안되어서 겹치지 않는 숫자를 임의로 얻어냈다(큰 정수값을 얻어내도록 함)
- PendingIntent 인텐트 전달자 객체에 intent를 담아서
NotificationCompat.Builder 에 넣어준다.
- 주석으로 builder의 인자들 설명!
- setAutoCancel(true) 로 설정하면 알림을 읽는 순간(터치하면) 알림이 자동으로 사라진다.
Notification noti=builder.build();
NotificationManagerCompat.from(this).notify(currentId, noti);
- 이 builder.build() 가 notificaton 타입이다. 조금 풀어서 쓰면 이런 코드가 된다.
- 메시지를 보내면 기기에 알림을 보낼 수 있는지 승인을 요청하는 창이 뜬다.
- 위쪽 알림 바에 뭔가 생겨난 것을 볼 수 있다.
- 이렇게 알림이 뜬다. 알림을 클릭하면 다시 MainActifvity가 나타난다.
- 알림을 표시하려면 이렇게 permission이 설정되어 있어야 한다.
- 알림에 가보면 이렇게 알림 채널이 있다.
- 알림 채널 안에 들어가면 이렇게 알림채널에 대한 세부적인 설정을 할 수 있다.
- 여기서 알림채널의 이름을 설정한 것이다.
- 이름(name), 설명(text) 부분을 이렇게 수정하면 여기에 뜬다.
- 이렇게 NotificationChannel 객체를 따로 생성하지 않으면 알림이 오지 않는다!
- 액티비티 추가
DetailActivity
package com.example.step21notification;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class DetailActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
//전달된 intent 객체
Intent intent = getIntent();
//intent 객체에 "msg"라는 키값으로 전달된 문자열 얻어내기
String msg=intent.getStringExtra("msg");
//TextView에 출력해보기
TextView textView=findViewById(R.id.textView);
textView.setText(msg);
}
}
activity_detail.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.step21notification.DetailActivity"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:id="@+id/textView"/>
</LinearLayout>
- 이 intent를 detail Activity로 전달하기
- MainActivity에서 위와 같이 Intent 객체를 생성해서 값을 넣어주고,
DetailActivity에서 .getIntent() 하면 된다.
- 입력받은 메시지(msg)가 DetailActivity에 출력된다!
'국비교육(22-23)' 카테고리의 다른 글
85일차(2)/Android App(50) : Service / Binder 객체로 mp3파일 재생하기 (0) | 2023.02.10 |
---|---|
85일차(1)/Android App(49) : Notification(2) (0) | 2023.02.09 |
84일차(1)/Android App(47) : Content Provider (0) | 2023.02.08 |
83일차(1)/Android App(46) : 전화걸기 기능 구현 (0) | 2023.02.07 |
[Android Studio] 모듈 의존성 제거 (모듈 삭제) (0) | 2023.02.07 |