web-dev-qa-db-fra.com

Existe-t-il des API pour les vibrations personnalisées dans iOS?

À partir d'iOS 5, les utilisateurs peuvent créer des modèles de vibration personnalisés pour les alertes et les sonneries. La capture d'écran suivante montre l'interface utilisateur pour en créer une (application Contacts dans iOS 6):

Screenshot of UI for creating custom vibrations in iOS 6

J'ai cherché autour, y compris la documentation, et je ne trouve aucune API publique qui expose la création ou la lecture de vibrations personnalisées. Le plus proche est d'utiliser le framework AudioToolbox pour jouer une vibration courte et constante:

AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

Quelqu'un sait-il s'il existe des API pour les vibrations personnalisées? Il ne doit pas nécessairement s'agir d'API publiques. Je suis curieux de savoir ce que l'application Contacts utilise. Est-ce que quelqu'un sait?

P.S. D'autres ont suggéré _CTServerConnectionCreate dans CoreTelephony ( exemple ). Je l'ai essayé, mais je n'ai pu déclencher aucune vibration pour une raison quelconque.

Mise à jour d'octobre 2015:

Il existe de nouvelles API privées dans iOS 9 pour interagir avec Taptic Engine sur les appareils compatibles. Voir Taptic dans iOS 9 pour en savoir plus.

69
Andrew

Après avoir creusé des heures dans l'application Contact, j'ai compris comment cela fonctionne.

ABNewPersonViewControlle invoque une classe dans le framework ToneLibrary pour ce faire.

La pile d'appels ressemble à ceci:

0   CoreFoundation                  0x3359a1d4 CFGetTypeID + 0
1   CoreFoundation                  0x33596396 __CFPropertyListIsValidAux + 46
2   CoreFoundation                  0x33517090 CFPropertyListCreateData + 124
3   AudioToolbox                    0x38ac255a AudioServicesPlaySystemSoundWithVibration + 158
5   ToneLibrary                     0x35a7811a -[TLVibrationRecorderView vibrationComponentDidStartForVibrationRecorderTouchSurface:] + 38
6   ToneLibrary                     0x35a772b2 -[TLVibrationRecorderTouchSurface touchesBegan:withEvent:] + 342
7   UIKit                           0x3610f526 -[UIWindow _sendTouchesForEvent:] + 314
8   UIKit                           0x360fc804 -[UIApplication sendEvent:] + 376

Après avoir recherché "AudioServicesPlaySystemSoundWithVibration" sur le Web, je n'ai rien trouvé.

Je décide donc de m'y intéresser moi-même. C'est une fonction privée dans le framework AudioToolbox.

la déclaration de la fonction est comme

void AudioServicesPlaySystemSoundWithVibration(SystemSoundID inSystemSoundID,id arg,NSDictionary* vibratePattern)

"inSystemSoundID" est SystemSoundID .comme "AudioServicesPlaySystemSound", passez "kSystemSoundID_Vibrate".

"arg" n'est pas important, passez à zéro, tout fonctionnera bien.

"vibratePattern" est un pointeur de "NSDictionary", l'application Contact passe en {Intensity = 1; OffDuration = 1; OnDuration = 10; } pour enregistrer les entrées utilisateur.

Mais seulement appeler cette fonction fera qu'une vibration ne s'arrêtera jamais. Je dois donc trouver une fonction pour l'arrêter.

La réponse est "AudioServicesStopSystemSound". C'est également une fonction privée dans le cadre AudioToolbox.

la déclaration de la fonction est comme

void AudioServicesStopSystemSound(SystemSoundID inSystemSoundID)

Je suppose que l'application Contact utilise AudioServicesPlaySystemSoundWithVibration dans la méthode touchesBegan et AudioServicesStopSystemSound dans la méthode touchEnd pour atteindre cet effet.

TLVibrationController gérera un objet de modèle de vibration pour enregistrer le processus que vous saisissez.

Enfin, il génère un dictionnaire à passer dans AudioServicesPlaySystemSoundWithVibration pour rejouer tout le processus comme ci-dessous:

NSMutableDictionary* dict = [NSMutableDictionary dictionary];
NSMutableArray* arr = [NSMutableArray array ];

[arr addObject:[NSNumber numberWithBool:YES]]; //vibrate for 2000ms
[arr addObject:[NSNumber numberWithInt:2000]];

[arr addObject:[NSNumber numberWithBool:NO]];  //stop for 1000ms
[arr addObject:[NSNumber numberWithInt:1000]];

[arr addObject:[NSNumber numberWithBool:YES]];  //vibrate for 1000ms
[arr addObject:[NSNumber numberWithInt:1000]];

[arr addObject:[NSNumber numberWithBool:NO]];    //stop for 500ms
[arr addObject:[NSNumber numberWithInt:500]];

[dict setObject:arr forKey:@"VibePattern"];
[dict setObject:[NSNumber numberWithInt:1] forKey:@"Intensity"];


AudioServicesPlaySystemSoundWithVibration(4095,nil,dict);

Donc, si vous voulez des vibrations personnalisées dans iOS. Utilisez AudioServicesPlaySystemSoundWithVibration et AudioServicesStopSystemSound.

102
Kevin Cao

Il y a un projet appelé HapticKeyboard qui fait cela. Voir: http://code.google.com/p/zataangstuff/source/browse/trunk/HapticKeyboard/Classes/HapticKeyboard.m?r=9

Plus précisément, regardez le dernier ensemble de fonctions

_CTServerConnectionSetVibratorState(&x, connection, 0, 0, 0, 0, 0);

Il y a deux problèmes:

  1. Je doute que votre application soit autorisée dans l'App Store. Apple verra cela comme une décharge de batterie pour les utilisateurs et ils sont assez stricts sur l'expérience utilisateur
  2. Cela peut nécessiter un jailbreak. Il y a eu plusieurs nouvelles versions iOS depuis la dernière fois que j'ai joué avec ça, donc c'est difficile à dire
4
Jonathan