Objetivo High Quality:
Para manejar la comunicación ussd, hay que tener presente que la interfaz depende del SO y del fabricante.
Agregar en tu archivo build.gradle
del proyecto Android:
repositories {
jcenter()
}
dependencies {
// java
implementation 'com.romellfudi.ussdlibrary:ussd-library:{latestVersion}'
// kotlin
implementation 'com.romellfudi.ussdlibrary:kotlin-ussd-library:{kotlinLatestVersion}'
}
En caso uses Kotlin, revisar mi otro proyecto (kotlin branch en archivado): Kotlin Void USSD
- Escribir el archivo xml acá to res/xml folder (if necessary), this config file allow link between App and SO:
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
.../>
Agregar las dependencias: CALL_PHONE, READ_PHONE_STATE and SYSTEM_ALERT_WINDOW:
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Agregar el servicio:
<service
android:name="com.romellfudi.ussdlibrary.USSDService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/ussd_service" />
</service>
Primero necesitamos mapear los mensajes de respuesta USSD, para idetificar los de logeo y de error
KEY MESSAGE | String Messages |
---|---|
KEY_LOGIN | "espere","waiting","loading","esperando",... |
KEY_ERROR | "problema","problem","error","null",... |
map = new HashMap<>();
map.put("KEY_LOGIN",new HashSet<>(Arrays.asList("espere", "waiting", "loading", "esperando")));
map.put("KEY_ERROR",new HashSet<>(Arrays.asList("problema", "problem", "error", "null")));
Instancia un objeto ussController con su activity
USSDApi ussdApi = USSDController.getInstance(activity);
ussdApi.callUSSDInvoke(phoneNumber, map, new USSDController.CallbackInvoke() {
@Override
public void responseInvoke(String message) {
// message has the response string data
String dataToSend = "data"// <- send "data" into USSD's input text
ussdApi.send(dataToSend,new USSDController.CallbackMessage(){
@Override
public void responseMessage(String message) {
// message has the response string data from USSD
}
});
}
@Override
public void over(String message) {
// message has the response string data from USSD
// response no have input text, NOT SEND ANY DATA
}
});
Si requiere un flujo de trabajo, tienes que usar la siguiente estructura:
ussdApi.callUSSDInvoke(phoneNumber, map, new USSDController.CallbackInvoke() {
@Override
public void responseInvoke(String message) {
// first option list - select option 1
ussdApi.send("1",new USSDController.CallbackMessage(){
@Override
public void responseMessage(String message) {
// second option list - select option 1
ussdApi.send("1",new USSDController.CallbackMessage(){
@Override
public void responseMessage(String message) {
...
}
});
}
});
}
@Override
public void over(String message) {
// message has the response string data from USSD
// response no have input text, NOT SEND ANY DATA
}
...
});
En caso de uso android >= M, necesitaras verificar los permisos, igualmente los métodos callUSSDInvoke
y callUSSDOverlayInvoke
también verifican que esten habilitados;
# check if accessibility permissions is enable
USSDController.verifyAccesibilityAccess(Activity)
# check if overlay permissions is enable
USSDController.verifyOverLay(Activity)
Soporte multi-sim card:
ussdApi.callUSSDInvoke(phoneNumber, simSlot, map, new USSDController.CallbackInvoke() {
...
}
Un severo problema al manejar este tipo de widget, este no puede ocultarse, redimencionarse, no puede ser puesto en el fondo con un rogressDialog
Pero recientemente a partir del Android O, Google permite la construcción build a nw kind permission dde widget sobrepuestos, mi solución implementada fue este widget llamdo OverlayShowingService
:
For use need add permissions at AndroidManifest:
<uses-permission android:name="android.permission.ACTION_MANAGE_OVERLAY_PERMISSION" />
La librería cuenta con dos componentes:
Agregar Broadcast Service:
<service android:name="com.romellfudi.ussdlibrary.SplashLoadingService"
android:exported="false" />
Invocar como cualquier servicio:
Intent svc = new Intent(activity, SplashLoadingService.class);
// show layout
getActivity().startService(svc);
ussdApi.callUSSDOverlayInvoke(phoneNumber, simSlot, map, new USSDController.CallbackInvoke() {
...
// dismiss layout
getActivity().stopService(svc);
...
}
En esta sección dejo las líneas requeridas para realizar la conexión VOIP-USSD
ussdPhoneNumber = ussdPhoneNumber.replace("#", uri);
Uri uriPhone = Uri.parse("tel:" + ussdPhoneNumber);
context.startActivity(new Intent(Intent.ACTION_CALL, uriPhone));
Una vez inicializado la llamada el servidor telcom comenzará a enviar las famosas pantallas ussd
Copyright 2018 Romell D.Z.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.