解决方法
1.首先尝试,Intent.ACTION_DIAL
确实,在开始时,可以直接从应用程序(使用意图Intent.ACTION_DIAL)调用USSD代码,甚至可以从网站调用,只需使用“tel:”模式.打开拨号器,输入所需的数字.当您放入最后一个#时,代码会自动发送,对用户来说几乎是透明的,不需要进行交互.但这实际上被认为是系统的一个漏洞,因为有人可能会编写恶意软件,甚至更多,在网站中插入恶意代码甚至可能会擦除手机或阻止SIM卡.您可以阅读此内容,例如in this link
截至2012年9月,似乎三星终于fixed that vulnerability所以例如你的S3无法做到这一点.此时很难找到任何仍然易受攻击的设备.
2.第二次尝试,解决方法
好吧,Android中的所有内容都是应用,即使手机本身也是一款应用.那么,为什么我们不能尝试复制它的代码呢?实际上,当用户手动发送ussd时会发生什么?
答案太可能了:
易于测试:我将手机置于飞行模式,所以如果必须发送代码,希望它能够.这是我的预期:我拨打了代码,出现了ServiceMode屏幕!它是空的,所以我们可以说拨号器打开一个系统应用程序,这个应用程序调用提供程序.
很容易找出这个应用程序.在三星设备中,至少在S4中,它的名字是ServiceMode.您可以在设置>中找到它.应用程序管理器>所有.因此,我们可以尝试通过以下方法之一了解它是如何推出的:
2.1.阅读手机应用程序代码
我试过了,但一开始就很混乱,所以我去了选项2
2.2.检查服务模式应用程序
我打开ES文件浏览器>应用经理.
连接手机,在手机/备份/应用程序,我有servicestatus apk.
几分钟或逆向工程之后,我有了清单文件,就像它所使用的那样具有启发性.在那里我可以看到一堆活动,还有一些广播接收器.我不知道我更害怕什么.
2.2.1让我们尝试一下这些活动.
既然我们知道我们可以从另一个开放一个特定的应用程序,我将尝试编写一个简单的应用程序,打开其中一个活动.这很简单:
Intent i= new Intent(Intent.Action_MAIN); i.setClass( "package name","class name"); startActivity(i);
由于此应用程序不打算从启动器图标打开,因此它没有带有intent过滤器的活动,让我们知道它是主要活动.所以我必须尝试至少其中一些.但无论如何,我看到了一些我不喜欢的东西.我稍后会告诉你.
我试过了,但是,正如我所料,我无法打开那些活动.我得到一个未找到活动的例外.所以,让我们试试接收器.至少这会很有趣.
2.2.2让我们试试接收器.
有一些,但特别是我喜欢这个意图过滤器:
<intent-filter> <action android:name="android.provider.Telephony.SECRET_CODE" /> ...
看起来不错.我去了Telephony.java,在那里我可以看到:
/** * Broadcast Action: A "secret code" has been entered in the dialer. Secret codes are * of the form *#*#<code>#*#*. The intent will have the data URI:</p> * * <p><code>android_secret_code://<code></code></p> */ public static final String SECRET_CODE_ACTION = "android.provider.Telephony.SECRET_CODE";
看起来很棒,它是一个特定的意图,可能我们需要的模式不是“tel:”而是“android_secret_code://”,可能代码必须采用不同的内部格式.
我试着或多或少只是为了好玩,因为我知道我在活动中遇到了同样的问题,这是:
<permission android:name="com.sec.android.app.servicemodeapp.permission.KEYSTRING" android:protectionLevel="signatureOrSystem" />
该应用程序声明此权限,每个组件都使用它.所以,或者您知道如何声明和设置签名,或者您是一个系统应用程序.否则你根本无法与这个应用程序进行交互.
当然,您甚至无法考虑创建自己的服务模式应用程序,因为如果不是系统应用程序,您就不会与提供程序进行这种通信(因为您必须通过一些会说“伤心”的固件应用程序你觉得你是“”吗?
结论
在他看来,我们无能为力,至少使用三星手机,我们可以认为每一部手机都是一样的.
备择方案
嗯,实际上没有一个真正好.但是让我们看看:
备选方案1.找到另一种ussd代码
我们知道有两种USSD.当您拨打最后一个#时,操作会自动触发,另一个则需要您按下呼叫按钮.
如果您尝试使用第三方拨号程序,则可以看到
>当您拨打第一种类型的代码时,根本不会触发任何内容(只有固件拨号器可以触发它们)
>您可以使用其他类型(类型代码按下调用).我想这意味着这种代码的风险较小,因为它不会改变设备中的任何内容,因此它们是允许的.
>当然,如果您键入第一种类型的代码并按下调用,则会出现错误,因为该代码无法正常工作.
因此,如果第三方可以发送该类型的代码,则每个应用都可以.因此,如果您可以尝试查找在用户按下呼叫按钮后触发的该类型的替代ussd代码,您可以实现所需的功能.在这种情况下,您应该使用Intent.ACTION_CALL意图
//如果您使用ACTION_DIAL意图,它会打开拨号器并将给定的数字放入其中.
//同时,如果我们使用ACTION_CALL,应用程序将直接调用.
Intent intent = new Intent(Intent.ACTION_CALL); intent.setData(Uri.parse("tel:"+ "*" + Uri.encode("#") + "0011" + Uri.encode("#"))); //here you woud put your alternative code startActivity(intent);
您还需要在清单中声明此权限
<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>
可能你可以找到一个替代代码来做到这一点,因为我在互联网上看到了一些,但此时没有人为我工作.你可以尝试一下
备选方案2.等待官方API出现
在android project page at coogle code中,有一个添加USSD API支持的请求.它有很多订阅者,但它已经很老了(超过5年),我担心这不是很好.
无论如何,这可能发生,可能是android tem会考虑准备一个api所以一个应用程序可以声明一些权限,并提出某种代码的请求.但是,我知道,这可以永远等待.
那么,该说些什么.愿运气寻找解决方案,或替代您的应用程序.对不起,我的研究并不富有成效:(