SecurityException:对签名 APK 上的错误接口的 Binder 调用

Posted

技术标签:

【中文标题】SecurityException:对签名 APK 上的错误接口的 Binder 调用【英文标题】:SecurityException: Binder invocation to an incorrect interface on signed APK 【发布时间】:2017-01-17 15:41:49 【问题描述】:

我正在开发一个位置感知应用程序。我将 Google Play Location Services 和 Google Maps 集成到我的应用程序中。我的应用程序在调试模式下运行没有问题。当我在发布模式下生成签名的 APK 并运行应用程序时,它在启动时崩溃,并出现以下异常:

Process: com.example.akif, PID: 4233
    java.lang.RuntimeException: Unable to resume activity com.example.akif/com.example.akif.activities.MainActivity: java.lang.SecurityException: Binder invocation to an incorrect interface
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3400)
    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3440)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2713)
    at android.app.ActivityThread.-wrap12(ActivityThread.java)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6077)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: java.lang.SecurityException: Binder invocation to an incorrect interface
    at android.os.Parcel.nativeEnforceInterface(Native Method)
    at android.os.Parcel.enforceInterface(Parcel.java:482)
    at vz.onTransact(:com.google.android.gms.DynamiteModulesB:81)
    at android.os.Binder.transact(Binder.java:499)
    at com.google.android.gms.maps.a.bt.c(Unknown)
    at com.google.android.gms.maps.i.b(Unknown)
    at com.google.android.gms.b.d.b(Unknown)
    at com.google.android.gms.b.j.a(Unknown)
    at com.google.android.gms.maps.h.b(Unknown)
    at com.google.android.gms.maps.h.a(Unknown)
    at com.google.android.gms.b.a.c(Unknown)
    at com.google.android.gms.b.a.e(Unknown)
    at com.google.android.gms.maps.g.f(Unknown)
    at android.support.v4.app.k.ay(Unknown)
    at android.support.v4.app.x.l(Unknown)
    at android.support.v4.app.ax.h(Unknown)
    at android.support.v4.app.ax.i(Unknown)
    at android.support.v4.app.ax.run(Unknown)
    at android.support.v4.app.x.ae(Unknown)
    at android.support.v4.app.i.aa(Unknown)
    at android.support.v4.app.a.onPostResume(Unknown)
    at android.support.v7.app.a.onPostResume(Unknown)
    at android.app.Activity.performResume(Activity.java:6792)
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3377)
    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3440) 
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2713) 
    at android.app.ActivityThread.-wrap12(ActivityThread.java) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:154) 
    at android.app.ActivityThread.main(ActivityThread.java:6077) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 

我注意到每个生命周期方法的以下日志都发生在我的片段的 onResume 方法中,我在该方法中检查 Google Play 服务的可用性,如下所示:

@Override public void onResume() 
    Log.debug(getClass(), "onResume()");

    GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();

    int googlePlayServicesAvailabilityResult = googleApiAvailability.isGooglePlayServicesAvailable(getContext());

    if (googlePlayServicesAvailabilityResult != ConnectionResult.SUCCESS) 
        if (!googleApiAvailability.isUserResolvableError(googlePlayServicesAvailabilityResult)) 
            Toast.makeText(getContext(), "Your device doesn't support Google Play location services. This application cannot run without it!", Toast.LENGTH_LONG).show();

            getActivity().finish();

            return;
        

        Dialog errorDialog = googleApiAvailability.getErrorDialog(getActivity(), googlePlayServicesAvailabilityResult, GOOGLE_PLAY_SERVICES_REQUEST_CODE);

        if (errorDialog != null) 
            errorDialog.setCancelable(false);
            errorDialog.setCanceledOnTouchOutside(false);
            errorDialog.setOnDismissListener((DialogInterface dialogInterface) -> 
                Toast.makeText(getContext(), "You need Google Play location services to run this application!", Toast.LENGTH_LONG).show();

                getActivity().finish();
            );

            errorDialog.show();
        
     else if (googleApiClient.isConnected() && !isUpdatingLocation) 
        startLocationUpdates();
    

    super.onResume();

我的 gradle 文件如下所示:

apply plugin: 'com.android.application'

android 
    compileSdkVersion 24
    buildToolsVersion "24.0.1"

    defaultConfig 
        applicationId "com.example.akif"
        minSdkVersion 15
        targetSdkVersion 24
        versionCode 1
        versionName "0.1"

        jackOptions 
            enabled true
        
    

    compileOptions 
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    

    buildTypes 
        debug 
            applicationIdSuffix '.test'
        

        release 
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        
    


dependencies 
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile 'com.android.support:appcompat-v7:24.2.0'
    compile 'com.android.support:cardview-v7:24.2.0'
    compile 'com.android.support:design:24.2.0'
    compile 'com.android.support:preference-v7:24.2.0'
    compile 'com.google.android.gms:play-services-location:9.4.0'
    compile 'com.google.android.gms:play-services-maps:9.4.0'
    compile 'com.github.mehmetakiftutuncu:toolbelt:1.1.0'
    compile 'com.squareup.okhttp3:okhttp:3.4.1'
    compile 'joda-time:joda-time:2.9.4'

我根据我的包名com.example.akif.testcom.example.akif 分别为调试和发布模式设置了两个Google Maps API 密钥。所以,我认为这与包名称无关,但话又说回来,很可能与此有关,因为我对错误一无所知。

知道发生了什么吗?

【问题讨论】:

这看起来类似于this thread。 @noogui 但事实并非如此。我没有使用计费服务。我也没有任何 AIDL 文件。 【参考方案1】:

在进行了大量研究但几乎没有结果后,我能够通过以下 Proguard 规则解决问题:

-keep public class com.google.android.gms.*  public *; 
-dontwarn com.google.android.gms.**

我仍然不知道我遇到此问题的真正原因,但它似乎已解决。

希望这会有所帮助。

【讨论】:

你存的太多了。见***.com/a/39701449/94363

以上是关于SecurityException:对签名 APK 上的错误接口的 Binder 调用的主要内容,如果未能解决你的问题,请参考以下文章

Java SecurityException:签名者信息不匹配

在 Android 10 上安装更新同一应用的 apk 失败; java.lang.SecurityException:文件仍然打开

java.lang.SecurityException: GoogleCertificatesRslt: 使用调试密钥签名的包 (go/gsrlt)

Android开发对apk文件进行签名

尝试签署 ANDROID 应用程序时出现异常 - “java.lang.SecurityException:Manifest 主要属性的签名文件摘要无效”

apk签名工具