gpt4 book ai didi

android - 交互式 ussd session (多步)在 android 8(奥利奥)上不起作用

转载 作者:可可西里 更新时间:2023-11-01 18:48:04 27 4
gpt4 key购买 nike

我目前正在使用 android api 级别 26(Nexus 6P)中可用的电话管理器(USSD 响应)。对于单步 ussd session ,它正在运行。

引用: http://codedrago.com/q/140674/android-telephony-telephonymanager-ussd-android-8-0-oreo-does-android-8-0-api-26-support-sending-and-repying-to-ussd-messages

例子:

USSD 请求:“A”(ussd session 启动)

USSD 响应:“X”(ussd session 终止)

    TelephonyManager =  telephonyManager(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
Handler handler = new Handler();
TelephonyManager.UssdResponseCallback callback = new TelephonyManager.UssdResponseCallback() {
@Override
public void onReceiveUssdResponse(TelephonyManager telephonyManager, String request, CharSequence response) {
super.onReceiveUssdResponse(telephonyManager, request, response);
Log.e("ussd",response.toString());

}

@Override
public void onReceiveUssdResponseFailed(TelephonyManager telephonyManager, String request, int failureCode) {
super.onReceiveUssdResponseFailed(telephonyManager, request, failureCode);
Log.e("ussd","failed with code " + Integer.toString(failureCode));
}
};

try {
Log.e("ussd","trying to send ussd request");
telephonyManager.sendUssdRequest("*123#",
callback,
handler);
}catch (Exception e){


String msg= e.getMessage();
Log.e("DEBUG",e.toString());
e.printStackTrace();
}

但对于交互式 ussd 请求-响应(多步),它不起作用。 多步场景如下:

第 1 步。

USSD 请求:“A”(ussd session 启动)

USSD 回应:“X”

第 2 步。

USSD 请求:“B”(ussd session 继续)

USSD 响应:"is"

第 3 步。

USSD 请求:“C”

USSD 响应:“Z”(ussd session 终止)

最佳答案

我能够得到一个菜单,通过发送一个数字来响应它,但超过那个数字,我想我是在电信公司的摆布下 - 他们发送一个菜单来阻止整个屏幕,如果你取消它,整个 session 就会消失.在电信工作过后,我认为这可能因电信公司而异,因为他们中的一些拥有可以终止用户发起的 session 并将其替换为电信方发起的 session 的网关。从技术上讲,这两个 session 是分离的。但这是我的代码:

    package org.rootio.test.telephony.telephonyautorespond;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;
import android.telecom.TelecomManager;
import android.telephony.PhoneStateListener;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.Switch;
import android.widget.Toast;

import com.google.android.material.snackbar.Snackbar;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import androidx.annotation.RequiresApi;

import static android.content.ContentValues.TAG;

interface UssdResultNotifiable {
void notifyUssdResult(String request, String returnMessage, int resultCode);
}

public class HomeActivity extends Activity implements UssdResultNotifiable {

USSDSessionHandler hdl;
private TelephonyManager telephonyManager;
private PhoneCallListener listener;
private TelecomManager telecomManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
}

public void onUssdSend(View view) {
//USSDHandler callback = new USSDHandler(view);
/* if (checkSelfPermission(Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
*//*if(ActivityCompat.shouldShowRequestPermissionRationale(HomeActivity.this, Manifest.permission.CALL_PHONE))
{

}
else
{*//*
//ActivityCompat.requestPermissions(HomeActivity.this, new String[]{Manifest.permission.CALL_PHONE}, 0);
// }
Snackbar.make(view, "permissions were missing", Snackbar.LENGTH_LONG)
.setAction("Response", null).show();
return;
}*/
//HomeActivity.this.telephonyManager.sendUssdRequest("*#123*99#", callback, new Handler());



hdl = new USSDSessionHandler(HomeActivity.this, HomeActivity.this);

hdl.doSession(((EditText)this.findViewById(R.id.ussdText)).getText().toString());

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_home, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}

return super.onOptionsItemSelected(item);
}

public void toggleListener(View v) {
if (((Switch) v).isChecked()) {
this.listenForTelephony();
Toast.makeText(this, "Listening for calls", Toast.LENGTH_LONG).show();
} else {
this.stopListeningForTelephony();
}
}

private void listenForTelephony() {
this.telephonyManager = (TelephonyManager) this.getSystemService(this.TELEPHONY_SERVICE);
this.telecomManager = (TelecomManager) this.getSystemService(this.TELECOM_SERVICE);
this.listener = new PhoneCallListener();
telephonyManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
}

