본문 바로가기
개발일기/부산버스

android 오레오 적용기

by 유주원 2018. 10. 31.




구글에서 위와 같은 엄포장이 날라왔다!!!

핵심은 11/1일 이전에 targetSdk version을 26이상으로 맞추라는 거였다.


'그래.. 업데이트 한지도 오래됐으니깐 맞춰줄께~'


너무 쉽게 생각했었을까?? 바꿔야 할 게 너무 많았다.


일단 무턱대고 gradle의 targetsdk를 26으로 변경하고 build 했다. (support:appcompat-v7은 23.0.0, compileSDKVersion도 23으로 유지)


'어~ build 잘되네.. 쉽자나~'


내 폰에서만 확인해 본 후, 무턱대고 배포 ㄱㄱ를 진행했다.


결과적으로 targetsdk를 26으로 바꾸자마자 크게 2가지 문제가 발생했다.


참고로 아래의 두 가지 문제를 해결하기 위해서는 compileSDKVersion과 support:appcompat-v7을 각각 26, 26.0.0으로 바꿔줘야 한다.


그럼 이제 무엇이 문제가 되었는지를 살펴보자. 


첫번째는 선택 권한..


사용자는 앱 실행시에 권한을 허용할 것인지 아닌지에 대한 선택을 할 수가 있는데, 내 코드에는 그런 내용이 전혀 없었다.

그래서 사용자가 현재 위치를 통해 지도보기를 하는 경우 앱이 죽는 문제가 발생했다. ( 위치 권한이 없었기 때문에)


아래와 같이 앱 실행시 해당 권한이 허용되어 있는지를 확인한 후 해당 권한이 없다면 요청하는 코드를 추가하자.


if (ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

ActivityCompat.requestgPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, AppString.REQUEST_GPS);

}


위의 코드에서 AppString.REQUEST_GPS는 그냥 상수 class에 정의한 integer 이다.


public static final int REQUEST_GPS = 1;


해당 권한을 제대로 수여 받았는지 확인 하는 코드도 아래와 같이 만들 수가 있다.


@Override

public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {

switch(requestCode){

case AppString.REQUEST_GPS: {

if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

// 실행할 기능

}

return;

}

}

}




두번째는 알림 기능.


버스가 도착하기 몇 분전에 notification manager를 통해 알림을 보내 주는데 이 기능이 전혀 동작하지 않는 것이다.


debug를 찍다 보니 channal Id가 null이라는 warning 메시지가 발견되었고, 해당 키워드로 검색 결과 아래의 블로그를 발견했다.


http://gun0912.tistory.com/77



핵심은 안드로이드 오레오부터는 notification 보낼 때, channel id도 같이 보내줘야 notification 알람을 보내 줄 수가 있다고 한다. (오레오 이전 버전의 안드로이드에서는 알람이 정상 동작함)


하지만 오레오 이전 버전에서는 channel Id라는 항목이 아예 없기 때문에 코드로 버전을 분기쳐서 각각 처리를 해야 한다.

아래와 같이 처리하자.


private NotificationManager mNotificationManager = null;


@Override

public void onCreate() {

this.mNotificationManager = (NotificationManager) getSystemService(this.NOTIFICATION_SERVICE);


if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

String id = "channel_id";

CharSequence name = "testAlarm";

String description = "test";

NotificationChannel mChannel = new NotificationChannel(id, name, NotificationManager.IMPORTANCE_LOW);


mChannel.setDescription(description);

mChannel.enableLights(true);

mChannel.setLightColor(Color.RED);

mChannel.enableVibration(true);

mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});


mNotificationManager.createNotificationChannel(mChannel);

}

....

}


이렇게 notificationManager에 channel 정보를 추가하자.


그 후, notification을 보낼 때는 아래와 같이 하자.


NotificationCompat.Builder builder = new NotificationCompat.Builder(this)

.setSmallIcon(R.drawable.ic_action_alarms)

.setContentTitle("test")

.setContentText("test alarm")

.setContentIntent(intent);


if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

builder.setChannelId("channel_id");

}


Notification notification = builder.build();

notification.flags = Noptification.FLAG_ONGOING_EVENT;

mNotificationManager.notify(1, notification);