首页 > 解决方案 > Android 在运行时找不到方法

问题描述

我有一个应用程序应该支持从 KitKat 开始的设备,因此最低 API 19。这在 Android 9-10 之前或多或少是可行的。

ServiceConnection.onBindingDied

有这个:

class MyActivity : AppCompatActivity(), AdapterView.OnItemSelectedListener, ServiceConnection {
  ...
  @RequiresApi(api = Build.VERSION_CODES.P)
  override fun onNullBinding(componentName: ComponentName?) {
      Log.d("MyActivity","onNullBinding(${componentName?.className} : ComponentName?)")
      super.onNullBinding(componentName)
  }
  @RequiresApi(api = Build.VERSION_CODES.O)
  override fun onBindingDied(componentName: ComponentName?) {
      Log.d("MyActivity","onBindingDied(${componentName?.className} : ComponentName?)")
      super.onBindingDied(componentName)
  }

将导致运行时错误I/dalvikvm: Could not find method android.content.ServiceConnection.onBindingDied, referenced from method com.my.app.MyActivity.onBindingDied

NotificationChannel.getId

从 Android 10 开始,前台服务需要通知,而通知现在需要通知通道。所以,在同一个班级里有这个:

    private fun recreateNotification() {
        val newNotificationContentTTitle = "${getText(R.string.notif_connection)} Bluetooth"
        val newNotificationContentText   = "${getText(R.string.notif_printer)} ${MyConfig.btData.name}"

        MyConfig.data.notificationManager.cancelAll() 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            MyConfig.data.notification = MyConfig.data.notificationBuilder
                .setOngoing(true)
                .setSmallIcon(android.R.drawable.stat_sys_warning)
                .setContentTitle(newNotificationContentTTitle)
                .setContentText(newNotificationContentText)
                .setPriority(NotificationManager.IMPORTANCE_LOW)
                .setCategory(Notification.CATEGORY_SERVICE)
                .setChannelId(MyConfig.data.notificationChannel.id)
                .build()
        } else {
            val pendingIntent: PendingIntent =
                Intent(this, FileService::class.java).let { notificationIntent ->
                    PendingIntent.getActivity(this, 0, notificationIntent, 0)
                }
            MyConfig.data.notification = Notification.Builder(this)
                .setContentTitle(newNotificationContentTTitle)
                .setContentText(newNotificationContentText)
                .setSmallIcon(android.R.drawable.stat_sys_warning)
                .setContentIntent(pendingIntent)
                .setTicker(getText(com.ny.app.R.string.printer_service_started)) // until Lollipop
                .build()
        }
        MyConfig.data.notificationManager.notify(MyConfig.data.notificationID, MyConfig.data.notification)
    }

我收到此运行时错误:I/dalvikvm: Could not find method android.app.NotificationChannel.getId, referenced from method com.ny.app.MyActivity.recreateNotification应用程序崩溃。

作为参考,MyConfig : Application()我用来存储静态/全局数据。我在 Android 4 设备上遇到了这些问题,但在 Android 10 设备上运行良好。

为什么不会@RequiresApiBuild.VERSION_CODES被尊重?


这些是我的 gradle 文件:

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    ext.kotlin_version = "1.5.0"
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.2.1"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
        jcenter() // Warning: this repository is going to shut down soon
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}
plugins {
    id 'com.android.application'
    id 'kotlin-android'
}
android {
    compileSdkVersion 30
    buildToolsVersion "30.0.3"
    defaultConfig {
        applicationId "com.ny.app"
        minSdkVersion 19
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
}
dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:2.0.4'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

和清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ny.app">

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-sdk
        android:minSdkVersion="19"
        android:targetSdkVersion="21" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar"
        android:name="com.ny.app.SConfig"
        android:directBootAware="true"
        android:persistent="true"
        android:persistableMode="persistAcrossReboots"
        android:requestLegacyExternalStorage="true">
        <activity android:name=".MyActivity">
            <intent-filter>
                <category android:name="android.intent.category.LAUNCHER" />
                <action android:name="android.intent.action.MAIN" />
            </intent-filter>
        </activity>
        <service
            android:name=".MyService"
            android:directBootAware="true"
            android:description="@string/notif4"
            android:stopWithTask="false" />
        <receiver android:name=".Receiver"></receiver>
    </application>
</manifest>

标签: androidkotlingradleandroid-api-levels

解决方案


推荐阅读