当前位置: 首页 > 知识库问答 >
问题:

实现USSD特性。将服务绑定到PhoneUtils,而无需在每次更新时重新启动电话

苏硕
2023-03-14

我正在尝试在Android上实现一个发送、接收和解析USSD代码的应用程序。到目前为止,我使用了http://commandus.com/blog/?p=58上的代码来获得这个功能。为了使服务正常工作,需要重新启动电话。当用户第一次安装应用程序时,这不会是一个问题,但我注意到在模拟器上测试时,手机需要在每次更新时重新启动,即使该服务没有任何新内容。我想知道的是:

    null
* This file is auto-generated.  DO NOT MODIFY.
package com.android.internal.telephony;

/**
 * Interface used to interact with extended MMI/USSD network service.
 */
public interface IExtendedNetworkService extends android.os.IInterface {
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements
        com.android.internal.telephony.IExtendedNetworkService {
    private static final java.lang.String DESCRIPTOR = "com.android.internal.telephony.IExtendedNetworkService";

    /** Construct the stub at attach it to the interface. */
    public Stub() {
        this.attachInterface(this, DESCRIPTOR);
    }

    /**
     * Cast an IBinder object into an
     * com.android.internal.telephony.IExtendedNetworkService interface,
     * generating a proxy if needed.
     */
    public static com.android.internal.telephony.IExtendedNetworkService asInterface(
            android.os.IBinder obj) {
        if ((obj == null)) {
            return null;
        }
        android.os.IInterface iin = (android.os.IInterface) obj
                .queryLocalInterface(DESCRIPTOR);
        if (((iin != null) && (iin instanceof com.android.internal.telephony.IExtendedNetworkService))) {
            return ((com.android.internal.telephony.IExtendedNetworkService) iin);
        }
        return new com.android.internal.telephony.IExtendedNetworkService.Stub.Proxy(
                obj);
    }

    public android.os.IBinder asBinder() {
        return this;
    }

    @Override
    public boolean onTransact(int code, android.os.Parcel data,
            android.os.Parcel reply, int flags)
            throws android.os.RemoteException {
        switch (code) {
        case INTERFACE_TRANSACTION: {
            reply.writeString(DESCRIPTOR);
            return true;
        }
        case TRANSACTION_setMmiString: {
            data.enforceInterface(DESCRIPTOR);
            java.lang.String _arg0;
            _arg0 = data.readString();
            this.setMmiString(_arg0);
            reply.writeNoException();
            return true;
        }
        case TRANSACTION_getMmiRunningText: {
            data.enforceInterface(DESCRIPTOR);
            java.lang.CharSequence _result = this.getMmiRunningText();
            reply.writeNoException();
            if ((_result != null)) {
                reply.writeInt(1);
                android.text.TextUtils
                        .writeToParcel(
                                _result,
                                reply,
                                android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
            } else {
                reply.writeInt(0);
            }
            return true;
        }
        case TRANSACTION_getUserMessage: {
            data.enforceInterface(DESCRIPTOR);
            java.lang.CharSequence _arg0;
            if ((0 != data.readInt())) {
                _arg0 = android.text.TextUtils.CHAR_SEQUENCE_CREATOR
                        .createFromParcel(data);
            } else {
                _arg0 = null;
            }
            java.lang.CharSequence _result = this.getUserMessage(_arg0);
            reply.writeNoException();
            if ((_result != null)) {
                reply.writeInt(1);
                android.text.TextUtils
                        .writeToParcel(
                                _result,
                                reply,
                                android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
            } else {
                reply.writeInt(0);
            }
            return true;
        }
        case TRANSACTION_clearMmiString: {
            data.enforceInterface(DESCRIPTOR);
            this.clearMmiString();
            reply.writeNoException();
            return true;
        }
        }
        return super.onTransact(code, data, reply, flags);
    }

    private static class Proxy implements
            com.android.internal.telephony.IExtendedNetworkService {
        private android.os.IBinder mRemote;

        Proxy(android.os.IBinder remote) {
            mRemote = remote;
        }

        public android.os.IBinder asBinder() {
            return mRemote;
        }

        public java.lang.String getInterfaceDescriptor() {
            return DESCRIPTOR;
        }

        /**
         * Set a MMI/USSD command to ExtendedNetworkService for further
         * process. This should be called when a MMI command is placed from
         * panel.
         * 
         * @param number
         *            the dialed MMI/USSD number.
         */
        public void setMmiString(java.lang.String number)
                throws android.os.RemoteException {
            android.os.Parcel _data = android.os.Parcel.obtain();
            android.os.Parcel _reply = android.os.Parcel.obtain();
            try {
                _data.writeInterfaceToken(DESCRIPTOR);
                _data.writeString(number);
                mRemote.transact(Stub.TRANSACTION_setMmiString, _data,
                        _reply, 0);
                _reply.readException();
            } finally {
                _reply.recycle();
                _data.recycle();
            }
        }

        /**
         * return the specific string which is used to prompt MMI/USSD is
         * running
         */
        public java.lang.CharSequence getMmiRunningText()
                throws android.os.RemoteException {
            android.os.Parcel _data = android.os.Parcel.obtain();
            android.os.Parcel _reply = android.os.Parcel.obtain();
            java.lang.CharSequence _result;
            try {
                _data.writeInterfaceToken(DESCRIPTOR);
                mRemote.transact(Stub.TRANSACTION_getMmiRunningText, _data,
                        _reply, 0);
                _reply.readException();
                if ((0 != _reply.readInt())) {
                    _result = android.text.TextUtils.CHAR_SEQUENCE_CREATOR
                            .createFromParcel(_reply);
                } else {
                    _result = null;
                }
            } finally {
                _reply.recycle();
                _data.recycle();
            }
            return _result;
        }

        /**
         * Get specific message which should be displayed on pop-up dialog.
         * 
         * @param text
         *            original MMI/USSD message response from framework
         * @return specific user message correspond to text. null stands for
         *         no pop-up dialog need to show.
         */
        public java.lang.CharSequence getUserMessage(
                java.lang.CharSequence text)
                throws android.os.RemoteException {
            android.os.Parcel _data = android.os.Parcel.obtain();
            android.os.Parcel _reply = android.os.Parcel.obtain();
            java.lang.CharSequence _result;
            try {
                _data.writeInterfaceToken(DESCRIPTOR);
                if ((text != null)) {
                    _data.writeInt(1);
                    android.text.TextUtils.writeToParcel(text, _data, 0);
                } else {
                    _data.writeInt(0);
                }
                mRemote.transact(Stub.TRANSACTION_getUserMessage, _data,
                        _reply, 0);
                _reply.readException();
                if ((0 != _reply.readInt())) {
                    _result = android.text.TextUtils.CHAR_SEQUENCE_CREATOR
                            .createFromParcel(_reply);
                } else {
                    _result = null;
                }
            } finally {
                _reply.recycle();
                _data.recycle();
            }
            return _result;
        }

        /**
         * Clear pre-set MMI/USSD command. This should be called when user
         * cancel a pre-dialed MMI command.
         */
        public void clearMmiString() throws android.os.RemoteException {
            android.os.Parcel _data = android.os.Parcel.obtain();
            android.os.Parcel _reply = android.os.Parcel.obtain();
            try {
                _data.writeInterfaceToken(DESCRIPTOR);
                mRemote.transact(Stub.TRANSACTION_clearMmiString, _data,
                        _reply, 0);
                _reply.readException();
            } finally {
                _reply.recycle();
                _data.recycle();
            }
        }
    }

    static final int TRANSACTION_setMmiString = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
    static final int TRANSACTION_getMmiRunningText = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
    static final int TRANSACTION_getUserMessage = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
    static final int TRANSACTION_clearMmiString = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
}

/**
 * Set a MMI/USSD command to ExtendedNetworkService for further process.
 * This should be called when a MMI command is placed from panel.
 * 
 * @param number
 *            the dialed MMI/USSD number.
 */
public void setMmiString(java.lang.String number)
        throws android.os.RemoteException;

/**
 * return the specific string which is used to prompt MMI/USSD is running
 */
public java.lang.CharSequence getMmiRunningText()
        throws android.os.RemoteException;

/**
 * Get specific message which should be displayed on pop-up dialog.
 * 
 * @param text
 *            original MMI/USSD message response from framework
 * @return specific user message correspond to text. null stands for no
 *         pop-up dialog need to show.
 */
public java.lang.CharSequence getUserMessage(java.lang.CharSequence text)
        throws android.os.RemoteException;

/**
 * Clear pre-set MMI/USSD command. This should be called when user cancel a
 * pre-dialed MMI command.
 */
public void clearMmiString() throws android.os.RemoteException;
}
package net.g_el.mobile.mtc;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.IBinder;
import android.os.PatternMatcher;
import android.os.RemoteException;
import android.util.Log;

import com.android.internal.telephony.IExtendedNetworkService;

/**
* Service implements IExtendedNetworkService interface.
* USSDDumbExtendedNetworkService Service must have name
* "com.android.ussd.IExtendedNetworkService" of the intent declared in the
* Android manifest file so com.android.phone.PhoneUtils class bind to this
* service after system rebooted. Please note service is loaded after system
* reboot! Your application must check is system rebooted.
* 
* @see Util#syslogHasLine(String, String, String, boolean)
*/
public class USSDDumbExtendedNetworkService extends Service {
public static final String TAG = "MobileServices";
public static final String LOG_STAMP = "*USSDTestExtendedNetworkService bind successfully*";
public static final String URI_SCHEME = "ussd";
public static final String URI_AUTHORITY = "g_el.net";
public static final String URI_PATH = "/";
public static final String URI_PAR = "return";
public static final String URI_PARON = "on";
public static final String URI_PAROFF = "off";
public static final String MAGIC_ON = ":ON;)";
public static final String MAGIC_OFF = ":OFF;(";
public static final String MAGIC_RETVAL = ":RETVAL;(";

private static boolean mActive = false;
private static CharSequence mRetVal = null;
private Context mContext = null;
private String msgUssdRunning = "G Testing...";

final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_INSERT.equals(intent.getAction())) {
            mContext = context;
            if (mContext != null) {
                msgUssdRunning = mContext.getString(R.string.msgRunning);
                mActive = true;
                Log.d(TAG, "activate");
            }
        } else if (Intent.ACTION_DELETE.equals(intent.getAction())) {
            mContext = null;
            mActive = false;
            Log.d(TAG, "deactivate");
        }
    }
};

