You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用SMS Retriever API发布模式运行App并解决ClassCastException问题

Fix ClassCastException in Release Mode & Comply with SMS Retriever API for Google Play

Hey there, let's tackle your problem step by step—first we'll squash that ClassCastException that's only popping up in release builds, then we'll set up the SMS Retriever API to meet Google Play's requirements for SMS verification.

1. Fixing the ClassCastException: $Proxy0 cannot be cast to d.a.a.a.k.h Error

This is 100% caused by ProGuard obfuscation breaking AsyncHttpClient's internal class structure. Debug mode works because obfuscation is disabled, and your previous release builds probably had different ProGuard rules or unchanged dependencies that didn't trigger this issue.

Here's how to fix it:

  • Open your proguard-rules.pro file and add these rules to exempt AsyncHttpClient and related classes from obfuscation:
    # Keep Android Async Http library classes intact
    -dontwarn com.loopj.android.http.**
    -keep class com.loopj.android.http.** { *; }
    
    # Preserve JSON classes to avoid parsing failures
    -keep class org.json.** { *; }
    
    # Keep your custom JsonHttpResponseHandler subclass methods
    -keepclassmembers class * extends com.loopj.android.http.JsonHttpResponseHandler {
        public void onSuccess(...);
        public void onFailure(...);
    }
    
  • Double-check your build.gradle release config to ensure it's using the correct ProGuard file (your current setup looks good, but confirm anyway):
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.release
        debuggable = true
    }
    
  • Clean and rebuild your release build: Run ./gradlew clean assembleRelease from the terminal, or use Android Studio's Build > Clean Project followed by Build > Generate Signed Bundle/APK.

2. Setting Up SMS Retriever API for Google Play Compliance

Google Play now discourages apps from using READ_SMS or RECEIVE_SMS permissions, so the SMS Retriever API is the way to go—it lets your app automatically grab verification SMS without needing those permissions.

Step-by-step setup:

  1. Confirm dependencies: You already have the required dependency in your build.gradle, but just make sure it's there:

    implementation 'com.google.android.gms:play-services-auth-api-phone:16.0.0'
    
  2. Add broadcast receiver to AndroidManifest.xml:

    <receiver
        android:name=".SMSBroadcastReceiver"
        android:exported="true">
        <intent-filter>
            <action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED" />
        </intent-filter>
    </receiver>
    
  3. Create the SMS broadcast receiver class:

    public class SMSBroadcastReceiver extends BroadcastReceiver {
        private SMSListener smsListener;
    
        public void setSmsListener(SMSListener smsListener) {
            this.smsListener = smsListener;
        }
    
        @Override
        public void onReceive(Context context, Intent intent) {
            if (SmsRetriever.SMS_RETRIEVED_ACTION.equals(intent.getAction())) {
                Bundle extras = intent.getExtras();
                Status status = (Status) extras.get(SmsRetriever.EXTRA_STATUS);
    
                switch (status.getStatusCode()) {
                    case CommonStatusCodes.SUCCESS:
                        // Grab the SMS content
                        String message = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);
                        if (smsListener != null) {
                            smsListener.onSMSReceived(message);
                        }
                        break;
                    case CommonStatusCodes.TIMEOUT:
                        // No SMS received within 5 minutes
                        if (smsListener != null) {
                            smsListener.onSMSFailure();
                        }
                        break;
                }
            }
        }
    
        public interface SMSListener {
            void onSMSReceived(String message);
            void onSMSFailure();
        }
    }
    
  4. Start the SMS Retriever in your OTP screen:

    // Initialize SMS Retriever client
    SmsRetrieverClient client = SmsRetriever.getClient(this);
    Task<Void> task = client.startSmsRetriever();
    
    // Listen for task success/failure
    task.addOnSuccessListener(aVoid -> 
        Toast.makeText(getApplicationContext(), "Waiting for verification SMS...", Toast.LENGTH_SHORT).show()
    );
    
    task.addOnFailureListener(e -> 
        Toast.makeText(getApplicationContext(), "Failed to start SMS listener", Toast.LENGTH_SHORT).show()
    );
    
    // Register the broadcast receiver
    SMSBroadcastReceiver receiver = new SMSBroadcastReceiver();
    receiver.setSmsListener(new SMSBroadcastReceiver.SMSListener() {
        @Override
        public void onSMSReceived(String message) {
            // Extract OTP from the SMS (adjust regex to match your SMS format)
            String otp = extractOTP(message);
            otpEditText.setText(otp);
        }
    
        @Override
        public void onSMSFailure() {
            Toast.makeText(getApplicationContext(), "No SMS received, please enter OTP manually", Toast.LENGTH_SHORT).show();
        }
    });
    
    registerReceiver(receiver, new IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION));
    

    Note: Implement the extractOTP() method to parse your verification code from the SMS text.

  5. Format your verification SMS correctly:
    Your SMS must include your app's unique hash value at the end, like this:

    LookAround: Your verification code is 123456
    FA+9qCX9VSu

    To get your app's hash value (use your release keystore for production builds):

    try {
        String packageName = getApplicationContext().getPackageName();
        PackageInfo packageInfo = getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
        for (Signature signature : packageInfo.signatures) {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            md.update(signature.toByteArray());
            String hashKey = Base64.encodeToString(md.digest(), Base64.NO_WRAP);
            Log.d("AppHash", hashKey);
        }
    } catch (PackageManager.NameNotFoundException | NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    

3. Final Checks

  • Test your release build again to confirm the ClassCastException is gone and your AsyncHttpClient requests work as expected.
  • Verify the SMS Retriever API works with your test SMS (make sure to use the release hash if testing a signed release build).
  • Remove any unnecessary SMS permissions (READ_SMS, RECEIVE_SMS) from your manifest—you won't need them with the SMS Retriever API, and this will help your app pass Google Play's policy checks.

内容的提问来源于stack exchange,提问作者Rohan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:38:51