Une application Qt android qui envoie des SMS.


Application Qt android

La première solution qui s'offre à nous pour écrire des applications mobiles sous android est bien entendu de les développer en java en utilisant l'API native (JNI Java Native Interface). C'est sans équivoque selon moi la meilleure solution, car le web foisonne de forums, d'aides et d'exemples sur le sujet.

En revanche, si comme moi vous ne comptez développer des applications mobile qu’occasionnellement et que vous maîtrisez le c++, la bibliothèque Qt commence à offrir un large spectre de fonctionnalités utilisables très simplement sous android, et IOS, telles que les IHM, l'accés au réseau local et à l'internet, la gestion du bluetooth, l’accès aux capteurs, .etc.

Pour le lecteur qui n'a pas encore fait ses premiers pas sous Qt android, un tutoriel en français est disponible ici. Je vous conseille d'y aller, je n'aurai pas pu faire mieux!

Malheureusement, à l'heure où j'écris ce post toutes les fonctionnalités de l'API android ne sont pas implémentées sous Qt (version 5.4). En revanche, les développeurs ont prévu une classe permettant d’appeler directement l'API en c++, la classe QAndroidJniObject. Bien que je ne la trouve personnellement pas très pratique à utiliser, c'est quand même une alternative intéressante pour avoir accès à la totalité de l'API java android dans une application Qt.

Appel du SmsManager de l'API java

Dans le domaine industriel, et surtout avec les taux de couverture actuels du réseau GSM, l'envoi de SMS peut être une solution pour échanger des données avec une station déportée. Aujourd'hui, des interfaces GSM à prix abordable sont disponibles, et peuvent facilement être connectées à une carte, Arduino ou Raspberry par exemple, pour réaliser ce type de station (station météo, domotique, surveillance/sécurité, process industriels .etc.).

La solution qui consiste à être averti et à contrôler une ou plusieurs stations à partir de notre smartphone, en échangeant des SMS, devient alors très séduisante et ouvre des perspectives immenses. Pour cela, il faut bien entendu que notre application android soit capable d'envoyer et de recevoir ces SMS, ce qui fait partie de ces fameuses fonctionnalités non encore implémentées.

Ce petit tuto montre comment envoyer des SMS en accédant directement à l'API java android (JNI).

Comme d'habitude, vous devez commencer par créer un projet d'application graphique Qt basé sur un QWidget, sous android.

Dans le fichier de projet (.pro), il faut rajouter ensuite le module androidextras

QT       += androidextras

puis, dans le fichier d'entête de la classe principale, les inclusions:

#include <QtAndroid>
#include <QAndroidJniObject>

Dans l'API java, une des solutions disponibles pour l'envoi de SMS est la mise en oeuvre de la classe java SmsManager - il en existe d'autre utilisant le concept d'Intent/Listener.

Vous trouverez un exemple java d'envoi de SMS avec SMSManager, et je vous engage également à consulter la documentation complète de la classe SMSManager pour bien comprendre la suite.

Pour envoyer un SMS, il faut maintenant:

récupérer la référence sur l'activité principale de notre application:

// get the Qt android activity
QAndroidJniObject activity =  QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative",
                                                                        "activity",
                                                                        "()Landroid/app/Activity;");

puis, si cette dernière est active, récupérer la référence du SmsManager par défaut:

if (activity.isValid()){
    // get the default SmsManager
    QAndroidJniObject mySmsManager = QAndroidJniObject::callStaticObjectMethod("android/telephony/SmsManager",
                                                                               "getDefault",
                                                                               "()Landroid/telephony/SmsManager;" );

la classe SmsManager de l'API JAVA possède une méthode sendTextMessage ayant le prototype suivant:

public void SmsManager.sendTextMessage(String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)

C'est cette dernière que nous allons appeler en c++ via la méthode QAndroidJniObject::callMethod. Il faut donc préparer les arguments destinationAddress le numéro du destinataire, scAddress notre numéro, et text le texte du SMS. Dans mon exemple, ces informations sont récupérées sur l'interface, dans des QLineEdit

// get phone number & text from UI and convert to Java String
QAndroidJniObject myPhoneNumber = QAndroidJniObject::fromString(ui->lineEditDestinataire->text());
QAndroidJniObject myTextMessage = QAndroidJniObject::fromString(ui->lineEditTexte->text());
QAndroidJniObject scAddress = NULL;
QAndroidJniObject sentIntent = NULL;
QAndroidJniObject deliveryIntent = NULL;

il ne reste plus qu'à appeler la méthode sendTextMessage de l'objet mySmsManager en y passant les bons arguments, soit:

  • la chaîne "sendTextMessage" qui représente le nom de la méthode,
  • la chaîne "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/app/PendingIntent;)V" le prototype de cette méthode, pour rappel void SmsManager.sendTextMessage(String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent).
  • les chaînes java myPhoneNumber.object(), scAddress.object() et myTextMessage.object() les numéros et le texte du SMS
  • les deux derniers arguments pendingIntent et deliveryIntent sont mis à NULL - voir la documentation pour plus de détails.
mySmsManager.callMethod<void>("sendTextMessage",
                              "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/app/PendingIntent;)V",
                              myPhoneNumber.object<jstring>(),
                              scAddress.object<jstring>(),
                              myTextMessage.object<jstring>(), NULL, NULL );

Voilà, il faut également penser à autoriser l'application à envoyer des SMS dans son manifest.xml en y rajoutant la ligne:

android.permission.SEND_SMS

dans QtCreator, cela se fait dans les paramètres du projet (icône sur la barre de gauche) puis Build Android APK, bouton Create Templates et enfin permissions. Rajouter android.permission.SEND_SMS.

Vous pouvez télécharger mon projet complet. Pensez à reprendre le manifest comme ci-dessus.

Enjoy !