適配Android6.0到8.0詳細過程——小白教程

前言:

由於GooglePlay在2018年11月1日開始上架項目要求targetSdkVersion在26以上,因此只能版本適配了。我的項目版本是22,也就是Android5.1,之前也沒有做過版本適配,只能一邊查資料一邊摸索着搞,如果有不對的地方,或者有更好的解決方案,歡迎聯繫指出!

準備工作:

要適配Android8.0首先要先把AndroidStudio升級到AndroidStudio3.0以上版本。

打開project.properties,設置

target=android-26

打開配置文件build.gradle,修改targetSdkVersion,compileSdkVersion爲26以上,更新gradle版本爲最新版本,我這裏更新的是gradle:3.2.1

具體如下:

compileSdkVersion 26
targetSdkVersion 26

dependencies {
    classpath
'com.android.tools.build:gradle:3.2.1'
}

具體截圖:

buildToolsVersion 會在更新gradle時自動更新成28.0.3 或更新版本。

=========分割線==============

如果有用到代碼混淆的話,可能回遇到下面這個異常:

更新前代碼:

    buildTypes {

release {

            // 是否進行混淆

            minifyEnabled false

            zipAlignEnabled true

            shrinkResources true

            // 混淆文件的位置

proguardFiles getDefaultProguardFile('proguard-project.txt'), 'proguard-project.txt'

            buildConfigField "boolean", "LOG_DEBUG", "false"

        }    debug {

            buildConfigField "boolean", "LOG_DEBUG", "true"

        }

}

更新後報出異常:

User supplied default proguard base extension name is unsupported

解決:

proguardFile ('TIS-SmarthomeV5.0.3/.../proguard-project.txt')

異常:Removing unused resources requires unused code shrinking to be turned on.

解決:

minifyEnabled true  //這裏原本是false改成true

如果不使用代碼混淆:

// 是否進行混淆

minifyEnabled false
zipAlignEnabled false

shrinkResources false

=======分割線========

編譯,根據錯誤提示,如果之前是用compile的,把compile改成implementation,testCompile改成testImplementation, instrumentTest改成androidTest。

另外如果項目有使用到multidex 突破64k限制解決方案的有可能回報下面這種異常:

解決:

implementation 'com.android.support:multidex:1.0.3'

把依賴改成最新版,我這裏是改成1.0.3,然後就能解決Failed to resolve: multidex這個異常了。

接着下面那個異常是這樣解決的:

修改項目根目錄的那個build.gradle文件中repositories, 保持google()在第一位置:
allprojects {
    repositories {
        google()//
保持這個放在頂部
        mavenCentral()
        maven {
            url "https://jitpack.io"
        }
        maven{
            url 'https://maven.google.com'
        }
        jcenter()//
保持這個放在底部
    }

具體截圖:

接着編譯,

如果出現編譯異常:

Please correct the above warnings first.

看Messages 視圖提示,可以在你的混淆文件proguard-rules.pro裏面添加下面這句代碼屏蔽警告:

-ignorewarnings

繼續編譯,有可能會出現v4jar包keyeventcompat不存在的異常:

Error:(30, 31) 錯誤: 找不到符號
符號:    KeyEventCompat

位置: 程序包 android.support.v4.view

解決:

KeyEventCompat類被取消了 hasNoModifiers方法已經被KeyEvent實現了

報錯:

if (KeyEventCompat.hasNoModifiers(event)) {

    handled = arrowScroll(FOCUS_FORWARD);

} else if (KeyEventCompat.hasModifiers(event, KeyEvent.META_SHIFT_ON)) {

    handled = arrowScroll(FOCUS_BACKWARD);

}

改成:

 

if (event.hasNoModifiers()) {

    handled = arrowScroll(FOCUS_FORWARD);

} else if (event.hasModifiers(KeyEvent.META_SHIFT_ON)) {

    handled = arrowScroll(FOCUS_BACKWARD);

}

=======================分割線======================

完成以上操作可以成功編譯運行之後,開始先適配6.0的動態權限:

Android6.0開始,官方對權限的要求越來越嚴格,所以一些危險權限需要在程序中動態獲取,讓用戶點擊允許權限才能獲取,普通權限和以前沒區別,可以直接在清單文件裏面配置獲取。而危險權限在清單文件裏面配置了,如果用戶沒有點擊允許一樣是獲取不到的。具體哪些是危險權限,哪些是普通權限可以自己在網上查一下,這裏就不詳細說了。

首先在build.gradle中的dependencies裏面添加第三方權限工具,這裏使用閆振杰封裝的第三方依賴:

dependencies {implementation 'com.yanzhenjie:permission:2.0.0-rc4'}

因爲已經在配置文件中添加了第三方依賴,所以我們可以直接使用別人封裝好的動態獲取權限的API。一般來說,在打開程序的主activity那裏我們就要向用戶申請權限了,在MainActivity的onCreate()方法裏面申請,代碼如下:

@Override
    public void onCreate(Bundle savedInstanceState) {
        getWindow().requestFeature(Window.FEATURE_NO_TITLE);//設置無標題
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_smartbus);

  	//寫你自己的初始化佈局…
    
   
        //獲取外部存儲權限和地理位置權限
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { //版本在23及以上
            AndPermission.with(this).permission(Permission.READ_EXTERNAL_STORAGE, Permission.WRITE_EXTERNAL_STORAGE,
                    Permission.ACCESS_FINE_LOCATION, Permission.ACCESS_COARSE_LOCATION).onGranted(new Action() {
                @Override
                public void onAction(List<String> permissions) {
                    //TODO
			//成功獲取權限後要做的操作
                         }
            }).onDenied(new Action() {
                @Override
                public void onAction(List<String> permissions) {
//用戶拒絕權限,toast提示用戶如果不允許權限有部分功能將無法使用
                    Toast.makeText(HomepageActivity.this,
                            "Rejection may result in some functionality being unavailable.",
                            Toast.LENGTH_SHORT).show();
                }
            }).start();

        }else{//低於6.0版本的
          //TODO
        }
    }

 

