Android # Notification
안드로이드/Android-Dev

Android # Notification

Notification

알람(Notification)은 화면 상단에 정보를 표시하여 사용자가 알 수 있도록 한다. 이 알림 기능은 주로 다른 사람에게서 메시지를 받았을 때나, 단말의 상태, 특정 앱의 상태변화 등의 목적으로 사용된다.

알림은 NotificationManager 시스템 서비스를 이용해 화면 상단에 띄울 수 있다. 알림을 띄우려면 Notification 객체를 만들어야 하는데, 이 객체는 NotificationCompat.Builder 객체를 이용해서 만든다.

Example

Notification을 발생시키는 버튼을 만들고, 버튼을 터치할 때마다 터치 횟수를 증가시키는 변수(count)를 만든다.
최종적으로 Notification에 의해서 전달되는 값은 마지막에 전달한 값이 되는 걸 확인하기 위한 예제이다.
즉, 터치를 할 때마다 Notification이 발생하지만, Notification을 클릭 했을 때 마지막 값(총 터치 횟수)을 띄워주는 것을 볼 것이다.
[초기화면]


초기 버튼만 있는 상태이다. 버튼을 클릭하게되면 count변수가 증가하고, Notification이 발생한다.


[Notification 발생 상태]

발생한 Notification을 클릭하지 않고, 버튼만 터치한다면 count의 수만 증가하게 된다.
Notification을 누르게 되면, 마지막 count값(총 터치횟수)을 intent로 전달한다.


[Notification 클릭 후 상태]



소스코드

[ativity_main.xml]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?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">
 
    <Button
        android:id="@+id/button"
        android:layout_marginTop="500px"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button" />
</LinearLayout>
cs

Notification과 count를 증가시키는 버튼.

[MainActivity.java]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package org.techtown.noti;
 
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
 
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
 
public class MainActivity extends AppCompatActivity {
 
    private static String NOTIFICATION_CHANNEL_ID = "channel1";
    private int count = 0;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                count++;
                NotificationSomethings();
            }
        });
    }
 
    public void NotificationSomethings() {
        NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
 
        Intent notificationIntent = new Intent(this, ResultActivity.class);
        notificationIntent.putExtra("notificationId", count); //전달할 값
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK) ;
        PendingIntent pendingIntent = PendingIntent.getActivity(this0, notificationIntent,  PendingIntent.FLAG_UPDATE_CURRENT);
 
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground)) //BitMap 이미지 요구
                .setContentTitle("상태바 드래그시 보이는 타이틀")
                .setContentText("상태바 드래그시 보이는 서브타이틀")
                // 더 많은 내용이라서 일부만 보여줘야 하는 경우 아래 주석을 제거하면 setContentText에 있는 문자열 대신 아래 문자열을 보여줌
                //.setStyle(new NotificationCompat.BigTextStyle().bigText("더 많은 내용을 보여줘야 하는 경우..."))
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                .setContentIntent(pendingIntent) // 사용자가 노티피케이션을 탭시 ResultActivity로 이동하도록 설정
                .setAutoCancel(true);
 
        //OREO API 26 이상에서는 채널 필요
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
 
            builder.setSmallIcon(R.drawable.ic_launcher_foreground); //mipmap 사용시 Oreo 이상에서 시스템 UI 에러남
            CharSequence channelName  = "노티페케이션 채널";
            String description = "오레오 이상을 위한 것임";
            int importance = NotificationManager.IMPORTANCE_HIGH;
 
            NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName , importance);
            channel.setDescription(description);
 
            // 노티피케이션 채널을 시스템에 등록
            assert notificationManager != null;
            notificationManager.createNotificationChannel(channel);
 
        }else builder.setSmallIcon(R.mipmap.ic_launcher); // Oreo 이하에서 mipmap 사용하지 않으면 Couldn't create icon: StatusBarIcon 에러남
 
        assert notificationManager != null;
        notificationManager.notify(1234, builder.build()); // 고유숫자로 노티피케이션 동작시킴
    }
}
 
cs

NotificationSomethings 메서드에서는 NotificationManager 객체를 참조한 후 NotificationCompat.Builder 객체를 생성한다. 그런데 안드로이드 오레오 버전 이전과 이후에 Builder 객체를 만드는 방법이 다르기 때문에 Build.VERSION.SDK_INT 상수의 값을 비교여 단말의 OS 버전에 따라 다른 코드가 실행되도록 한다. 오레오 이후 버전에서는 알림 채널이 지정되어야 하며, 채널은 createNotificationChannel() 메서드를 이용해 생성한다. Builder 객체가 만들어지면 알림 정보를 설정할 수 있다. 각각의 알림 정보를 설정하고 Builder 객체의 build() 메서드를 호출하면 Notification 객체가 생성된다. NotificationManager의 notify() 메서드를 호출하면서 이 Notification 객체를 파라미터로 전달하면 알림을 띄우게 된다.

[ResultActivity.java]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package org.techtown.noti;
 
import android.app.NotificationManager;
import android.content.Context;
import android.os.Bundle;
import android.widget.TextView;
 
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
 
public class ResultActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        setContentView(R.layout.result_main);
 
 
        String text = "전달 받은 값은";
        int id = 0;
 
        Bundle extras = getIntent().getExtras();
        if (extras == null) {
            text = "값을 전달 받는데 문제 발생";
        }
        else
            id = extras.getInt("notificationId");
 
        TextView textView = (TextView) findViewById(R.id.textView);
        textView.setText(text + " " + id);
 
        NotificationManager notificationManager =  (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
main
 
        //노티피케이션 제거
        notificationManager.cancel(id);
    }
}
cs

Notification을 통해서 전달받은 값(총 터치 횟수)을 보여준다.

[result_main.xml]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">
 
    <Button
        android:text=""
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="20dp"
        android:id="@+id/textView" />
 
</androidx.constraintlayout.widget.ConstraintLayout>
cs

[AndroidManifest.xml]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.techtown.noti">
 
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
 
        <activity
            android:name=".ResultActivity"
            android:parentActivityName=".MainActivity" >
        </activity>
 
    </application>
 
</manifest>
cs

**ResultActivity**를 manifest에 추가해준다.

'안드로이드 > Android-Dev' 카테고리의 다른 글

Android # setContentView(+Inflater)  (0) 2020.02.04
Android # SharedPreferences  (0) 2019.12.17
Android # 진동과 소리 울리기  (2) 2019.12.16
Android # baseline(view)  (0) 2019.12.14
Android # gravity 속성들  (0) 2019.12.14