private void stopListeningForTelephony() {
this.telephonyManager = null;
this.telecomManager = null;
}

@Override
public void notifyUssdResult(final String request, final String returnMessage, final int resultCode) {
this.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(HomeActivity.this, "Request was " + request + "\n response is " + returnMessage + "\n result code is " + resultCode, Toast.LENGTH_LONG).show();

}
});

}


class PhoneCallListener extends PhoneStateListener {
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onCallStateChanged(int state, String incomingNumber) {

switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
HomeActivity.this.telecomManager.acceptRingingCall();
break;
case TelephonyManager.CALL_STATE_IDLE:
Toast.makeText(HomeActivity.this, "Call is no longer active...", Toast.LENGTH_LONG);
break;
}
}
}

@TargetApi(Build.VERSION_CODES.O)
class USSDHandler extends TelephonyManager.UssdResponseCallback {

View parent;

USSDHandler(View v) {
this.parent = v;
}

@Override
public void onReceiveUssdResponse(TelephonyManager telephonyManager, String request, CharSequence response) {
super.onReceiveUssdResponse(telephonyManager, request, response);
Snackbar.make(this.parent, response, Snackbar.LENGTH_LONG)
.setAction("Response", null).show();
}

@Override
public void onReceiveUssdResponseFailed(TelephonyManager telephonyManager, String request, int failureCode) {
super.onReceiveUssdResponseFailed(telephonyManager, request, failureCode);
Snackbar.make(this.parent, "error is " + failureCode + " for req " + request, Snackbar.LENGTH_LONG)
.setAction("Response", null).show();
}
}


}

class USSDSessionHandler {

TelephonyManager tm;
private UssdResultNotifiable client;
private Method handleUssdRequest;
private Object iTelephony;

USSDSessionHandler(Context parent, UssdResultNotifiable client) {
this.client = client;
this.tm = (TelephonyManager) parent.getSystemService(Context.TELEPHONY_SERVICE);
try {
this.getUssdRequestMethod();
} catch (Exception ex) {
//log
}

}

private void getUssdRequestMethod() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
if (tm != null) {
Class telephonyManagerClass = Class.forName(tm.getClass().getName());
if (telephonyManagerClass != null) {
Method getITelephony = telephonyManagerClass.getDeclaredMethod("getITelephony");
getITelephony.setAccessible(true);
this.iTelephony = getITelephony.invoke(tm); // Get the internal ITelephony object
Method[] methodList = iTelephony.getClass().getMethods();
this.handleUssdRequest = null;
/*
* Somehow, the method wouldn't come up if I simply used:
* iTelephony.getClass().getMethod('handleUssdRequest')
*/

for (Method _m : methodList)
if (_m.getName().equals("handleUssdRequest")) {
handleUssdRequest = _m;
break;
}
}
}
}

public void doSession(String ussdRequest) {
try {

if (handleUssdRequest != null) {
handleUssdRequest.setAccessible(true);
handleUssdRequest.invoke(iTelephony, SubscriptionManager.getDefaultSubscriptionId(), ussdRequest, new ResultReceiver(new Handler()) {

@Override
protected void onReceiveResult(int resultCode, Bundle ussdResponse) {
/*
* Usually you should the getParcelable() response to some Parcel
* child class but that's not possible here, since the "UssdResponse"
* class isn't in the SDK so we need to
* reflect again to get the result of getReturnMessage() and
* finally return that!
*/

Object p = ussdResponse.getParcelable("USSD_RESPONSE");

if (p != null) {

Method[] methodList = p.getClass().getMethods();
for(Method m : methodList)
{
Log.i(TAG, "onReceiveResult: " + m.getName());
}
try {
CharSequence returnMessage = (CharSequence) p.getClass().getMethod("getReturnMessage").invoke(p);
CharSequence request = (CharSequence) p.getClass().getMethod("getUssdRequest").invoke(p);
USSDSessionHandler.this.client.notifyUssdResult("" + request, "" + returnMessage, resultCode); //they could be null
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}

});
}
} catch (IllegalAccessException | InvocationTargetException e1) {
e1.printStackTrace();
}
}
}

请忽略电话接听功能 - 我之前使用此应用程序来测试 Oreo 的自动电话接听功能。下面是显示的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".HomeActivity">


<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="USSD Input"
android:textSize="18sp" />

<EditText
android:id="@+id/ussdText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="textPersonName" />
</LinearLayout>

<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="onUssdSend"
android:text="send" />
</LinearLayout>

关于android - 交互式 ussd session (多步)在 android 8(奥利奥)上不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46519929/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com