19 октября 2011 в 09:46

USSD в Android из песочницы

USSD (Unstructured Supplementary Service Data)— стандартный сервис в сетях GSM, позволяющий организовать интерактивное взаимодействие между абонентом сети и сервисным приложением в режиме передачи коротких сообщений.
Как известно, Android не имеет API для чтения USSD сообщений, далее я расскажу как решить эту проблему.

Как то столкнулся с задачей отослать команду и принять USSD сообщение. Оказывается USSD ответ сохраняется в буфере BufferedReader и существует сторонний класс USSD, для парсинга информации из этого буфера.

Сам класс можно скопировать тут

Теперь рассмотрим саму реализацию использования класса:
Для начала создадим интерфейс приложения, у нас будет AutoCompleteTextView, TextView, Button:

<!--?xml version="1.0" encoding="utf-8"?-->
<linearlayout xmlns:android="schemas.android.com/apk/res/android" 
   android:orientation="vertical" 
   android:layout_width="fill_parent" 
   android:layout_height="fill_parent">
<autocompletetextview 
       android:layout_width="fill_parent" 
       android:text="" 
       android:layout_height="wrap_content" 
       android:inputtype="phone|textUri"
       android:id="@+id/Text1">
<requestfocus></requestfocus>
</autocompletetextview>
<textview 
       android:layout_width="fill_parent" 
       android:id="@+id/Text2" 
       android:layout_height="wrap_content">
</textview>
<button 
       android:text="@string/send"
       android:id="@+id/button1" 
       android:layout_width="fill_parent" 
       android:layout_height="wrap_content">
</button>
</linearlayout>


Вот такой интерфейс у нас должен получиться:

image

Теперь предадим жизни приложению, напишем сам код получения результата USSD.

// не пишу все импорты, напишу только то, что не забудьте подключить класс USSD
import com.example.android.UssdMessage.USSD;
 
public class UssdmessageActivity extends Activity implements OnClickListener {
/** Called when the activity is first created. */
private TextView view;
private AutoCompleteTextView number;
 
Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(this);
this.view = (TextView) findViewById(R.id.Text2);
this.number = (AutoCompleteTextView) findViewById(R.id.Text1);
}
 
Override
public void onClick(View arg0) {
String encodedHash = Uri.encode(«#»);
call(«*» + number.getText() + encodedHash);
this.view.setText(«»);
}
 
protected void call(String phoneNumber) {
try {
startActivityForResult(
new Intent(«android.intent.action.CALL», Uri.parse(«tel:»
+ phoneNumber))1);
} catch (Exception eExcept) {
this.view.append(«nn » + «n« + eExcept.toString());
}
}
 
Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
USSD ussd = new USSD(4000,4000); // передается два параметра, задержка до и после (ms) создания сообщения
if (ussd.IsFound())
this.view.append(«n«+ussd.getMsg());
else
this.view.append(«»+R.string.error_ussd_msg);
}
 
}


Так же не забудьте добавить следующие разрешения (иначе не заработает):

<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>
<uses-permission android:name="android.permission.CALL_PRIVILEGED"></uses-permission>
<uses-permission android:name="android.permission.READ_LOGS"></uses-permission>


Скриншот работы приложения:

image

Добавлю то, что класс написан так, что выводит в logcat отладочную информацию.
На мой взгляд не сложный и удобный класс, который может помочь в решении Ваших задач.
Спасибо за внимание.

.apk файл Скачать
исходники Скачать
+53
15945
108
KREGI 14,5

Комментарии (42)

