본문 바로가기
컴퓨터 공학/Android

[Do it 개정6판_안드로이드 스튜디오]둘째마당_15 푸시 서비스와 센서 및 단말 기능 사용하기

by hahehohoo 2019. 12. 3.
반응형

15-1 진동과 소리로 알려주기

- 사용자에게 무언가를 알려주는 가장 간단한 방법은 진동과 소리

- 안드로이드에서 진동은 얼마동안 안 울리도록 할 것인지 지정할 수 있음-> Vibrator라는 시스템 서비스 객체를 사용

 

> SampleVibrate 프로젝트

 

 

▼ MainActivity.java

package com.ogrg.techtown.vibrate;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.media.MediaPlayer;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    @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) {
                Vibrator vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);

                if(Build.VERSION.SDK_INT >= 26) {
                        vibrator.vibrate(VibrationEffect.createOneShot(1000,10));
                }else {
                        vibrator.vibrate(1000);
                }
            }
        });

        Button button2 = findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View v) {
                Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
                Ringtone ringtone = RingtoneManager.getRingtone(getApplicationContext(), uri);
                ringtone.play();
            }
        });

        Button button3 = findViewById(R.id.button3);
        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MediaPlayer player = MediaPlayer.create(getApplicationContext(), R.raw.beep);
                player.start();
            }
        });

    }
}

- 첫 번째 버튼 클릭했을 때는 Vibrator 객체를 참조

- 이 객체에는 vibrate() 메서드가 정의되어 있는데 안드로이드 버전 26부터 파라미터가 변경되었으므로 Build.VERSION.SDK_INT 상수의 값과 현재 단말의 OS 버전 값을 비교하자

 

- 두 번째 버튼을 클릭했을 때는 API에서 제공하는 기본 음원 재생 

- Ringtone 객체는 RingtoneManager.getRingtone() 메서드를 이용해 참조할 수 있음

 

- 세 번째 버튼을 클릭했을 때는 직접 지정한 음원을 재생하도록 했다. 

- rew 폴더 안에 들어있는 beep.wav 파일을 지정했다. 

 

★ 진동 권한 추가 방법

 

▼ AndroidManifest.xml

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

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

 

15-2 상단 알림으로 알려주기

- 알림(Notification)은 화면 상단에 정보를 표시하여 사용자가 알 수 있도록 한다. 

- NotificationManager 시스템 서비스를 이용해 화면 상단에 띄울 수 있다. 

 

> SampleNoti 프로젝트

▼ MainActivity.java

package com.ogrg.techtown.noti;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    NotificationManager manager;

    private static String CHANNER_ID = "channel1";
    private static String CHANNER_NAME = "channel1";

    private static String CHANNER_ID2 = "channel2";
    private static String CHANNER_NAME2 = "channel2";

    @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) {
                showNoti1();
            }
        });

        Button button2 = findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                showNoti2();
            }
        });
    }

    private void showNoti1() {
        manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);

        NotificationCompat.Builder builder = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            if (manager != null && manager.getNotificationChannel(CHANNER_ID) != null) {
                manager.createNotificationChannel(new NotificationChannel(
                        CHANNER_ID, CHANNER_NAME, NotificationManager.IMPORTANCE_DEFAULT
                ));
                builder = new NotificationCompat.Builder(this, CHANNER_ID);
            }

        }else{
            builder = new NotificationCompat.Builder(this);
        }
        if (builder != null) {
            builder.setContentTitle("간단 알림");
            builder.setContentText("알림 메세지입니다. ");
            builder.setSmallIcon(android.R.drawable.ic_menu_view);
            Notification noti = builder.build();

            manager.notify(1, noti);
        }

    }

    public void showNoti2() {
        manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        NotificationCompat.Builder builder = null;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                if (manager != null && manager.getNotificationChannel(CHANNER_ID2) != null) {
                    manager.createNotificationChannel(new NotificationChannel(
                            CHANNER_ID2, CHANNER_NAME2, NotificationManager.IMPORTANCE_DEFAULT
                    ));
                    builder = new NotificationCompat.Builder(this, CHANNER_ID2);
                }

            }else{
            builder = new NotificationCompat.Builder(this);
        }

        Intent intent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 101, intent, PendingIntent.FLAG_CANCEL_CURRENT);


        if (builder != null) {
            builder.setContentTitle("간단 알림");
            builder.setContentText("알림 메세지입니다. ");
            builder.setSmallIcon(android.R.drawable.ic_menu_view);
            builder.setAutoCancel(true);
            builder.setContentIntent(pendingIntent);
            Notification noti = builder.build();
            manager.notify(2, noti);

        }
    }
}

 

 

 

15-3 푸시 서비스 사용하기

■ 푸시 메세지란?

- 단말의 위쪽 부분에 보이는 상태바(Status Bar) 부분에 업데이트에 대한 메세지가 표시되면 사용자는 업데이트를 할 것인가의 여부를 결정하게 됨

 

1단계: 푸시 서비스 수신을 위한 새로운 프로젝트를 만들기

2단계: FCM 설정 페이지 프로젝트 만들기

3단계: 앱에서 푸시 서비스 사용을 위한 설정하기

4단계: FCM을 사용할 수 있도록 서비스 만들어 등록하기

5단계: 화면 레이아웃 만들기

6단계: 소스 코드에 단말 등록 기능 추가하기

7단계: 소스 코드에 메세지 수신 기능 추가하기

8단계: 메시지 전송 앱 만들기

9단계: 메시지 전송 앱의 코드 입력하기

 

> SamplePush 프로젝트

▼ MainActivity.java

package com.ogrg.techtown.push;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.InstanceIdResult;

