【问题标题】:Are there APIs for custom vibrations in iOS?iOS 中是否有用于自定义振动的 API?
【发布时间】:2012-10-09 14:36:30
【问题描述】:

从 iOS 5 开始,用户可以为警报和铃声创建自定义振动模式。以下屏幕截图显示了用于创建一个的 UI(iOS 6 中的联系人应用程序):

我一直在四处搜索,包括文档,但找不到任何公开自定义振动的创建或播放的公共 API。最接近的就是使用AudioToolbox 框架来播放一个短暂的、持续的振动:

AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

有谁知道是否有用于自定义振动的 API? 它不一定是公共 API。我很想知道联系人应用程序使用什么。有人知道吗?

附注其他人在CoreTelephony (example) 中建议了_CTServerConnectionCreate。我试过了,但由于某种原因无法振动。

2015 年 10 月更新:

iOS 9 中有新的私有 API 可与兼容设备中的 Taptic Engine 进行交互。请参阅Taptic in iOS 9 了解更多信息。

【问题讨论】:

  • Core Haptics 即将在 iOS 13 中推出!它目前处于测试阶段。有关详细信息,请参阅“创建自定义触觉模式”here。

标签: ios vibration iphone-vibrate


【解决方案1】:

在联系人应用程序中挖掘了几个小时后,我弄清楚了它是如何工作的。

ABNewPersonViewControlle 调用 ToneLibrary 框架中的某个类来执行此操作。

调用堆栈如下所示:

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

在网上搜索“AudioServicesPlaySystemSoundWithVibration”后,我一无所获。

所以我决定自己研究一下。它是 AudioToolbox 框架中的一个私有函数。

函数的声明是这样的

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

“inSystemSoundID”是SystemSoundID。就像“AudioServicesPlaySystemSound”一样,传递“kSystemSoundID_Vibrate”。

"arg" 不重要,将 nil 传递给它,一切都会正常工作。

“vibratePattern”是“NSDictionary”的指针,Contact App传入 { 强度 = 1; 关闭持续时间 = 1; 持续时间 = 10; } 用于记录用户输入。

但是只有调用这个函数才会让震动永不停止。所以我必须找到一些函数来阻止它。

答案是“AudioServicesStopSystemSound”。也是 AudioToolbox 框架中的私有函数。

函数的声明是这样的

void AudioServicesStopSystemSound(SystemSoundID inSystemSoundID)

我猜Contact App在touchesBegan方法中使用AudioServicesPlaySystemSoundWithVibration,在touchEnd方法中使用AudioServicesStopSystemSound来达到这个效果。

TLVibrationController 将管理一个振动模式对象来记录您输入的过程。

最后它生成一个字典传递给 AudioServicesPlaySystemSoundWithVibration 来回放整个过程,如下所示:

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);

因此,如果您想在 iOS 中自定义振动。使用 AudioServicesPlaySystemSoundWithVibration 和 AudioServicesStopSystemSound。

【讨论】:

  • 注意:AudioServicesPlaySystemSoundWithVibration 仅适用于 iOS6。
  • @Jonny FOUNDATION_EXTERN "AudioServicesPlaySystemSoundWithVibration(unsigned long, objc_object*, NSDictionary*) 可以解决问题。不要忘记也链接到 AudioToolbox.framework
  • 现在 Apple 在提交时拒绝 AudioServicesPlaySystemSoundWithVibration。
  • 有什么方法可以实现自定义振动而不会让应用被苹果拒绝?
  • 这只会让您收到这样的好邮件:** 我们发现您最近发送的“Appname”存在一个或多个问题。要处理您的交付,必须更正以下问题: 非公共 API 使用:该应用引用了 Appname 中的非公共符号:_AudioServicesPlaySystemSoundWithVibration **
【解决方案2】:

有一个名为 HapticKeyboard 的项目可以做到这一点。见:http://code.google.com/p/zataangstuff/source/browse/trunk/HapticKeyboard/Classes/HapticKeyboard.m?r=93

具体看最后一组函数

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

有两个问题:

  1. 我怀疑你的应用是否会被允许进入应用商店。 Apple 会将此视为用户的电池消耗,他们对用户体验非常严格
  2. 这可能需要越狱。自从我上次玩这个之后,已经有几个新的 iOS 版本,所以很难说

【讨论】:

  • 感谢您的回答。在我提出问题之前,我确实已经看过 HapticKeyboard(已有 4 年历史)。我尝试按照代码中的说明触发振动,但它对我不起作用。我正在寻找 Apple 用于在联系人中实现自定义振动的 API,如屏幕截图所示。
  • Apple 的 HapticEngine 和其他设备上的所有振动响应实际上是在消耗电池电量。顺便说一句,代码链接已损坏。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-14
  • 2023-01-22
  • 2011-06-12
  • 1970-01-01
相关资源
最近更新 更多