精华内容
下载资源
问答
  • targetSdkVersion 三个版本号中最有趣的就是 targetSdkVersion 了。 targetSdkVersion 是 Android 提供向前兼容的主要依据,在应用的 targetSdkVersion 没有更新之前系统不会应用最新的行为变化。这允许你在适应新...
  • Android项目该如何选择targetSdkVersion

    万次阅读 多人点赞 2017-10-12 09:59:28
    新手的第一个Android项目或许没有认真考虑过如何选择targetSdkVersion的问题,也或许还有一部分像TeachCourse一样的开发者,积累一些工作经验后才回头来思考这个问题。那么该如何选择一个targetSdkVersion的属性值?...

    新手的第一个Android项目或许没有认真考虑过如何选择targetSdkVersion的问题,也或许还有一部分像TeachCourse一样的开发者,积累一些工作经验后才回头来思考这个问题。那么该如何选择一个targetSdkVersion的属性值?一个属性值为23的targetSdkVersion表示什么含义?那么API 24和Android 7.0又是什么关系?为什么API 19开发的Android项目可以在Android 7.0系统的手机上运行,反之Android 4.x系统的手机可以运行API 24开发的Android项目?最后,正确理解compileSdkVersion、minSdkVersion和targetSdkVersion三者之间的关系。

    应用程序接口和Android系统关系

    一、认识targetSdkVersion

    targetSdkVersion即目标软件开发版本,在创建每一个Android项目的时候都需要选择targetSdkVersionminSdkVersion,一个targetSdkVersion的属性值表示创建的Android项目使用哪个API版本,一个API版本使用一个整型数字表示,API的全称是Application Programming Interface,即应用程序编程接口,API 19对应的编程接口和API 23定义的编程接口存在差别,因为使用整型数字表示targetSdkVersion的属性值,容易记忆和便于比较它们之间的大小,高版本API编程接口可以兼容低版本API编程接口,反之则不行。

    需要区别Android 7.0API 24之间的关系,Android 7.0定义的手机系统的版本,该系统的版本对外开放的应用程序接口被定义为API 24,如果开发者想要在开发的APP中使用Android 7.0系统提供的功能,这些功能包括:多窗口支持、通知显示变更、JIT/AOT编译、快速的应用安装路径等等,那么新手在创建的Android项目的时候就需要选择API 24的应用程序接口。

    不知道开发者也没有注意到,为什么API 19开发的Android项目可以在Android 7.0系统的手机上运行,反之Android 4.x系统的手机可以运行API 24开发的Android项目,它们运行的效果是否一样呢?如果是Android 7.0系统运行API 24开发的应用程序,效果又是怎么样?这就让TeachCourse联想到了API 23开发的应用程序在低于Android 6.0系统上运行时,如果权限被禁用后,会提示如下图:

    运行时权限

    但是,如果API 23开发的应用程序在高于或等于Android 6.0系统的手机上运行时需要自己定义打印上述Toast,下面是完整的运行时权限申请的代码:

    
        private static final int REQUEST_CODE_PERMISSION=0x112;
        private void initPermission() {
            int flag= ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
            if(PackageManager.PERMISSION_GRANTED!=flag){
                ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CAMERA}, REQUEST_CODE_PERMISSION);
            }else{
                alterImageNew();
            }
        }
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            if (REQUEST_CODE_PERMISSION==requestCode){
                switch (grantResults[0]){
                    case PackageManager.PERMISSION_DENIED:
                        boolean isSecondRequest=ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.CAMERA);
                        if(isSecondRequest)
                            ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CAMERA},REQUEST_CODE_PERMISSION);
                        else
                            Toast.makeText(this, "拍照权限被禁用,请在权限管理修改", Toast.LENGTH_SHORT).show();
                        break;
                    case PackageManager.PERMISSION_GRANTED:
                        alterImageNew();
                        break;
                }
            }
        }
    

    如果需要显示类似于上面图片显示的Toast提示,开发者需要在onRequestPermissionResult回调方法中,打印拍照权限被禁用,请在权限管理修改这句话,在使用API 23应用程序编程接口开发的APP中都可以反复复制上面代码,仅将CAMERA替换成定义的权限参数,将alterImageNew()替换成拥有权限后要执行的代码。

    举这个例子的目的,想要说明为什么在API 23版本开发的APP在低于Android 6.0系统不会执行上述代码的原因。

    高版本的API定义了一些的编程接口,但是通常不需要开发者考虑是否高版本API开发的APP在低版本的Android系统的兼容性问题,APIAndroid系统是两个不一样的概念,API属于应用层的东西,Android系统属于底层的东西,开发者想要显示底层的演示效果,就需要使用API来完成,如果想要不同的演示效果,又需要考虑选择哪个版本的API,也就是文章的标题提到的:如何选择targetSdkVersion属性值的问题。

    二、如何选择targetSdkVersion

    一个Android系统,对外提供一套API,如何选择targetSdkVersion取决于应用程序需要实现的功能,如果你的应用程序使用API 7就可以实现的功能,可以不用考虑使用API 24,使用低版本API的其中一个好处,可以让更多的Android系统运行的效果保持一致,即兼容性更好,打个比方:API 7开发的APP可能兼容98%以上的Android手机,而API 24开发的APP可能兼容仅有60%,所谓的不兼容并不是无法正常运行,而是在不同Android系统的手机运行的效果差异比较大,会让用户感觉难以接受;使用低版本API的其中一个不足,显示的效果比较OUT,提供的可用的接口或类比较少,本来一句代码可以完成的功能(封装的类或接口),需要自己花一天琢磨写很多的代码,也就是有高版本API的其中一个原因,提供更多的或封装好的应用程序接口让开发者使用。

    同时,高版本API会针对低版本存在的问题进行改进和完善,摈弃一下不用的类或接口,新增一些方法或属性,如果你使用的方法是在某个API被另一个方法代替的话,你可能就得在代码中区分APP是运行在哪个版本的Android系统,一个很典型的例子:WebChromeClientonShowFileChooser()方法和openFileChooser()方法,如果你的targetSdkVersion小于19,在处理WebView上传表单的数据的时候就需要重写openFileChooser方法;如果你的targetSdkVersion大于或等于19,你就必须同时重写onShowFileChooseropenFileChooser两个方法,openFileChooser方法在Android 4.0以下系统被回调,另一则在Android 4.0以上系统被回调。这是高低版本API摈弃或新增一些类和方法时需要注意的其中一个问题。

    API版本号和Android系统关系

    了解并学习Android 4.x、Android 5.x、Android 6.x或Android 7.x系统的特性,重点掌握不同系统同一个功能的实现方式,即行为变更,特点:变更的行为在当前系统或更高系统版本中被支持,一个简单的例子:Android 7.0系统其中的一个行为变更是权限更改,尝试传递file:// URI 的方式写入本地文件或读取本地文件,使用API 24开发的APP将会触发 FileUriExposedException异常,请求拍照并保存到本地的正确的写法,如下:

    
        /**
         * 调用系统相机
         */
        private void goToTakePhoto() {
            String state = Environment.getExternalStorageState();
            if (Environment.MEDIA_MOUNTED.equals(state)) {
                File file = new File(mSDCardPath, System.currentTimeMillis() + ".jpg");
                /**Android 7.0以上的方式**/
                Uri contentUri = getUriForFile(this, getString(R.string.install_apk_path), file);
                grantUriPermission(getPackageName(), contentUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, contentUri);
                /**Android 7.0以前的方式**/
    //            intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
                startActivityForResult(intent, RESULT_CAPTURE_IMAGE);
            } else {
                Toast.makeText(this, "sdcard不存在", Toast.LENGTH_SHORT).show();
            }
        }
    

    想要查看完整的例子,文章后面附上源码,可以下载测试。本来已经代码可以实现的拍照功能,API 24开发的APP在Android 7.0以上系统需要至少四个步骤:

    1. 在AndroidManifest.xml文件中定义一个FileProvider
    2. 指定写入或读取本地文件的目录
    3. 生成完整的URI
    4. 请求授予URI权限
    5. 实现手机拍照并保存本地功能

    三、关于minSdkVersion和compileSdkVersion

    minSdkVersion定义应用程序支持的最低API版本,最低版本设置为API 11,目标版本设置为API 24,那么应用程序调用使用API 14提供的方法时,Android Studio或Eclipse开发工具将提醒开发者引用一个未定义的方法,使用该方法需要将minSdkVersion设置为API 14以上,如下图:

    minSdkVersion含义

    继续在上述代码,造成的结果大于或等于Android 4.0的系统可以正常执行,小于Android 4.0的系统将在运行时尝试访问不可用的 API 时发生崩溃。

    compileSdkVersion定义应用程序编译选择哪个Android SDK版本,通常compileSDKVersion属性值被设置为最新的API版本,例如:25,改变compileSDKVersion的属性值不会影响Android系统运行行为,比如说,将属性值设置为25,targetSdkVersion属性值为23,代码如下:

        compileSdkVersion 25
        buildToolsVersion "25.0.2"
        defaultConfig {
            applicationId "cn.teachcourse.demos"
            minSdkVersion 11
            targetSdkVersion 23
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        }
    

    开发的应用程序在Android 7.0系统运行,不会以Android 7.0新增的行为运行,决定Android系统行为的仍然是targetSDKVersion,那么compileSDKVersion有什么用呢?选择最新的API版本,在编译的时候检查代码的错误和警告,提示开发者修改和优化,因为通常在Android项目中会引入第三方的支持库,支持库使用了23.1.1版本,compileSdkVersion的属性值至少为23.0.0,新版本的支持库的发布紧跟着对应的Android系统平台,能够更好的兼容。

    四、targetSdkVersion、minSdkVersion和CompileSdkVersion之间的关系

    记住一点:Android系统平台的行为变更,只有targetSdkVersion的属性值被设置为大于或等于该系统平台的API版本时,才会生效;compileSdkVersion属于Android编译项目时其中的一项配置,主要区别是compileSDKVersion在不会被打包的APK文件中,targetSdkVersionminSdkVersion将被打包到APK文件中,具体可以解压APK文件后,查看AndroidManifest.xml文件,如下图:

    targetSdkVersion区别

    你会发现在使用Android Studio开发工具时,手动修改AndroidManifest.xml的属性值,使用Gradle构建后,将会被忽略,最终生成的是build.gradle配置文件指定的属性值。它们之间的关系如下:

    minSdkVersion <= targetSdkVersion <= compileSdkVersion

    展开全文
  • Android targetSdkVersion28 适配

    千次阅读 2019-06-12 18:22:16
    平时csdn看资料的时候,都是...正好近期把targetSdkVersion 升到了28,适配过程中踩到了各种坑,趁此机会写一篇个人总结与诸位一起分享。 1. 腾讯云-语音识别 code=-301 & 7.0无法抓包 & MTA崩溃 这几...

    平时csdn看资料的时候,都是游客模式,前两天要看个评论,不得不登一下,发现之前写的一个心得,有好几个朋友评论了。虽然是很小的问题,但能帮到别人,心里就很满足2333

    正好近期把targetSdkVersion 升到了28,适配过程中踩到了各种坑,趁此机会写一篇个人总结与诸位一起分享。

     


    1. 腾讯云-语音识别 code=-301 & 7.0无法抓包 & MTA崩溃

    这几个其实本质是一个问题。详情参考官方文档网络安全配置。可以看到关键的一点是“从 Android 9(API 级别 28)开始,系统默认情况下已停用明文支持。”,即 cleartextTrafficPermitted="false"。

    由此而知,腾讯云语音识别一直报错code=-301, message=server connect failed,其实是因为加了这个设置ClientConfiguration.setServerProtocolHttps(false); 导致接口都是http,自然无法使用了,去掉该配置就可以了,因为默认是用的https。因为demo中是这么设置的,所以之前同事就copy过来了,我升级target sdk后发现不能用也没多想就给腾讯云提了工单,那边一开始也接锅表示会修复的,结果升新版后还是不行,一来一回花了不少时间,以后用sdk还是得多看文档,但这语音识别的文档也太简陋了,连版本日志都没...

    MTA崩溃也是同样的问题,一上报就崩了,CLEARTEXT communication to xxx not permitted by network security policy,看了下MTA已经是新版本了,再加上其他sdk中可能还有http的,所以索性修改networkSecurityConfig,允许明文。

    7.0以上不能抓包则同样需要在networkSecurityConfig中配置信任的证书,我选择了debug调试时信任所有证书。

    networkSecurityConfig配置如下:

    在res/xml中新建 network_security_config.xml

    <?xml version="1.0" encoding="utf-8"?>
    <network-security-config>
        <debug-overrides cleartextTrafficPermitted="true">
            <trust-anchors>
                <certificates src="system" />
                <certificates src="user" />
            </trust-anchors>
        </debug-overrides>
        <base-config cleartextTrafficPermitted="true" />
    </network-security-config>

    在AndroidManifest里的<application>标签中,添加代码:

     android:networkSecurityConfig="@xml/network_security_config"

    以上问题就一并解决啦,各位可以根据自己的需求来进行配置。 

     2. java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation

    这个问题发生在android 8.0 的机子上,app都没进就崩了,我的心也跟着一起崩了啊23333

    这个问题中有较多讨论,问题来源是源码中这一段

      //Need to pay attention mActivityInfo.isFixedOrientation() and ActivityInfo.isTranslucentOrFloating(ta)
        if (getApplicationInfo().targetSdkVersion >= O_MR1 && mActivityInfo.isFixedOrientation()) {
            final TypedArray ta = obtainStyledAttributes(com.android.internal.R.styleable.Window);
            final boolean isTranslucentOrFloating = ActivityInfo.isTranslucentOrFloating(ta);
            ta.recycle();
    
            //Exception occurred
            if (isTranslucentOrFloating) {
                throw new IllegalStateException(
                        "Only fullscreen opaque activities can request orientation");
            }
        }

    解决方法:项目中很多activity用的主题都是透明的

     <style name="CommonTheme" parent="AppTheme">
            <item name="android:windowIsTranslucent">true</item>
            <item name="android:windowBackground">@color/white</item>
     </style>

    将用到透明主题的acitivity在manifest中的

    android:screenOrientation="portrait"

    这行都去掉就可以了,经测试,如果透明activity后面有不透明的固定方向的activity,透明的是不会转动的,所以主页activity不要用透明主题就好。

    3. android 9.0 pie windowSoftInputMode不管怎么设置 进入activity键盘不会自动弹出

    这个问题也蛮妖的,就是在9.0上弹不出键盘,android:windowSoftInputMode="adjustResize|stateVisible"不起作用。

    依旧是在stackoverflow找到了解决办法,在9.0上,没有自动获取焦点,那就只能手动代码中requestFocus,或者xml加上</requestFocus>,例如:

     <EditText
            android:id="@+id/et_envelope_post_script"
            android:layout_width="match_parent"
            android:layout_height="98dp"
            android:background="@color/white"
            android:gravity="left|top"
            android:padding="16dp"
            android:textSize="16sp">
            <requestFocus />
     </EditText>

    4. okhttp3 通过multipart上传文件名为中文报错Caused by: java.lang.IllegalArgumentException: Unexpected char

    顺便升级了一下okhttp3,结果bugly中几个上报都是通过multipart/form-data上传书封时的,是因为用到的本地图片文件名含中文,报错如下:

     Caused by: java.lang.IllegalArgumentException: Unexpected char 0x6211 at 39 in Content-Disposition value: form-data; name="bookCover"; filename="我推荐吗.jpg"

    代码使用:

    MultipartBody.Builder builder = new MultipartBody.Builder()
                    .setType(MultipartBody.FORM)
                    .addFormDataPart(param, targetFile.getName(), RequestBody.create(MEDIA_TYPE, targetFile));

    源码部分:

     /** Add a form data part to the body. */
        public Builder addFormDataPart(String name, @Nullable String filename, RequestBody body) {
          return addPart(Part.createFormData(name, filename, body));
        }
       public static Part createFormData(String name, @Nullable String filename, RequestBody body) {
          if (name == null) {
            throw new NullPointerException("name == null");
          }
          StringBuilder disposition = new StringBuilder("form-data; name=");
          appendQuotedString(disposition, name);
    
          if (filename != null) {
            disposition.append("; filename=");
            appendQuotedString(disposition, filename);
          }
    
          return create(Headers.of("Content-Disposition", disposition.toString()), body);
        }
      public static Headers of(String... namesAndValues) {
        if (namesAndValues == null) throw new NullPointerException("namesAndValues == null");
        if (namesAndValues.length % 2 != 0) {
          throw new IllegalArgumentException("Expected alternating header names and values");
        }
    
        // Make a defensive copy and clean it up.
        namesAndValues = namesAndValues.clone();
        for (int i = 0; i < namesAndValues.length; i++) {
          if (namesAndValues[i] == null) throw new IllegalArgumentException("Headers cannot be null");
          namesAndValues[i] = namesAndValues[i].trim();
        }
    
        // Check for malformed headers.
        for (int i = 0; i < namesAndValues.length; i += 2) {
          String name = namesAndValues[i];
          String value = namesAndValues[i + 1];
          checkName(name);
          checkValue(value, name);
        }
    
        return new Headers(namesAndValues);
      }
    
     static void checkName(String name) {
        if (name == null) throw new NullPointerException("name == null");
        if (name.isEmpty()) throw new IllegalArgumentException("name is empty");
        for (int i = 0, length = name.length(); i < length; i++) {
          char c = name.charAt(i);
          if (c <= '\u0020' || c >= '\u007f') {
            throw new IllegalArgumentException(Util.format(
                "Unexpected char %#04x at %d in header name: %s", (int) c, i, name));
          }
        }
      }
    
      static void checkValue(String value, String name) {
        if (value == null) throw new NullPointerException("value for name " + name + " == null");
        for (int i = 0, length = value.length(); i < length; i++) {
          char c = value.charAt(i);
          if ((c <= '\u001f' && c != '\t') || c >= '\u007f') {
            throw new IllegalArgumentException(Util.format(
                "Unexpected char %#04x at %d in %s value: %s", (int) c, i, name, value));
          }
        }
      }

    由此可知,文件名中含中文时,checkValue会抛出异常,解决办法就是上传前重命名文件名。同时注意,header头中也是不能带中文的。

    5. 其他

    有些项目中已经适配,或者没涉及的点,也一起提一下。

    一个是7.0开始App对外无法暴露file://类型的URI了,在类似调用系统相机或是通过代码安装apk等需要暴露uri给其他app的情况下,会抛出FileUriExposedException异常,需要使用FileProvider来定义对外暴露的文件夹路径,再调用:

    FileProvider.getUriForFile(this.mContext.getApplicationContext(), authority, file);

    来获取content://类型的Uri。其中authority指在manifest的<provider>中配置的provider名,例如:

    <provider
                android:name="me.iwf.photopicker.utils.PhotoFileProvider"
                android:authorities="${applicationId}.provider"
                android:exported="false"
                android:grantUriPermissions="true">
                <meta-data android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/__picker_provider_paths"/>
    </provider>

    其中__picker_provider_paths是在res/xml中定义的对外暴露的文件夹路径,如下:

    <?xml version="1.0" encoding="utf-8"?>
    <paths>
        <external-path name="external_storage_root" path="."/>
        <files-path name="files" path="."/>
    </paths>

    关于paths配置比较详细的讲解可参考Android 7.0适配-应用之间共享文件(FileProvider)

    二是android 8.0以上未知来源的应用是不可以通过代码来执行安装的,会提示“解析包时出现问题”。需要申明权限

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

    并在代码中动态申请。 这么一想之前一些app更新时是碰到过这个问题,当时只当是apk有问题,现在看来是没有进行适配。我们的项目因为是直接跳到网页进行下载的,所以没有碰到这个问题。

    目前为止碰到的问题大概就这些,如果之后还有的话,会在此更新的,也希望各位能留言自己在升级sdk中碰到的坑,我也会一并整理进来的。

     

    展开全文
  • targetSdkVersion 升级到 29、30 文件处理

    千次阅读 2021-06-16 00:28:37
    读写正常不报错 targetSdkVersion = 30,targetSdkVersion 由 低版本 修改到 30,覆盖安装,读写报错,程序崩溃 (open failed: EACCES (Permission denied)) targetSdkVersion = 30,targetSdkVersion 由 低版本 ...

    code小生 一个专注大前端领域的技术平台公众号回复Android加入安卓技术群

    作者:zhongjh
    链接:https://www.jianshu.com/p/892a2ca5c41e
    声明:本文已获zhongjh授权发表,转发等请联系原作者授权

    android12要来了,很多老app还在29以下,该文章就是讲述升级到29、30关于文件的处理。

    在总结多种情况之前,我们再次确认下目前有哪些存储目录

    • 私有存储 (Private Storage) : 每个应用在都拥有自己的私有目录,其它应用看不到,彼此也无法访问到该目录。

    • 内部存储私有目录 (/data/data/packageName) ;

    • 外部存储私有目录 (/sdcard/Android/data/packageName);

    • 共享存储 (Shared Storage) : 存储其他应用可访问文件, 包含媒体文件、文档文件以及其他文件,对应设备DCIM、Pictures、Alarms、Music、Notifications、Podcasts、Ringtones、Movies、Download等目录。

    • 外部存储:Environment.getExternalStorageDirectory()获取sdcard下的任意文件夹,在SDK29以上已经过期、失效。

    Android版本迭代变化

    在29版本后,只能操作本身内部存储私有目录、外部存储私有目录、共享存储,但是依然可以通过android:requestLegacyExternalStorage="true"来设置(在AndroidManifest.xml中的application添加该配置),不启用分区存储,一切照旧。

    但是30版本以后,就强制性的只能操作规定的目录,这个时候依然有个兼容配置设置,android:preserveLegacyExternalStorage="true"(在AndroidManifest.xml中的application添加该配置),这个配置使得手机appSdk30版本以下,更新appSdk30版本以后,依然不启用分区存储,一切照旧。

    那么我简单总结多种情况和解决方式:

    • targetSdkVersion = 28,运行后正常读写所有文件,如果不是必须的需求并且是新创建的项目的话,建议把文件按照规范存储在外部存储私有目录 (/sdcard/Android/data/packageName)

    • targetSdkVersion = 29,targetSdkVersion 由 低版本 修改到 29,覆盖安装,运行后正常读写。

    • targetSdkVersion = 29,卸载旧应用,重新安装新应用,如果读写外部存储,程序崩溃 (open failed: EACCES (Permission denied))

    • targetSdkVersion = 29,添加android:requestLegacyExternalStorage="true"(不启用分区存储),读写正常不报错

    • targetSdkVersion = 30,targetSdkVersion 由 低版本 修改到 30,覆盖安装,读写报错,程序崩溃 (open failed: EACCES (Permission denied))

    • targetSdkVersion = 30,targetSdkVersion 由 低版本 修改到 30,覆盖安装,增加 android:preserveLegacyExternalStorage="true",读写正常不报错

    • targetSdkVersion = 30,卸载旧应用,重新安装新应用,不管设置任何配置,如果读写外部存储,程序崩溃 (open failed: EACCES (Permission denied))

    如果我app缓存文件存储在外部存储,那么如何处理升级到30并且迁移文件呢?

    • 客户app有重要文件在外部存储

    • 客户app要升级sdk到30

    • 要考虑新客户安装app

    所以最终是设置android:preserveLegacyExternalStorage="true",所有目录按照外部存储私有目录来进行读写操作,判断外部存储如果可以操作文件并且存在需要迁移的文件夹,先复制过来,并且需要增加一个全局缓存标记已经进行迁移成功。

    如果用到数据库切记先迁移文件后再初始化数据库。

    相关推荐

    Android Kotlin+Jetpack+MVVM

    Android 自定义注解处理器并生成 json 文件

    Android 10文档阅读总结

    Android 中.aar文件生成方法与用法

    细细品读!深入浅出,官方文档看ConstraintLayout

    我是code小生,喜欢可以随手点个在看、转发给你的朋友,谢谢~

    
    如果你有写博客的好习惯
    欢迎投稿
    
    点个“在看”小生感恩❤️
    
    展开全文
  • targetSdkVersion 代表着目标版本,在编译的时候会将该版本的api编译进apk中。 minSdkVersion 代表着最低版本,在编译的时候兼容到该参数指定最低版本api。 二、targetSdkVersion指目标版本。 应用的 targetSdk...

    一、Android gradle中常见的版本配置

    compileSdkVersion 代表着编译的时候,会采用该api的规范进行代码检查和警告,但是并不会编译进apk中。
    targetSdkVersion 代表着目标版本,在编译的时候会将该版本的api编译进apk中。
    minSdkVersion 代表着最低版本,在编译的时候兼容到该参数指定最低版本api。
    

    二、targetSdkVersion指目标版本。

    应用的 targetSdkVersion 没有更新之前系统不会应用最新的行为变化

    例如:

    我们的compileversion使用的是25,运行在(6.0)手机上。我们把targetsdkversion设置在23之下,我们就不要去对权限进行动态设置。

    三、minsdkversion指最小允许的sdk版本。

    如果当前手机sdk版本是7,你的app最小允许版本是9.则在当前手机是无法安装我们的app。

    尽量兼容更多版本,但要满足当前使用的class所需要的最低版本要求。

    四、compilesdkversion指当前编译代码的sdk版本。

    编译代码所使用的sdk版本
    谷歌建议尽量使用最新的sdk版本编译代码。

    展开全文
  • 提升targetSdkVersion至26+适配

    千次阅读 2019-05-21 14:15:08
    前几天发版时接到了华为那边的提醒,说请尽快将targetSdkVersion提升到26+,2019年5月1号之后将会拒绝所有targetSdkVersion低于26的应用的上架和更新。于是查了一下,发现目前国内的主要应用渠道商都已经签订了电信...
  • targetSDK <= 22: 优点:便于数据统计。因为不会受运行时权限影响,默认拥有储存及电话等统计用到的重要权限; 缺点:当设备版本大于6.0时不能使用安装apk功能; 26 <= targetSDK <= 28 优点:某些硬核渠道...
  • targetSdkVersion=29踩坑

    2021-06-11 20:00:38
    目前遇到的几个问题汇总下: 1.截图权限问题崩溃 2.外置SD卡使用问题崩溃 3.界面显示问题
  • targetsdkversion过低

    千次阅读 2019-05-28 11:20:38
    用hbuilder 打的包,上架小米,发现提示targetsdkversion 过低 要 >= 26 只需要在 。json文件中设置 就可以了 "plus" : { "distribute" : { "google" : { "targetSdkVersion":26 } } } 在这里 添加一个...
  • Android之targetSdkVersion详解

    千次阅读 2019-04-20 08:41:02
    Google 官方发布文章解析 compileSdkVersion、minSdkVersion 以及 targetSdkVersion 的含义,以及合理设置各个值的意义,原文Picking your compileSdkVersion, minSdkVersion, and targetSdkVersion(后面简称 ...
  • Android targetSdkVersion你真的了解吗?

    万次阅读 多人点赞 2018-06-15 17:08:00
    当然不是,系统通过targetSdkVersion来保证Android的向前兼容性,在Android4.4之后的设备上,系统会判断你的targetSdkVersion是否小于19,如果小于的话,那就按照19之前的api方法,如果大于等于19,那么就按照之后的...
  • targetSdkVersion(24) > 手机的版本(6.0) 对应项目会运行手机版本内一切特性。譬如项目targetSdkVersion是24,那么项目里没做6.0权限管理,调用危险权限相机就会闪退(利大于弊) **手机的版本>targetSdk...
  • 为什么要在说权限申请的时候,说targetSdkVersion呢!其实是有原因的,因为目标版本的值的修改,对权限的申请检查是有很大的影响! 例如当targetSdkVersion版本小于23(6.0)的时候,其在编译的时候,不会对权限...
  • compileSdkVersion, targetSdkVersion区别

    千次阅读 2019-02-21 14:46:54
    借鉴原文 ... 一.compileSdkVersion compileSdkVersion:SDK编译版本 compileSdkVersion 告诉 Gradle 用哪个 Android SDK 版本编译你的应用。使用任何新添加的 API 就需要使用对应 Level 的 Android S...
  • 这篇文章就先介绍最常见的版本兼容性,顺便帮助大家理解 Android 开发中常见的几个版本相关的属性:minSdkVersion、targetSdkVersion、maxSdkVersion、compileSdkVersion。 自己设计版本兼容 在说明 Android 的应用...
  • 上面的AsyncTask就是很好的例子,在不同targetSdkVersion下执行逻辑不同,因此现在的targetSdkVersion改变所带来的逻辑改变,可能会导致bug出现 最后给大家带来一张是那种SdkVersion的关系吧:    
  • targetSdkVersion=29权限问题

    千次阅读 2020-04-08 09:48:01
    targetSdkVersion=28,29时产生的权限问题现象 现象 升级as版本后,没注意build文件里面targetSdkVersion的变化(29),当时在测试机测试一切正常,但正式上线后发现在部分机型(华为荣耀20、华为mate30pro)上,会...
  • compileSDKversion 这个是编译期间你所使用的api版本,一般越高越好,越高表示开发时可以 ...targetSdkVersion 为兼容而生,使开发的app在各个版本的手机系统上表现一致,如果实际手机系统低于开发时定义...
  • 谷歌强制升级TargetSdkVersion适配指导 谷歌发布的Android P版本对TargetSdkVersion参数提出了要求,华为终端开放实验室迅速对TOP3000应用展开检测,测试结果不容乐观:超过300个应用出现了兼容性问题,不兼容率...
  • 因应用市场的要求,需要将targetSdkVersion的版本改变为26+,所以才有了本篇文章的由来 一.权限问题 毋庸置疑,以前targetSdkVersion是22就是懒得处理权限导致的,应了一句话,欠下的总要还的. 举个栗子,以前你想使用...
  • targetSdkVersion升级到28一些修改的地方(持续更新)  申国骏 关注 https://www.jianshu.com/p/6ce99e03080f 前言 Google Play应用市场对于应用的targetSdkVersion有了更为严a格的要求。从 2018 年 8 月 1 日起...
  • SDK版本 版本名称 10.0 29 (Android Q)(10) 9.0 28 Pie (Android P)(派/馅饼) 8.1 27 Oreo(Android O)(奥利奥) 8.0 26 Oreo(Android O)(奥利奥) 7.1 25 Nougat(Android N)(牛轧糖) 7.0 24 ...
  • 原来是因为TargetSDKVersion为30的情况下,必须用V2以上的签名模式才可以成功。 但是因为MTP加固涉及到重签,而用的重签版本之前太老了,还是v1的,所以导致加固后的包都安装失败。
  • 在manifest的application节点外加入 <queries> <package android:name="com.tencent.mm" /> </queries> 同理,支付宝也一样 ...package android:name="hk.alipay.wallet..
  • Android targetSdkVersion 28 HTTP请求报错的解决办法
  • 当android 6.0 后,获取SD卡...我们将targetSdkVersion 设置低于23 (6.0),这样编译后的app 在android 6.0 及以上的真机运行时,android系统发现我们的targetSdkVersion低于23 ,(例如是22)就无须动态授权啦。 ...
  • targetSdkVersion讲解

    千次阅读 2016-07-28 16:47:16
    targetSdkVersion讲解 在manifest文件中的 用来描述该应用程序可以运行的最小和最大API级别,以及应用程序开发者设计期望运行的平台版本。通过在manifest清单文件中添加该属性,我们可以更好的控制应用在不同...
  • compileSdkVersion,targetSdkVersion和minSdkVersion三者的关系

    万次阅读 多人点赞 2018-07-30 16:13:29
    compileSdkVersion,targetSdkVersion和minSdkVersion ** *compileSdkVersion *定义应用程序编译选择哪个Android SDK版本,通常compileSDKVersion属性值被设置为最新的API版本,例如:25,改变...
  • a href="http://www.codeceo.com/article/android-compilesdkversion-minsdkversion-targetsdkversion.html" target="_self">原文链接</a></p><p>作者:Ian Lake,Google...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 137,388
精华内容 54,955
关键字:

targetsdk