public class MainActivity extends AppCompatActivity {
    TextView textView;
    TextView textView2;


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

        textView = findViewById(R.id.textView);
        textView2 = findViewById(R.id.textView2);

        FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(this, new OnSuccessListener<InstanceIdResult>() {
            @Override
            public void onSuccess(InstanceIdResult instanceIdResult) {
                String newToken = instanceIdResult.getToken();

                println("등록id : " + newToken);
            }
        });

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View v) {
                String instanceId = FirebaseInstanceId.getInstance().getId();
                println("확인된 인스턴스 id : " + instanceId);
            }
        });
    }

    @Override
    protected void onNewIntent(Intent intent) {
        println("onNewIntent 호출됨");

        if(intent != null) {
            processIntent(intent);
        }
        super.onNewIntent(intent);
    }

    private void processIntent(Intent intent) {
        String from = intent.getStringExtra("from");
        if(from == null){
            println("from is null.");
            return;
        }

        String contents = intent.getStringExtra("contents");

        println("DATA : " + from + ", "+contents);
        textView.setText("[" + from + "]로부터 수신한 데이터 : " + contents);
    }




    private void println(String s) {
        textView2.append(s + "\n");
    }

}

▼ MyFirebaseMessagingService.java

package com.ogrg.techtown.push;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.NonNull;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

import java.util.Map;

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "FMS";

    public MyFirebaseMessagingService() {

    }

    @Override
    public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
        Log.d(TAG, "onMessageReceived() 호출됨");

        String from = remoteMessage.getFrom();
        Map<String, String> data = remoteMessage.getData();
        String contents = data.get("contencs");
    }

    @Override
    public void onNewToken(@NonNull String s) {
        super.onNewToken(s);
        Log.e(TAG, "onMessageReceived() 호출됨");
    }


    private void sendToActivity(Context context, String from, String contents){
        Intent intent = new Intent(context, MainActivity.class);
        intent.putExtra("from",from);
        intent.putExtra("contents", contents);

        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|
                Intent.FLAG_ACTIVITY_SINGLE_TOP|
                Intent.FLAG_ACTIVITY_CLEAR_TOP);

        context.startActivity(intent);
    }


}

 

▼ AndroidManifest.xml

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

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

    <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">
        <service
            android:name=".MyFirebaseMessagingService"
            android:enabled="true"
            android:exported="true"
            android:stopWithTask="false"></service>

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.MESSAGING_EVENT" />
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

 

 

> SamplePushSend 프로젝트

 

▼ MainActivity.java

package com.ogrg.techtown.push.send;

import androidx.appcompat.app.AppCompatActivity;

import android.app.DownloadManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONArray;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

public class MainActivity extends AppCompatActivity {
    EditText editText;
    TextView textView;

    static RequestQueue requestQueue;
    static String regId;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText = findViewById(R.id.editText);
        textView = findViewById(R.id.textView);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                String input = editText.getText().toString();
                send(input);
            }
        });

        if (requestQueue == null) {
            requestQueue = Volley.newRequestQueue(getApplicationContext());
        }
    }

    public void send(String input) {
        JSONObject requestData = new JSONObject();

        try {
            requestData.put("priority", "high");

            JSONObject dataObj = new JSONObject();
            dataObj.put("contents", input);
            requestData.put("data", dataObj);

            JSONArray idArray = new JSONArray();
            idArray.put(0, regId);
            requestData.put("registration_ids", idArray);
        }catch (Exception e) {
            e.printStackTrace();
        }

        sendData(requestData, new SendResponseListener(){

            @Override
            public void onRequestCompleted(){
                println("onRequestCompleted 호출됨");

            }

            @Override
            public void onRequestStarted() {
                println("onRequestStarted 호출됨");

            }

            @Override
            public void onRequestWithError(VolleyError error) {
                println("onRequestWithError 호출됨");

            }
        });
    }

    public void println(String data){
        textView.append(data + "\n");
    }

    public interface SendResponseListener {
        public void onRequestStarted();
        public void onRequestCompleted();
        public void onRequestWithError(VolleyError error);
    }

    public void sendData(JSONObject requestData, final SendResponseListener listener) {
        JsonObjectRequest request = new JsonObjectRequest(
                Request.Method.POST,
                "https://fcm.googleapis.com/fcm/send",
                requestData,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        listener.onRequestCompleted();
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                listener.onRequestWithError(error);
            }
        }
        ){
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> params = new HashMap<String, String>();
                return params;
            }

            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                Map<String, String> headers = new HashMap<String, String>();
                headers.put("Authorization", "key=AIzaSyAGVSVmay1mbiJpf4RVRWqvpqphXSHkpoM");
                return headers;
            }

            @Override
            public String getBodyContentType() {
                return "application/json";
            }
        };

        request.setShouldCache(false);
        listener.onRequestStarted();
        requestQueue.add(request);
    }
}

 

▼ AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ogrg.techtown.push.send">

    <uses-permission android:name="android.permission.INTERNET"/>
    <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>
    </application>

</manifest>

 

 

 

소문난 명강의 오준석의 플러터 생존 코딩:Flutter와 Dart 입문부터 안드로이드와 iOS용 3가지 앱 개발까지, 한빛미디어이것이 자바다:신용권의 Java 프로그래밍 정복, 한빛미디어Hello Coding 프로그래밍:개념부터 처음 배우는, 한빛미디어처음 배우는 플러터:예제로 배우는 크로스 플랫폼 애플리케이션 개발, 한빛미디어돈 되는 안드로이드 앱 만들기:안드로이드 앱 개발을 위한 기본적이고 필수적인 내용 수록, 영진닷컴

 

 

반응형


댓글