2년 동안 방치된 Android 앱을 targetSdkVersion 21에서 targetSdkVersion 26으로 변경

소개



2년 정도 방치되어 있던 앱을 갱신하게 되었습니다만, 아시다시피,

앱 업데이트는 2018년 11월 1일부터 앱 대상을 Android 8.0(API 레벨 26) 이상으로 설정해야 합니다.

되어 있습니다.

업데이트하려는 앱의 targetSdkVersion을 확인하면 Android 5.0(API レベル 21)

어쩔 수 없기 때문에 필요한 작업을 확인하면서 targetSdkVersion 26 에 올려 갑니다.

환경



macOS High Sierra - 10.13.6
Android Studio - 3.3.2

할 일



앱에서 이용하고 있는 퍼미션이나 클래스에 의한 것이라고 생각합니다만, 대상의 앱에서는 이하를 대응하기로 했습니다.

  • Android Studio 3.3.2에서 빌드 가능
  • 2년전의 Android Studio 로부터 버젼도 상당히 오르고 있다고 생각하므로, 우선은 빌드할 수 있도록(듯이) 하는 곳으로부터.


  • 권한 (이번에는 android.permission.CAMERA)이 필요한 곳의 개수

  • Android 6.0(API 레벨 23)에서 권한 부여 방법이 변경됨 그래서 그 대응.


  • FileProvider로 변경
  • 카메라를 시작할 때 외부 파일을 지정하는 방법을 FileProvider를 사용하여 변경합니다.


  • GCM → FCM 대응
  • 아직 GCM을 사용했으므로 FCM으로 전환합니다.


  • NotificationChannel 지원
  • Android 8.0(API 레벨 26)에서 Notification Channel 대응하지 않으면 푸시 통지가 닿지 않게 되므로 대응합니다.


  • Android Studio 3.3.2에서 빌드 가능



    Android Studio가 말하는대로



    "gradle의 버전을 주시겠습니까?"

    compile → implementation으로 설정





    AndroidManifest.xml에서 android:minSdkVersion, android:targetSdkVersion 제거



    (Android Studio가 "지워도 괜찮습니까?"


    FloatMath를 (float)Math로 설정





    레이아웃 파일의 id 지정 변경






    이상으로 빌드할 수 있게 되었습니다.

    권한이 필요한 곳 ​​개수



    AndroidManifest.xml에 permission 추가


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

    권한이 필요한 곳에 권한 확인 처리와 확인에서 돌아왔을 때의 처리를 추가


    public static final int PERMISSION_REQUEST_CAMERA = 201;
    
    private void startCamera() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, PERMISSION_REQUEST_CAMERA);
            return;
        }
        imageFilePath = CameraHelper.startCameraAndGetImageFilePath(this, REQUEST_CODE_CAMERA_CAPTURE);
    }
    
    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        if (requestCode == PERMISSION_REQUEST_EXTERNAL_STORAGE) {
            showCameraOrGalleryDialog();
        }
        if (requestCode == PERMISSION_REQUEST_CAMERA) {    // ← 追加
            startCamera();
        }
    }
    

    이것으로 권한의 대응은 완료입니다.

    FileProvider로 변경



    공급자의 경로를 정의한 xml 파일 만들기



    provider_paths.xml
    <?xml version="1.0" encoding="utf-8"?>
    <paths xmlns:android="http://schemas.android.com/apk/res/android">
        <external-path name="external_files" path="."/>
    </paths> 
    

    AndroidManifest.xml에 공급자 정의


    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
    </provider>
    

    Uri 획득 방법 변경


    -            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(imageFile));
    +            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(activity, BuildConfig.APPLICATION_ID + ".provider", imageFile));
    

    이것으로 FileProvider의 대응은 완료입니다.

    GCM → FCM 대응



    Android Push 알림 GCM에서 FCM으로 마이그레이션 #Android #Firebase
    이쪽을 참고로 했습니다!

    대응 내용은 거의 같기 때문에 바꾼 곳만 써 둡니다.

    firebase-messaging을 10.2.1로 설정



    targetSdkVersion 26 으로 하면(자) , 적어도 10.2.1 로 합니다.
    (그에 따라 다른 라이브러리의 버전도 10.2.1로 합니다.)
    implementation 'com.google.android.gms:play-services-analytics:10.2.1'
    implementation 'com.google.firebase:firebase-messaging:10.2.1'
    

    message.getData() 를 Bundle 에 put 한다



    onMessageReceived() 의 인수가 Bundle 가 아니므로 생성해 줍니다.
    @Override
    public void onMessageReceived(RemoteMessage message) {
        Map<String, String> data = message.getData();
    
        Bundle bundle = new Bundle();
        for (Map.Entry<String, String> entry : data.entrySet()) {
            bundle.putString(entry.getKey(), entry.getValue());
        }
    
        PushMessageHandler.handleMessage(bundle);
    }
    

    이것으로 FCM 대응이 완료되었습니다.

    NotificationChannel 지원



    Android O에서 푸시 알림이 도착하지 않을 때
    이쪽을 참고로 했습니다!

    특히 바꾼 곳도 없기 때문에 쓰지 않습니다!

    생각한 것



    단번에 버전이 오르면 하는 일이 많아서 힘들었습니다…
    2019년부터 매년 대응해야 되었으므로 시간을 찾아서 세심하게 업데이트해 나가고 싶습니다.
    (방치하고 있는 어플은 지워 버려!라고 생각합니다만 어른스러운 사정도 있지요..)

    참고



  • 필요한 작업 확인
  • 2018년에 요구되는 targetSdkVersion(대상 API 레벨)을 설명합니다.


  • GCM → FCM 대응
  • Android Push 알림 GCM에서 FCM으로 마이그레이션 #Android #Firebase


  • NotificationChannel 지원
  • Android O에서 푸시 알림이 도착하지 않을 때

  • 좋은 웹페이지 즐겨찾기