private final IExtendedNetworkService.Stub mBinder = new IExtendedNetworkService.Stub() {

    @Override
    public void setMmiString(String number) throws RemoteException {
        Log.d(TAG, "setMmiString: " + number);
    }

    @Override
    public CharSequence getMmiRunningText() throws RemoteException {
        Log.d(TAG, "getMmiRunningText: " + msgUssdRunning);
        return msgUssdRunning;
    }

    @Override
    public CharSequence getUserMessage(CharSequence text)
            throws RemoteException {
        if (MAGIC_ON.contentEquals(text)) {
            mActive = true;
            Log.d(TAG, "control: ON");
            return text;
        } else {
            if (MAGIC_OFF.contentEquals(text)) {
                mActive = false;
                Log.d(TAG, "control: OFF");
                return text;
            } else {
                if (MAGIC_RETVAL.contentEquals(text)) {
                    mActive = false;
                    Log.d(TAG, "control: return");
                    return mRetVal;
                }
            }
        }

        if (!mActive) {
            Log.d(TAG, "getUserMessage deactivated: " + text);
            //return null;//Use this in order to cancel the output on the screen.
            return text;
        }
        String s = text.toString();
        // store s to the !
        Uri uri = new Uri.Builder().scheme(URI_SCHEME).authority(URI_AUTHORITY).path(URI_PATH).appendQueryParameter(URI_PAR,text.toString()).build();
        sendBroadcast(new Intent(Intent.ACTION_GET_CONTENT, uri));
        mActive = false;
        mRetVal = text;
        Log.d(TAG, "getUserMessage: " + text + "=" + s);
        return null;
    }

    @Override
    public void clearMmiString() throws RemoteException {
        Log.d(TAG, "clearMmiString");
    }
};

