Android12 Res Materiel Bluetooth -...
Transcript of Android12 Res Materiel Bluetooth -...
PROGRAMMATION ANDROID
Ahcène Bounceur Université de Bretagne Occidentale
1
Les Ressources Matérielles 2
Chapitre 12
Les Ressources Matérielles permettent de créer des
applications toujours plus immersives, communicantes et
interactives !
3
PLAN DU COURS
1. Les Capteurs 2. Le Bluetooth 3. La Caméra
4
LISTES DE RESSOURCES PRINCIPALES
¢ Affichage : � Appareil photo � 3D
¢ Entrées : � Clavier � Tactile � Boule de commande (trackball)
¢ Son : � Haut parleur / microphone � Reconnaissance vocale � Vibration
5
¢ Réseau : � 3G � Wi-Fi � Bluetooth � GPS
¢ Capteurs : � Accéléromètre � Orientation � Champs magnétiques � Température
Les Capteurs 6
LES CAPTEURS
¢ Une bonne partie du succès des terminaux modernes (comme les appareils Android, l'iPhone ou la console Wii) est la gestion du mouvement.
¢ Cela ne serait pas possible sans l'extraordinaire démocratisation des capteurs embarqués.
¢ Désormais, votre appareil : � détecte le mouvement � peut se situer dans l'espace
7
IDENTIFICATION DES CAPTEURS
¢ Le panel des capteurs s'est étoffé avec les versions successives d'Android : � accéléromètre, � capteur de pression, � capteur de proximité, � Etc.
¢ En revanche, les terminaux ne sont pas tous équipés de tous les capteurs.
8
IDENTIFICATION DES CAPTEURS
¢ L'API d'Android 1.6 a introduit un nouvel objet sensor responsable de la récupération des données,
¢ sous la houlette du SensorManager qui comme son nom l'indique chapeaute le groupe de capteurs au travers d'un service commun à tout le système.
9
UTILISATION DES CAPTEURS
¢ Pour accéder à un capteur, il faut : � 1. Récupérer une instance du service pour déclarer un
gestionnaire des capteurs : SensorManager manager = (SensorManager) getSystemService(SENSOR_SERVICE);
10
Ser
vice
UTILISATION DES CAPTEURS
¢ Représentation schématique des capteurs :
11
App
licat
ion
Capteur • Accéléromètre
Capteur • Orientation
Capteur • Température
SensorManager
UTILISATION DES CAPTEURS
¢ Pour accéder à un capteur, il faut : � 2. Déclarer et instancier le type du capteur à utiliser
(exemple : l'accéléromètre) : Sensor accel = manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
12
RÉCUPÉRATION DES DONNÉES
¢ Pour obtenir les données (valeurs) du capteurs, il faut s'enregistrer auprès du service comme écouteur d'événement grâce à la méthode registerListener.
¢ Après utilisation de ces données ou avant de quitter
l'application, il est indispensable de se dés-enregistrer en utilisant la méthode opposée unregisterListener.
13
UTILISATION DES CAPTEURS
¢ Pour accéder aux capteurs, il faut : � 3. S’enregistrer aux événements du capteur : boolean accelSupported = manager.registerListener(this, accel, SensorManager.SENSOR_DELAY_UI);
14
Taux de rafraîchissement des données
Doit implémenter SensorEventListener Il est conseillé de mettre cette instruction dans la méthode onResume d’une activité
TAUX DE RAFRAÎCHISSEMENT DES DONNÉES
¢ Plus le taux est élevé, plus les données sont rafraîchies et précises, et plus la consommation d'énergie est élevée. � SENSOR_DELAY_FASTEST : le taux de
rafraîchissement le plus élevé. � SENSOR_DELAY_GAME : taux utilisable pour des
applications nécessitant des données précises telles que les jeux.
� SENSOR_DELAY_NORMAL : taux normal utilisé par exemple par le système pour détecter les changements d'orientation.
� SENSOR_DELAY_UI : le taux le plus bas utilisé dans les applications ne nécessitant qu'une faible précision ou ne sollicitant que très peu de données, comme les composants graphiques d'une interface utilisateur.
15
DÉS-ENREGISTREMENT DE L'ÉCOUTEUR
Sensor accel = manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
...
// enregistrement ...
...
if (accelSupported)
manager.unregisterListener( this, accel );
16
Doit implémenter SensorEventListener Il est conseillé de mettre cette instruction dans la méthode onPause d’une activité
IMPLÉMENTATION DE L'ÉCOUTEUR
¢ L'écouteur : SensorEventListener ¢ La notification se fera via deux méthodes :
� onSensorChanged(SensorEvent event)¢ se déclanche si l'appareil récupère de l'inforamtion (en
mouvement pour le cas de l'accéléromètre)
� onAccuracyChanged(Sensor sensor, int accuracy)¢ se déclanche si la précision est changée
17
IMPLÉMENTATION DE L'ÉCOUTEUR
¢ onSensorChanged(SensorEvent event)
event.sensor.getType() =� Sensor.TYPE_ACCELEROMETER� Sensor.TYPE_MAGNETIC_FIELD� Sensor.TYPE_AMBIENT_TEMPERATURE� Sensor.TYPE_PROXIMITY� Sensor.TYPE_LIGHT� Sensor.TYPE_PRESSURE� Sensor.TYPE_GYROSCOPE
18
IMPLÉMENTATION DE L'ÉCOUTEUR
¢ onAccuracyChanged(Sensor sensor, int accuracy)
accuracy =� SensorManager.SENSOR_STATUS_ACCURACY_HIGH� SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM� SensorManager.SENSOR_STATUS_ACCURACY_LOW� SensorManager.SENSOR_STATUS_UNRELIABLE
19
IMPLÉMENTATION DE L'ÉCOUTEUR
¢ onAccuracyChanged(Sensor sensor, int accuracy)
sensor.getType() =� Sensor.TYPE_ACCELEROMETER� Sensor.TYPE_MAGNETIC_FIELD� Sensor.TYPE_AMBIENT_TEMPERATURE� Sensor.TYPE_PROXIMITY� Sensor.TYPE_LIGHT� Sensor.TYPE_PRESSURE� Sensor.TYPE_GYROSCOPE
20
RÉCEPTION DES DONNÉES
¢ Cas d'un Accéléromètre :
21
y x
z
y
x
z
RÉCEPTION DES DONNÉES
¢ Cas d'un Accéléromètre : public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType() = Sensor.TYPE_ACCELEROMETER) {
float x, y, z;
x = event.values[0];
y = event.values[1];
z = event.values[2];
}
}
22
RÉCEPTION DES DONNÉES
¢ Cas d'un Capteur de champ magnétique : public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType() = Sensor.TYPE_MAGNETIC_FIELD) {
float uTx,uTy,uTz;
uTx = event.values[0];
uTy = event.values[1];
uTz = event.values[2];
}
}
23
RÉCEPTION DES DONNÉES
¢ Cas d'un Capteur de température : public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType() = Sensor.TYPE_AMBIENT_TEMPERATURE) {
float temperature ;
temperature = event.values[0] ;
}
}
24
RÉCEPTION DES DONNÉES
¢ Cas d'un Capteur de proximité : public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType() = Sensor.TYPE_PROXIMITY) {
float distance;
distance = event.values[0];
}
}
25
RÉCEPTION DES DONNÉES
¢ Cas d'un Capteur de lumière : public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType() = Sensor.TYPE_LIGHT) {
float illuminance;
illuminance = event.values[0];
}
}
26
RÉCEPTION DES DONNÉES
¢ Cas d'un Capteur de pression : public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType() = Sensor.TYPE_PRESSURE) {
float pressure;
pressure = event.values[0];
}
}
27
RÉCEPTION DES DONNÉES
¢ Cas d'un Gyroscope : public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType() = Sensor.TYPE_GYROSCOPE) {
float x, y, z;
x = event.values[0];
y = event.values[1];
z = event.values[2];
}
}
28
RÉCEPTION DES DONNÉES
29
public class MainActivity extends AppCompatActivity implements SensorEventListener { private SensorManager manager; private Sensor accel; private Sensor temperature; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); manager = (SensorManager) getSystemService(SENSOR_SERVICE); accel = manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) ; temperature = manager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE) ; } @Override public void onSensorChanged(SensorEvent sensorEvent) { if(event.sensor.getType() == Sensor.TYPE_AMBIENT_TEMPERATURE) { float t = event.values[0]; Log.i("TAG", "TEMP : " + t); }
if(event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { float x = event.values[0]; float y = event.values[1]; float z = event.values[2]; Log.i("TAG", "ACCEL : " + x + " " + y + " " + z); } }}
¢ Exemple :
REMARQUE SUR L'ÉMULATEUR
¢ Il se peut que l'émulateur d'Android ne permet pas d'obtenir les données de certains capteurs virtuels : � Dans ce cas là, il est donc nécessaire de travailler
sur un vrai terminal.
30
CONSEILS
¢ L'utilisation des capteurs consomme beaucoup d'énergie et réduit l'autonomie de l'appareil. Il est donc conseillé dans vos applications d'informer l'utilisateur si le niveau de batterie est faible.
¢ Testez dans votre application la disponibilité et l'état de marche des capteurs et informez l'utilisateur sur l'existence ou non du capteur utilisé par cette application.
¢ Vos applications doivent être préparées à tous les cas de figures !
31
Le Vibreur
Attention : Le vibreur est une ressource matérielle, Mais, Le vibreur n'est pas un capteur, il est utilisé comme
un service de l'appareil. C'est comme l'utilisation d'un appel téléphonique ou d'un appel à une autre application de l'appareil.
32
Le Vibreur
¢ Ajouter la permission android.permission.VIBRATE :
<uses-permission android:name="android.permission.VIBRATE"/>
¢ Déclaration de la variable vibrator :
Vibrator vibrator;
¢ Instanciation de la variable vibrator : vibrator =
(Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
33
Le Vibreur
¢ Lancer la vibration : � Méthode 1 (vibration classique) :
vibrator.vibrate(a);
� Méthode 2 (vibration programmée) : vibrator.vibrate(new long[]{a1, b1, a2, b2, ..., ai, bi}, c);
¢ a : la durée de la vibration en millisecondes, ¢ ai : la durée de la ième pause, ¢ bi, la durée de la ième vibration, ¢ c : nombre de répétitions (c = –1 : pas de répétitions)
34
Le Bluetooth 35
Créé en 1998 par le fabricant suédois Ericsson
LE BLUETOOTH
¢ Le Bluetooth est une technologie de communication radio de courte distance (WPAN : Réseau personnel sans fil), créée pour simplifier les connexions entre appareils.
¢ Ce système a été conçu dans le but de remplacer les câbles des imprimantes, des kits "main libre", des souris/claviers, téléphones portables/PDA, etc.
¢ La plate-forme Android supporte le Bluetooth afin de permettre à des appareils d'échanger des données entre elles.
¢ Pour pouvoir profiter de ce système de connexion, Android a mis en place un ensemble d'APIs.
36
LEBLUETOOTH
L'API ANDROID.BLUETOOTH
¢ BluetoothAdapter : � il s'agit de la classe centrale pour les interactions avec
le Bluetooth, elle est utilisée pour récupérer les appareils environnants, effectuer toutes les requêtes et communiquer avec les autres appareils ;
¢ BluetoothDevice : � représente un appareil Bluetooth distant, et est utilisé
pour récupérer les informations sur l'appareil et créer une connexion ;
¢ BluetoothSocket et BluetoothServerSocket : � représentent les points de connexion permettant aux
appareils d'échanger des données entre eux.
38
LES PERMISSIONS
39
¢ Pour qu'une application puisse utiliser les capacités Bluetooth, vous devez avoir défini les permissions : � android.permission.BLUETOOTH
¢ Pour autoriser votre application à accepter une connexion entrante, à demander une connexion distante et à transférer des données.
<manifest ... >
...
<uses-permission android:name="android.permission.BLUETOOTH" />
...
</manifest>
LES PERMISSIONS
40
� android.permission.BLUETOOTH_ADMIN ¢ Pour pouvoir activer la recherche des autres appareils Bluetooth ou
pour manipuler les paramètres Bluetooth du téléphone.
<manifest ... >
...
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
...
</manifest>
DÉCLARER UN OBJET BLUETOOTH
¢ La classe permettant d’utiliser le Bluetooth est :
BluetoothAdapter
¢ Déclaration :
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
41
VÉRIFIER L'EXISTENCE DU BLUETOOTH
42
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null) {
// Le bluetooth est supporté
}
else {
// Le bluetooth n'est pas supporté
}
Vérifier si le BLUETOOTH est activé
43
adapter.isEnabled() Permet de savoir si le bluetooth est activé ou pas
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null) {
if (!adapter.isEnabled()) {
// Le bluetooth n’est pas activé
}
else {
// Le bluetooth est activé
}
}
else {
// Le bluetooth n'est pas supporté
}
Activer le BLUETOOTH
44
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null) {
if (!adapter.isEnabled()) {
Intent intent =
new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1);
}
else {
// Le bluetooth est activé
}
}
else {
// Le bluetooth n'est pas supporté
}
Le téléphone informe l’utilisateur si le Bluetooth n’est pas déjà activé
Activer le BLUETOOTH
¢ En fonction de la réponse de l'utilisateur, le Bluetooth sera activé ou non.
¢ En fonction de la réponse, la méthode startActivityForResult
permet de renvoyer RESULT_OK ou RESULT_CANCELED à travers la méthode onActivityResult : argument resultCode.
45
@Override public void onActivityResult(int req, int resultCode, Intent i) { String s = (resultCode==RESULT_OK )?"ACTIVE":"ANNULE"; Log.i("LSE", "Bluetooth réponse : "+s); }
ADRESSE MAC
¢ En réseau informatique, une adresse MAC (Media Access Control) est un identifiant physique stocké dans une carte réseau, attribué de façon unique à chaque carte à l'échelle mondiale : cet identifiant est en partie constitué par un champs identifiant le fabricant de la carte et l'autre partie attribuée par le constructeur lui-même.
46
83:C0:24:65:B7:FA 17 caractères
Protocole RFCOMM
¢ Le protocole RFCOMM émule les paramètres de la ligne série câblée ainsi que le statut d'un port série RS-232. Il est utilisé pour permettre le transfert des données série.
¢ Ce protocole est notamment utilisé par les modems, les imprimantes et les ordinateurs.
¢ Le Bluetooth utilise ce protocole pour échanger des données.
47
RECHERCHER D'AUTRES APPAREILS
¢ Pour qu'un appareil puisse être découvert, il faut que celui-ci autorise sa découverte.
¢ Si un appareil autorise sa découverte, une association sera alors établie.
¢ Une association signifie que les deux appareils sont conscients de leur existence respective, qu'ils sont capables de s'authentifier l'un l'autre et d'initier une connexion sécurisée entre eux.
¢ Une fois l'association établie avec un appareil distant, il est possible de se connecter à celui-ci en utilisant son adresse MAC pour transférer des données via un flux RFCOMM.
48
RENDRE SON APPAREIL DÉCOUVRABLE
49
¢ Si vous souhaitez rendre accessible l'appareil de l'utilisateur lors d'une recherche d'appareils Bluetooth, vous devez demander l'autorisation à l'utilisateur.
¢ Cette opération est limitée en durée. Cette dernière est spécifiée comme paramètre (en secondes) :
Intent intent =
new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 120);
startActivity(intent);
RÉCUPÉRER LES APPAREILS ASSOCIÉS
50
¢ Au lieu de lancer immédiatement une nouvelle recherche d'appareils Bluetooth, il convient dans un premier temps de rechercher si l'appareil de l'utilisateur ne connaît pas déjà l'appareil ciblé (n’est pas déjà associé).
¢ Pour cela, on utilise la méthode getBondedDevices qui permet d'effectuer une requête sur les appareils déjà connus (associés).
Set<BluetoothDevice> appareils = adapter.getBondedDevices();
if (appareils.size() > 0) {
for (BluetoothDevice appareil : appareils) { String n = appareil.getName(); // nomString a = appareil.getAddress(); // adresse mac
BluetoothClass b = appareil.getBluetoothClass(); // classeParcelUuid [] uuids = appareil.getUuids(); // uuids
}}
RECHERCHER LES APPAREILS ENVIRONNANT
¢ Pour récupérer la liste des appareils non associés ¢ On lance une découverte d’appareil en utilisant la méthode startDiscovery de la classe BluetoothAdapter.
¢ Cette méthode retourne immédiatement une valeur
booléenne indiquant si la découverte s'est correctement lancée.
51
RECHERCHER LES APPAREILS ENVIRONNANT
BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(BluetoothDevice.ACTION_FOUND))
BluetoothDevice appareil =
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
}
};
IntentFilter filtre = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(receiver, filtre);
52
Nécessite un récepteur (BroadcastReceiver) sur BluetoothDevice.ACTION_FOUND
RECHERCHER LES APPAREILS ENVIRONNANT
53
¢ Lancer le scan : adapter.startDiscovery();
¢ Il ne faut surtout pas oublier : � D'arrêter la découverte des nouveaux devices � De désabonner notre broadcast receiver � En redéfinissant la méthode onDestroy de l'activité
@Override
protected void onDestroy() {
adapter.cancelDiscovery();
unregisterReceiver(receiver);
super.onDestroy();
}
COMMUNICATION ENTRE APPAREILS BLUETOOTH
¢ Pour établir une connexion entre deux appareils, vous devez implémenter chaque côté de votre logique de communication : le côté serveur et le côté client.
¢ Qu'il s'agisse du client ou du serveur, l'objet
BluetoothSocket sera récupéré de façon différente: � Pour le serveur : il lui sera renvoyé lorsqu'il aura accepté la
demande de connexion. � Pour le client : il l'obtiendra après acceptation de la demande par
le serveur et l'établissement du flux RFCOMM. ¢ En général une application pourra se comporter aussi bien
en tant que serveur que client. 54
UUID
¢ Un identifiant UUID est un identifiant universel unique (Universally Unique IDentifier) représenté par une chaine de 128 bits qui identifie l'information de façon unique. L'intérêt de l'UUID est qu'il est suffisamment grand pour que vous puissiez en générer un aléatoirement et avoir peu de chance d'entrer en collision avec le même identifiant.
¢ En java, la classe UUID fait partie du package : java.util.UUID;
UUID uuid = UUID.fromString(String str)
Cette méthode static permet de récupérer un objet UUID à partir d'une chaine de caractère str.
55
UUID
¢ Récupérer l’UUID d’un appareil associé : BluetoothDevice appareil ;
appareil = adapter.getRemoteDevice("20:...");
56
UUID
¢ Récupérer l’UUID d’un appareil associé : BluetoothDevice appareil ;
Set<BluetoothDevice> appareils = adapter.getBondedDevices();
for (BluetoothDevice c_appareil : appareils) {
if(c_appareil.getAddress().equals("20:...")) {
appareil = c_appareil;
}
}
57
UUID
¢ Récupérer l’UUID d’un appareil associé : ParcelUuid [] p_uuids = appareil.getUuids();
ParcelUuid p_uuid = p_uuids[i];
UUID uuid = p_uuid.getUuid();
58
UUID
¢ Exemples :
00001101-0000-1000-8000-00805f9b34fb
0000110a-0000-1000-8000-00805f9b34fb
00001105-0000-1000-8000-00805f9b34fb
00001106-0000-1000-8000-00805f9b34fb
00001117-0000-1000-8000-00805f9b34fb
00001112-0000-1000-8000-00805f9b34fb
0000111f-0000-1000-8000-00805f9b34fb
00000000-0000-1000-8000-00805f9b34fb
00000000-0000-1000-8000-00805f9b34fb
59
Bluetooth 2
uuids
CRÉATION D'UN SERVEUR
¢ Pour créer un serveur et accepter la connexion de l'appareil distant (1) : � Obtenez un objet BluetoothServerSocket en appelant la
méthode listenUsingRfcommWithServiceRecord(String, UUID)
¢ String : une chaîne représentant le nom du service. ¢ UUID : un identifiant unique qui identifie sans ambiguïté le
service.
¢ Lors de la demande de connexion, le client enverra également un identifiant unique qui devra être le même que celui spécifié ici pour que la connexion s'établisse.
60
CRÉATION D'UN SERVEUR
¢ Pour créer un serveur et accepter la connexion de l'appareil distant (2) : � Débutez l'écoute des demandes de connexions en appelant la
méthode accept() ¢ Cette méthode ne retourne pas immédiatement et bloque
l'exécution de votre application. ¢ La méthode retournera un objet BluetoothSocket dès qu'une
demande de connexion sera acceptée avec un UUID correct.
¢ Vous pouvez annuler l'écoute des demandes de connexions en appelant la méthode close() du BluetoothServerSocket. Dans tous les cas, appelez cette méthode pour libérer les ressources dès que vous n'aurez plus besoin de cet objet.
61
CRÉATION D'UN Serveur
62
BluetoothServerSocket socketServeur = adaptateur.listenUsingRfcommWithServiceRecord("MonServi
ce", uuid);
BluetoothAdapter adaptateur = BluetoothAdapter.getDefaultAdapter();
UUID uuid = UUID.fromString(uuid_str);
BluetoothSocket socket = socketServeur.accept();
InputStream inStream = socket.getInputStream();OutputStream outStream = socket.getOutputStream();
CRÉATION D'UN SERVEUR : exemple
public class ServeurBt extends Thread {
private BluetoothSocket socket = null;
private BluetoothServerSocket socketServeur = null;
public ServeurBt(String nom, UUID uuid) {
try {
socketServeur =
adapter.listenUsingRfcommWithServiceRecord(nom, uuid);
} catch (IOException e) { }
}
.../...
63
CRÉATION D'UN SERVEUR : exemple
.../...
public void run() {
while(true) {
try {
socket = socketServeur.accept();
} catch (IOException e) { break;}
...
}
}
.../...
64
CRÉATION D'UN SERVEUR : exemple
.../...
public void annuler() {
try {
if (serverSocket != null)
serverSocket.close();
} catch (IOException e) { }
}
}
65
CRÉATION D'UN CLIENT
¢ Avant de pouvoir demander une connexion à un appareil distant, vous devez posséder l'objet BluetoothDevice de ce dernier : � soit en parcourant les appareils liés, � soit en effectuant une nouvelle détection d'appareils.
66
CRÉATION D'UN CLIENT
¢ La création d'un client suit la logique suivante (1) : � Appelez la méthode
createRfcommSocketToServiceRecord(UUID) de votre objet BluetoothDevice en spécifiant l'UUID du service désiré (le même que celui que vous aurez spécifié au BluetoothServerSocket).
� Cette méthode retourne un objet BluetoothSocket qui permettra de se connecter à l'appareil plus tard.
67
CRÉATION D'UN CLIENT
¢ La création d'un client suit la logique suivante (2) : � Appelez la méthode connect() de l'instance
BluetoothSocket. � Cet appel créera la connexion de communication
RFCOMM avec l'autre appareil si le service distant accepte votre demande.
� Cette méthode est bloquante ; par conséquence placez toujours votre code dans un fil d'exécution indépendant.
¢ Vous pouvez vous déconnecter en appelant la méthode close() de l'objet BluetoothSocket.
¢ Dans tous les cas, appelez cette méthode pour libérer les ressources.
68
CRÉATION D'UN Client
69
BluetoothSocket socket = appareilDist.createRfcommSocketToServiceRecord(uuid);
BluetoothAdapter adaptateur = BluetoothAdapter.getDefaultAdapter();
UUID uuid = UUID.fromString(uuid_str);
socket.connect();
InputStream inStream = socket.getInputStream();OutputStream outStream = socket.getOutputStream();
BluetoothDevice appareilDist = adaptateur.getRemoteDevice(mac_adr);
String mac_adr = "AA:BB:CC:DD:EE:FF"
CRÉATION D'UN CLIENT : exemple
public class ClientBt extends Thread {
private BluetoothSocket socket;
public ClientBt(BluetoothDevice appareil, UUID uuid) {
try {
socket = appareil.createRfcommSocketToServiceRecord(uuid);
} catch (IOException e) { }
}
.../...
70
CRÉATION D'UN CLIENT : exemple
.../...
public void run() {
//if (adapter.isDiscovering()) adapter.cancelDiscovery();
try {
socket.connect();
} catch (IOException connectException) {
try {
socket.close();
} catch (IOException closeException) { }
return;
}
}
.../... 71
CRÉATION D'UN CLIENT : exemple
.../...
public void annule() {
try {
socket.close();
} catch (IOException e) { }
}
}
.../...
72
ÉCHANGER DES DONNÉES
¢ Une fois le serveur et le client connectés, chacun va pouvoir échanger avec l'autre au travers de son objet BluetoothSocket.
¢ Comme pour toute communication par les sockets, les méthodes et techniques sont les mêmes. � Vous pouvez utiliser les méthodes getInputStream et
getOutputStream pour récupérer les flux entrant et sortant.
� Une fois les flux récupérés, vous pourrez utiliser les méthodes read et write respecti- vement pour lire et écrire des données.
� Ces méthodes étant bloquantes, vous devrez toujours les exécuter dans un fil d'exécution séparé.
73
UTILISER LE BLUETOOTH DANS VOS APPLICATIONS
¢ Le Bluetooth est un puissant outil pour rendre vos applications communicantes (réseau social, service de transfert de données, partage de données ou de connexion, etc).
¢ Mais comme tout moyen de communication, il consomme de la batterie et diminue d'autant l'autonomie du téléphone de l'utilisateur.
¢ Sachez utiliser ce moyen de communication avec parcimonie et n'activez le Bluetooth que si nécessaire.
¢ Sachez également que la détection des appareils à proximité consomme plus que la moyenne : n'effectuez donc des détections qu'en cas de besoin et après avoir averti l'utilisateur de cet écueil.
74
Caméra & Appareil photo 75
PRENDRE UNE PHOTO
¢ Déclarer une permission : <uses-feature android:name="android.hardware.camera" android:required="true" />
76
PRENDRE UNE PHOTO
¢ Lancer la caméra : private void lancerLaCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, 1);
}
}
77
PRENDRE UNE PHOTO
¢ Récupérer l’icône de la photo : @Override
protected void onActivityResult(int rCode, int resultCode, Intent data) {
if (rCode== 1 && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap bitmap = (Bitmap) extras.get("data");
imageView.setImageBitmap(bitmap);
}
}
78
PRENDRE UNE PHOTO
¢ Stocker la photo prise dans un fichier : � Déclarer une Permission :
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
79
PRENDRE UNE PHOTO
¢ Stocker la photo prise dans un fichier : � Créer un nom de fichier :
private String cheminAbsoluImg = "";
private void lancerLaCamera() throws IOException {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
File dossier = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File fichier = new File(dossier+"/monimage.jpg");
if(fichier != null) {
cheminAbsoluImg = fichier.getAbsolutePath();
startActivityForResult(intent, 1);
}
}
} 80
PRENDRE UNE PHOTO
¢ Stocker la photo prise dans un fichier : � Déclarer le fournisseur pour l’enregistrement :
private String cheminAbsoluImg = "";
private void lancerLaCamera() throws IOException {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
File dossier = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File fichier = new File(dossier+"/monimage.jpg");
if(fichier != null) {
cheminAbsoluImg = fichier.getAbsolutePath();
Uri uri = FileProvider.getUriForFile(this,
"nom_du_package.fileprovider", fichier);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, 1);
}
}
}
81
PRENDRE UNE PHOTO
¢ Stocker la photo prise dans un fichier : � Déclarer le fournisseur pour l’enregistrement :
<application>
...
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="nom_package.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"></meta-data>
</provider>
...
</application>
82
PRENDRE UNE PHOTO
¢ Stocker la photo prise dans un fichier : � Déclarer le fournisseur pour l’enregistrement (le fichier
file_paths) <?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="." />
</paths>
83
PRENDRE UNE PHOTO
¢ Récupérer l’image de la photo : @Override
protected void onActivityResult(int rCode, int resultCode, Intent data) {
if (rCode== 1 && resultCode == RESULT_OK) {
Bitmap bitmap = BitmapFactory.decodeFile(cheminAbsoluImg);
imageView.setImageBitmap(bitmap);
}
}
84
85