+6
SabMakc, #
Отправка / прием происходят полностью в фоне или на экране все равно отображается отправка и принимаемое сообщение?
+1
KREGI, #
Все равно появляется сообщение «Выполняется запрос USSD», и ответ тоже появляется в окне. Возможно можно перехватить или подавить, не вникал.
0
skive, #
Чтобы подавить, нужны root права у приложения.
0
b3er, #
Чтобы подавить окно ответа, оставив окно выполнения запроса, рут не нужен. Правда, работать будет далеко не на всех девайсах, впрочем, как и способ, описанный в данной статье.
Для полного подавления, действительно, нужен рут, и весьма нетривиальная организация перехвата сообщений от ril. Реализовано, например, в Prepay Widget.
0
antivir, #
Данная статья с большой бородой. Я видел ее в песочнице еще в начале сентября. Сейчас каким-то образом опять туда попала.
+5
KREGI, #
я эту статьи и писал… еще в те бородатые сентябрьские дни…
+3
antivir, #
Тогда с почином вас! :)
+1
KREGI, #
Спасибо :)
+1
KREGI, #
Спасибо :)
0
acmer, #
Да, и подключите это ваше «Горячее ТВ для взрослых в телефоне» ((=
0
KREGI, #
не интересует ))
0
AstaRoth, #
А эту ajc.su/mobilnye-os/android-mobilnye-os/ussd-v-android/ статью тоже Вы писали?
+2
KREGI, #
вы же знаете что такое интернет, видимо из песочницы её скопипастили на другой ресурс…
смотрите, строка
«Сам класс можно скачать тут»
если перейти по ссылке, то посмотрите кем размещен код класса :)
в той статье даже опечатки мои сохранены xD
«На ой взгляд не сложный»
+3
KREGI, #
если надо, могу приложить apk и исходники?
+1
AstaRoth, #
Спасибо! Я всего лишь спросил.
На том ресурсе статься точь-в-точь такая же от 5ого сентября, авторства не указано. Спасибо еще раз, что прояснили ситуацию.
А по поводу минусов: спасибо и за это, странное место хабр, я считаю -если есть какие-то вопросы: не нужно стесняться из задавать. Я никого ни в чем не обвинял, просто привел линк. Я думаю, что не зря, теперь автор может обратиться к админам ajc.su на предмет воровства чужой статьи.
0
antivir, #
Я думаю, минус был за то, что ваша ссылка пойдет тому сайту в плюс.
0
AstaRoth, #
Не пойдет она тому сайту в плюсы, а как раз все выведет на чистую воду. См.коммент автора ниже.
Предыстория: к примеру, даю я линк на эту статью людям, а мне вопрос: «мы где-то видели подобную» и линк дали уже на другой сайт.
Я к тому, что многие на хабре боятся лишнее слово сказать. А вдруг минуснут? А друг еще чего. А потому и гуляют по инету всякие левые ссылки…
0
KREGI, #
Написать то им хочется, но что то пока не нашел я куда там писать…
Спасибо за линк.
p.s. там не только мой пост, но и еще с хабра куча…
+1
antivir, #
Все нормально, вот она с указанием источника
habr-sandbox.livejournal.com/379031.html
0
zizop, #
Я может быть пропустил, а где само приложение можно скачать?
+1
KREGI, #
сейчас выложу apk и исходники
0
Damaskus, #
В эта бага висит 3 года уже.
Гугл, похоже, не особо заботят подобные вещи, поэтому появляются такие велосипеды.
0
KREGI, #
видимо они не видят в этом приоритетную задачу…
0
Damaskus, #
Прикрутите регулярочку, чтобы вывод был без рекламы. :-)
0
KREGI, #
Реклама? Вы ко мне обращаетесь?
0
Damaskus, #
"… ТВ взрослых в телефоне..."
0
KREGI, #
Задача была вывести USSD, можно и регулярку, что бы баланс был, тут уж насколько фантазии хватит.
Это ответ мегафона на запрос баланса.
+1
KREGI, #
Обновил пост, забыл про разрешения, обратите внимание — это важно.
+1
KREGI, #
и добавил ссылки на скачку файлов: .apk и исходники
0
stn, #
Я ме разбираюсь в этих технических деталях, но у меня разрыв шаблона. Есть Андроид таблетка, в ней стоит симка. EDGE, SMS великолепно работают. Не понимаю почему проблема с USSD? Я тупо не могу посмотреть баланс средств на моей симке. Что же мне ее теперь каждый раз вынимать и встaвлять в другой аппарат?

Установил вашу программу. Запускается, но в ответ на любой USSD номер на экране высвечиавется какое-то число. Galaxy Tab 10.1
0
KREGI, #
была похожая проблема на каком то другом устройстве, однако на моем acer s120 повторить не удалось…
0
stn, #
В чем принципиальная суть проблемы? Я понимаю, когда в таблетках отключают голосовые функции. Но почему вместе с ними пропадает и USSD? Я сначала думал, что проблема в отсутствии штатной номеронабиралки, но никакие сторонние приложения не помогли. Вроде бы USSD напрямую никак не свазан с голосом.
0
GooRoo, #
Когда же на моём Motorola Droid 2 Global заработают USSD?! :( Ваша статья как соль на рану.
0
KREGI, #
в некоторых случаях USSD можно заменить на отправку бесплатного SMS, так сейчас и делают программы по работе с балансом например.
0
GooRoo, #
Я облазил весь сайт МТС Украина, но не нашёл, как проверить баланс sms-кой. В поддержку было влом писать.
0
alan85, #
жалко на моем I5500 не работает… Хотя USSD Checker работает без сбоев.
0
KREGI, #
номер следует вводить без * и # как на скриншоте последнем
0
alan85, #
я понимаю, что без * и # — ответ на запрос высвечивается, но ussd.IsFound() дает false.
0
KREGI, #
это как? если ussd.IsFound() false то будет ошибка с сообщением типа не чего не найдено.
if (ussd.IsFound())
    this.view.append("\n"+ussd.getMsg()); // полученное ussd сообщение
else
    this.view.append(""+R.string.error_ussd_msg); //сообщение об ошибке

попробуйте убрать аргументы
USSD ussd = new USSD(); // по умолчанию 3000,3000
0
alan85, #
я немного видоизменил концовку — поэтому ничего. А так вечером попробую разобраться.
0
kataloo, #
Да, цифры как раз — это и есть сообщение об ошибке.
0
alan85, #
В LogCat ничего не сыпется просто…
Насколько я понял из дискуссии code.google.com/p/android/issues/detail?id=1285#c121 этот способ будет работать только при компиляции с режимом дебагинга. Нашел еще вот это commandus.com/blog/?p=58, но еще не побывал. Так как программист из меня мало мальский я предлагаю попробовать Вам.

Только зарегистрированные пользователи могут оставлять комментарии.
Войдите, пожалуйста.