如果還需要其他危險權限可以直接在這裏後面添加: AndPermission.with(this).permission(Permission.READ_EXTERNAL_STORAGE, Permission.WRITE_EXTERNAL_STORAGE,
                   
Permission.ACCESS_FINE_LOCATION, Permission.ACCESS_COARSE_LOCATION,

…..

)

而其他危險權限,例如相機權限,發送短信權限,可以在需要用到的地方再申請,因爲一開始向用戶申請太多權限的話,用戶體驗不是那麼好。

例如,可以在打開相機的回調那裏動態申請相機權限:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){//如果當前Android版本是6.0以上的
                    AndPermission.with(SettingActivity.this).permission(Permission.CAMERA).onGranted(new Action() {
                        @Override
                        public void onAction(List<String> permissions) {
                    //用戶允許權限,啓用相機
                            
                    intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    intent.putExtra(MediaStore.EXTRA_OUTPUT,
                        Uri.fromFile(new File(getExternalFilesDir("TIS-Smarthome/"), "photo_BgImage.png")));
                    startActivityForResult(intent, GET_BACKGROUND_PHOTOZOOM);
                        }
                    }).onDenied(new Action() {
                        @Override
                        public void onAction(List<String> permissions) {
                    //用戶拒絕權限,toast提示拒絕權限將使某些功能無法使用
                            Toast.makeText(SettingActivity.this,
                                    "Rejection may result in some functionality being unavailable.",
                                    Toast.LENGTH_SHORT).show();
                        }
                    }).start();
                }else {
                    //6.0以下的,直接啓動相機
                    intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    intent.putExtra(MediaStore.EXTRA_OUTPUT,
                        Uri.fromFile(new File(getExternalFilesDir("TIS-Smarthome/"), "photo_BgImage.png")));
                    startActivityForResult(intent, GET_BACKGROUND_PHOTOZOOM);
                }

" TIS-Smarthome/"是項目名稱,"photo_BgImage.png"是拍照存放的圖片名稱,也就是外部存儲到你手機哪裏,保存成什麼名字的圖片。

適配Android7.0

前面添加了兩個危險權限之後,如果你的應用有使用相機功能,你會發現在應用中打開相機就閃退。因爲Android官方在7.0對私有目錄訪問進行了限制,這裏我們可以使用FileProvider來解決。(當然你得先申請了相機權限,不會申請的參照上面的代碼在啓動相機前申請。)

首先在清單文件AndroidManifest.xml的application標籤下添加:

<application
        android:name="caro.automation.MyApplication"
        android:allowBackup="true"
        android:hardwareAccelerated="true"
        android:hasCode="true"
        android:icon="@drawable/tis"
        android:label="@string/app_name"
        android:usesCleartextTraffic="true"

        >


        <!--2018.10.16 相機打不開問題-->
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="你的包名.fileprovider"
            android:grantUriPermissions="true"
            android:exported="false"
            >
            <meta-data android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />

        </provider>

...
</application>

 

Provider標籤部分,file_paths是我們指定的文件目錄,所以需要在res文件夾下的xml文件目錄下新建file_paths.xml,然後編寫代碼:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <paths>
        <external-path path="" name="camera_photos" />
    </paths>
</resources>

正常來說這樣已經可以在7.0系統里正常調起相機了,但是有的手機在7.0之後你的APP就算有權限,給出一個URI之後手機也認爲你沒有權限,這個問題的解決方法是,在MyApplication的onCreate()方法中添加以下代碼:

   /*2018.10.16 相機打不開問題*/
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)//如果當前Android版本大於7.0
        { StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
            StrictMode.setVmPolicy(builder.build());
        }

適配Android8.0

Android8.0主要是適配通知欄和圖標。我這邊只做了通知欄的適配。

由於我負責的項目是使用第三方個推的,所以適配Android8.0只需要更新個推到最新版GETUI_ANDROID_SDK_2.12.5.0就可以了。先到個推官網下載最新的個推SDKhttp://docs.getui.com/getui/version/

下載完之後根據他的接入文檔重新接入一遍SDK就可以,這裏就不詳細描述了,畢竟我怎麼寫都沒有別人的接入文檔詳細0.0

更新完個推SDK後,點擊創建推送:

選擇目標用戶指定到你的測試機,發送通知,如果能成功接收到通知就是適配成功了。

完成適配後,使用Androidstudio3.2進行打包,我這裏出現警告fastjson沒有找到相關的類或接口。解決:更新fastjson依賴1.2.51版本,更新完注意把舊版的jar包刪除,不然會報jar包重複,導致打包失敗。

還要注意的是,8.0移除了靜態廣播,所以廣播要改成動態註冊!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章