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

Android IntentService中USSD请求无响应问题修复求助

修复你的USSD IntentService问题

看起来你遇到的问题主要是线程阻塞、回调方法未正确重写以及IntentService的使用方式不当导致的。我会一步步帮你修复代码,并解释每个问题点:

主要问题分析

  • 工作线程阻塞:你在onHandleIntent里用while(jobInProgress)循环卡死了IntentService的工作线程,这种阻塞完全没必要——IntentService的设计初衷就是处理完任务后自动销毁,不需要手动循环等待。
  • 回调方法未正确重写:你的MyCallback方法没有加@Override注解,一旦方法签名有细微错误,编译器无法检测,就会导致回调根本不触发,这是你看不到Toast的核心原因之一。
  • 不必要的Handler:sendUssdRequest的第三个Handler参数可以传null,系统会自动用主线程Handler执行回调,不需要手动创建。
  • jobInProgress初始值错误:初始设为true会导致循环直接启动,实际上应该在发起请求前才设为true。

修复后的完整代码

public class MyService extends IntentService {
    public static boolean jobInProgress = false;
    private TelephonyManager tm;

    // IntentService必须显式提供构造函数
    public MyService() {
        super("MyService");
    }

    // 正确实现USSD回调,添加@Override确保重写父类方法
    class MyCallback extends TelephonyManager.UssdResponseCallback {
        private final Context mContext;

        MyCallback(Context context) {
            this.mContext = context.getApplicationContext(); // 使用Application Context更稳妥
        }

        @Override
        public void onReceiveUssdResponse(TelephonyManager telephonyManager, String request, CharSequence response) {
            super.onReceiveUssdResponse(telephonyManager, request, response);
            Toast.makeText(mContext, "Response from network is : " + response, Toast.LENGTH_LONG).show();
            jobInProgress = false;
            stopSelf(); // 回调完成后主动停止服务
        }

        @Override
        public void onReceiveUssdResponseFailed(TelephonyManager telephonyManager, String request, int failureCode) {
            super.onReceiveUssdResponseFailed(telephonyManager, request, failureCode);
            Toast.makeText(mContext, "USSD request failed with code " + failureCode, Toast.LENGTH_LONG).show();
            jobInProgress = false;
            stopSelf(); // 请求失败也停止服务
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Toast.makeText(this, "Service is created.", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Toast.makeText(this, "Service is destroyed", Toast.LENGTH_LONG).show();
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        doJob();
        // 移除阻塞循环,回调触发后会主动停止服务
    }

    private void doJob() {
        tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
        if (tm == null) {
            Toast.makeText(getApplicationContext(), "TelephonyManager initialization failed", Toast.LENGTH_SHORT).show();
            stopSelf();
            return;
        }

        // 检查权限,API23+必须动态申请CALL_PHONE权限
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(getApplicationContext(), "CALL_PHONE permission not granted", Toast.LENGTH_SHORT).show();
            stopSelf();
            return;
        }

        jobInProgress = true;
        // 第三个参数传null,系统自动使用主线程Handler执行回调
        tm.sendUssdRequest("#105*2#", new MyCallback(this), null);
    }
}

额外注意事项

  • 动态权限申请:API23及以上系统,启动服务前要先动态申请CALL_PHONE权限:
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, 100);
        return;
    }
    // 权限通过后再启动服务
    startService(new Intent(this, MyService.class));
    
  • Manifest配置:确保在Manifest中注册服务并声明权限:
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 可选,用于检测网络状态 -->
    
    <application ...>
        <service android:name=".MyService" />
    </application>
    
  • 双卡设备适配:如果需要支持双卡,需使用TelephonyManager.createForSubscriptionId()获取对应卡槽的实例,否则默认使用主卡槽。

修改后,你的服务就能正常发起USSD请求,收到响应或失败时弹出Toast,最后自动停止服务。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:05:57