Trying to build USSD dialing extension.

I Want to make a ussd extension that dial ussd, get Responce, and reply to it

The code is below:

package ussd.ext.kodular;

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.telephony.TelephonyManager;
import android.util.Log;
import com.google.appinventor.components.annotations.*;
import com.google.appinventor.components.common.ComponentCategory;
import com.google.appinventor.components.runtime.AndroidNonvisibleComponent;
import com.google.appinventor.components.runtime.ComponentContainer;
import com.google.appinventor.components.runtime.EventDispatcher;

@DesignerComponent(
        version = 1,
        description = "Perform Ussd Functions",
        category = ComponentCategory.EXTENSION,
        nonVisible = true,
        iconName = "")

@SimpleObject(external = true)
public class UssdExt extends AndroidNonvisibleComponent {

    //Activity and Context
    private Context context;
    private Activity activity;

    public UssdExt(ComponentContainer container){
        super(container.$form());
        this.activity = container.$context();
        this.context = container.$context();
    }

    @SimpleFunction(description = "Dial a USSD code and get the response")
    public void dialUssdCode(final String ussdCode){
        if (hasPermissions()) {
            new AsyncTask<Void, Void, Void>() {
                protected Void doInBackground(Void... params) {
                    try {
                        TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
                        if (telephonyManager != null) {
                            telephonyManager.sendUssdRequest(ussdCode, new TelephonyManager.UssdResponseCallback() {
                                public void onReceiveUssdResponse(final CharSequence response) {
                                    Log.d("USSD Response", response.toString());
                                    // Trigger an event to pass the response back to the app
                                    activity.runOnUiThread(new Runnable() {
                                        public void run() {
                                            UssdResponseReceived(response.toString());
                                        }
                                    });
                                }

                                public void onReceiveUssdResponseFailed(int failureCode) {
                                    Log.d("USSD Response", "Failed with code: " + failureCode);
                                    // Trigger an event to indicate the failure
                                    UssdResponseFailed(failureCode);
                                }
                            }, null);
                        }
                    } catch (SecurityException e) {
                        e.printStackTrace();
                    }
                    return null;
                }
            }.execute();
        } else {
            Log.d("USSD Response", "Permissions not granted");
        }
    }

    private boolean hasPermissions() {
        return (activity.checkSelfPermission(android.Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED &&
                activity.checkSelfPermission(android.Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED);
    }

    @SimpleEvent(description = "Event triggered when a USSD response is received")
    public void UssdResponseReceived(String response){
        EventDispatcher.dispatchEvent(this, "UssdResponseReceived", response);
    }

    @SimpleEvent(description = "Event triggered when a USSD request fails")
    public void UssdResponseFailed(int errorCode){
        EventDispatcher.dispatchEvent(this, "UssdResponseFailed", errorCode);
    }

    @SimpleFunction(description = "Reply to a USSD message")
    public void replyToUssd(String message){
        // Implement reply functionality here
    }
}

But its not working. I dont know why. Can any one help me please?

You should add ussd response failed event to run on ui thread

And you can try using AsynchUtil instead of AsyncTask

AsynchUtil.runAsynchronously(new Runnable() {
    @Override
    public void run() {
        try {
            TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            if (telephonyManager != null) {
                telephonyManager.sendUssdRequest(ussdCode, new TelephonyManager.UssdResponseCallback() {
                    @Override
                    public void onReceiveUssdResponse(TelephonyManager telephonyManager, String request, String response) {
                        Log.d("USSD Response", response);
                        activity.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                UssdResponseReceived(response);
                            }
                        });
                    }

                    @Override
                    public void onReceiveUssdResponseFailed(TelephonyManager telephonyManager, String request, int failureCode) {
                        Log.d("USSD Response", "Failed with code: " + failureCode);
                        activity.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                UssdResponseFailed(failureCode);
                            }
                        });
                    }
                }, null);
            } else {
                Log.d("USSD Response", "TelephonyManager is null");
            }
        } catch (SecurityException e) {
            e.printStackTrace();
        }
    }
});

    

Don’t forget import AsynchUtil

import com.google.appinventor.components.runtime.util.AsynchUtil;
1 Like