iOS 中是否有用于自定义振动的 API?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12966467/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:49:35  来源:igfitidea点击:

Are there APIs for custom vibrations in iOS?

iosvibrationiphone-vibrate

提问by Andrew

Starting in iOS 5, users are able to create custom vibration patterns for alerts and rings. The following screenshot shows the UI for creating one (Contacts app in iOS 6):

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

Screenshot of UI for creating custom vibrations in iOS 6

在 iOS 6 中创建自定义振动的 UI 屏幕截图

I've been searching around, including the documentation, and I cannot find any public APIs that expose the creation or playback of custom vibrations. The closest thing is to use the AudioToolboxframework to play a short, constant vibration:

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

AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

Does anyone know if there are APIs for custom vibrations?It doesn't necessarily have to be public APIs. I'm curious to know what the Contacts app uses. Does anyone know?

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

P.S. Others have suggested _CTServerConnectionCreatein CoreTelephony(example). I tried it, but couldn't get any vibration going for some reason.

PS 其他人_CTServerConnectionCreateCoreTelephony示例)中提出了建议。我试过了,但由于某种原因无法产生任何振动。

October 2015 Update:

There are new private APIs in iOS 9 to interact with the Taptic Engine in compatible devices. See Taptic in iOS 9for more.

2015 年 10 月更新:

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

回答by Kevin Cao

After serval hours' digging in the Contact App, I have figured out how it works.

在接触应用程序中挖掘了几个小时后,我已经弄清楚它是如何工作的。

ABNewPersonViewControlle invoke some class in ToneLibrary framework to do this.

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

The call stack looks like this:

调用堆栈如下所示:

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

After search "AudioServicesPlaySystemSoundWithVibration" on the web , I found nothing.

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

So I decide to look into it myself. It's a private function in AudioToolbox framework.

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

the declaration of the function is like

函数的声明就像

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

"inSystemSoundID" is SystemSoundID .just like "AudioServicesPlaySystemSound", pass "kSystemSoundID_Vibrate".

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

"arg" is not important, pass nil to it , everything will still work fine.

"arg" 并不重要,将 nil 传递给它,一切仍然可以正常工作。

"vibratePattern" is a pointer of "NSDictionary", the Contact App pass into { Intensity = 1; OffDuration = 1; OnDuration = 10; } for recording user input.

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

But only call this function will make a vibration never stop. So I have to found some function to stop it.

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

The answer is "AudioServicesStopSystemSound". It's also a private function in AudioToolbox framework.

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

the declaration of the function is like

函数的声明就像

void AudioServicesStopSystemSound(SystemSoundID inSystemSoundID)

I guess the Contact App use AudioServicesPlaySystemSoundWithVibration in touchesBegan method, and AudioServicesStopSystemSound in touchEnd method to reach this effect.

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

TLVibrationController will manager a vibrate pattern object to record the process you input.

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

At last it generate a dictionary to pass into AudioServicesPlaySystemSoundWithVibration to replay the whole process like below:

最后它生成一个字典传递给 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);

So if you want a custom vibrations in iOS. Use AudioServicesPlaySystemSoundWithVibration and AudioServicesStopSystemSound.

所以如果你想在 iOS 中自定义振动。使用 AudioServicesPlaySystemSoundWithVibration 和 AudioServicesStopSystemSound。

回答by Jonathan

There's a project called HapticKeyboard that does this. See: http://code.google.com/p/zataangstuff/source/browse/trunk/HapticKeyboard/Classes/HapticKeyboard.m?r=93

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

Specifically, look at the last set of functions

具体看最后一组函数

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

There are two problems:

有两个问题:

  1. I doubt you'd get your app allowed into the app store. Apple will see this as a battery drain for users and they are pretty strict about the user experience
  2. This may require jailbreaking. There have been several new iOS versions since I've last played with this, so it's hard to tell
  1. 我怀疑您是否会允许您的应用进入应用商店。Apple 会将其视为用户的电池消耗,并且他们对用户体验非常严格
  2. 这可能需要越狱。自从我上次玩这个以来,已经有几个新的 iOS 版本,所以很难说