/**
 * Put stamp to the system log when PhoneUtils bind to the service after
 * Android has rebooted. Application must call
 * {@link Util#syslogHasLine(String, String, String, boolean)} to check is
 * phone rebooted or no. Without reboot phone application does not bind tom
 * this service!
 */
@Override
public IBinder onBind(Intent intent) {
    IntentFilter filter = new IntentFilter();
    filter.addAction(Intent.ACTION_INSERT);
    filter.addAction(Intent.ACTION_DELETE);
    filter.addDataScheme(URI_SCHEME);
    filter.addDataAuthority(URI_AUTHORITY, null);
    filter.addDataPath(URI_PATH, PatternMatcher.PATTERN_LITERAL);
    registerReceiver(mReceiver, filter);
    // Do not localize!
    Log.i(TAG, LOG_STAMP);

    return mBinder;
}

public IBinder asBinder() {
    Log.d(TAG, "asBinder");
    return mBinder;
}

@Override
public boolean onUnbind(Intent intent) {
    unregisterReceiver(mReceiver);
    return super.onUnbind(intent);
}

   }

共有1个答案

祁俊喆
2023-03-14

请清楚,您完全陷入了平台内部实现的杂草中。听起来你是想让它“好”地工作。你现在做的事情不会很好,没错。您无法保证这些内部实现在不同版本的平台上,甚至在制造商设备上的不同平台构建上都保持不变,也无法保证您看到的围绕此接口的行为在不同情况下都能正常工作。

