Apk 在 Lollipop 上运行良好,但在 Jelly Bean 和 Marshmallow 上运行不佳

Apk working well on Lollipop, but not on Jelly Bean and Marshmallow

当我将 phone 与 android Lollipop 一起使用时,我的所有功能都运行良好,但是,当我使用 Android Marshmallow 或 Jelly Bean 应用程序崩溃时。

以下是应用程序模块的构建 gradle 文件:

apply plugin: 'com.android.application'

android {
compileSdkVersion 23
buildToolsVersion '23.0.1'
defaultConfig {
    applicationId "com.example.k.sms"
    minSdkVersion 14
    targetSdkVersion 23
    versionCode 1
    versionName "1.0"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
productFlavors {
}
}

dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
}

这是我的 logcat,当我使用 android Marshmallow

在模拟器中测试我的应用程序时
12-26 19:10:41.860 18000-18000/com.example.k.sms D/AndroidRuntime: Shutting down VM
   12-26 19:10:41.860 18000-18000/com.example.k.sms E/AndroidRuntime: FATAL EXCEPTION: main
                                                                      Process: com.example.k.sms, PID: 18000
                                                               java.lang.SecurityException: Sending SMS message: uid 10057 does not have android.permission.SEND_SMS.
                                                                   at android.os.Parcel.readException(Parcel.java:1599)
                                                                   at android.os.Parcel.readException(Parcel.java:1552)
                                                                   at com.android.internal.telephony.ISms$Stub$Proxy.sendTextForSubscriber(ISms.java:768)
                                                                   at android.telephony.SmsManager.sendTextMessageInternal(SmsManager.java:310)
                                                                   at android.telephony.SmsManager.sendTextMessage(SmsManager.java:293)
                                                                   at com.example.k.sms.MainActivity.onClick(MainActivity.java:149)
                                                                   at android.view.View.performClick(View.java:5198)
                                                                   at android.view.View$PerformClick.run(View.java:21147)
                                                                   at android.os.Handler.handleCallback(Handler.java:739)
                                                                   at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                   at android.os.Looper.loop(Looper.java:148)
                                                                   at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                   at java.lang.reflect.Method.invoke(Native Method)
                                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

targetSdkVersion 23

java.lang.SecurityException: Sending SMS message: uid 10057 does not have android.permission.SEND_SMS.

看来你只是撞到了 targetSdk 没有意识到后果。当您以 API23 或更高版本为目标时,Marshmallow 引入了运行时权限模型,您的应用程序必须支持新的运行时权限模型,因为在这种情况下,清单声明的权限不再足够。

快速解决方案是将 targetSdk 设置为 22(或更低),因为只有这样运行时权限才会启动。引用 docs:

On all versions of Android, your app needs to declare both the normal and the dangerous permissions it needs in its app manifest, as described in Declaring Permissions. However, the effect of that declaration is different depending on the system version and your app's target SDK level:

  • If the device is running Android 5.1 or lower, or your app's target SDK is 22 or lower: If you list a dangerous permission in your manifest, the user has to grant the permission when they install the app; if they do not grant the permission, the system does not install the app at all.
  • If the device is running Android 6.0 or higher, and your app's target SDK is 23 or higher: The app has to list the permissions in the manifest, and it must request each dangerous permission it needs while the app is running. The user can grant or deny each permission, and the app can continue to run with limited capabilities even if the user denies a permission request.

如果您需要旧 API 中不可用的任何东西并且必须保持 targetSdk 23 或更高版本,那么您必须支持运行时权限(有一些外部库可以帮助解决这个问题)。

在清单中为 lollipop 和其他较低版本提供短信权限,并添加 Marshmallow 权限检查以获得高于 lollipop 的权限,如 android

中的运行时权限中所述