这只是糟糕糟糕糟糕。别这样。

 类似资料:
  • 问题内容: 如果我的进程正在加载.so库,并且该库有新版本可用,是否可以在不重新启动进程的情况下切换到新库?还是答案取决于诸如库中现有功能之一是否有参数更改之类的事情? 我正在一个相当大的系统中工作,该系统运行100多个进程,每个系统加载10多个库。这些库提供特定的功能,并由独立的团队提供。因此,当其中一个库发生更改(可以说是针对错误修复)时,理想的做法是在后台发布它而不影响运行的过程。可能吗 ?

  • 我正在开发一个。能让它一变就重启吗?我正在Coffeescript中开发它。是否可以监视以便在保存更改时重新启动?

  • 问题内容: 我正在尝试为我的Java游戏添加重启/重播功能。当前在我的Game类(GUI和游戏被初始化的地方)中,我有: 游戏对象包含整个游戏窗口的GUI,并包含各种对象(例如实际游戏窗口,计分板,倒数计时器等)。 我想添加一个功能,如果他们单击GUI上的重新启动按钮或游戏结束后,游戏将重新启动(以及倒计时和计分)。我确实意识到最好重新实例化对象(计分,倒数),但是一旦实例化,它们便成为我的GUI

  • 问题内容: 有什么方法可以在不重启mySQL服务器的情况下 清除 mysql 查询缓存 ? 问题答案: 我相信您可以使用… …如果您所运行的用户具有重新加载权限。另外,您可以通过…对查询缓存进行碎片整理。 有关更多信息,请参见MySQL手册的“ 查询缓存状态和维护”部分。

  • 问题内容: 我想在Docker容器中运行的Nginx中添加/删除服务器 我在Dockerfile中使用ADD命令将我的nginx.conf添加到/ etc / nginx目录中。 然后在我正在运行的nginx容器中有一个像这样的conf 如何重新启动我的Nginx以使已编辑的Nginx.conf生效? 先感谢您! 问题答案: 要重新加载NGINX配置,请运行以下命令 docker kill -s

  • 我们在Android8.1及以上版本中偶然发现了一个我们以前从未见过的问题,不幸的是,这使得我们的应用程序对我们的用户来说不太方便。在Android 8.1及以上版本中,当用户刷屏杀死应用程序时,后台粘性服务不会重新启动。