如何在iPhone上通过编程方式设置锁屏、壁纸和铃声?

27

在 iPhone 上,我们是否可以通过程序设置锁屏、壁纸和铃声?

如果 的话,请告诉我如何设置它们呢?


1
+1 我在许多应用程序中看到过它。https://dev59.com/6W7Xa4cB1Zd3GeqPt8oh - HDdeveloper
3个回答

39

这一切都可以轻松完成,但会被苹果拒绝。

通过修改com.apple.SpringBoard.plist文件中的ringtone键来改变铃声。

以下代码可用于读取自定义铃声(通过iTunes同步)的实际铃声标题。

NSMutableDictionary *custDict = [[NSMutableDictionary alloc] initWithContentsOfFile:@"/private/var/mobile/Media/iTunes_Control/iTunes/Ringtones.plist"];
NSMutableDictionary *dictionary = [custDict objectForKey:@"Ringtones"];

NSArray *keys = [dictionary allKeys];
id key = [keys objectAtIndex:indexPath.row];
NSMutableDictionary *customRingtone = [dictionary objectForKey:key];
NSString *name = [customRingtone objectForKey:@"Name"];
cell.textLabel.text = name;

壁纸可以被覆盖在以下位置:

NSString *homePath1 = @"/private/var/mobile/Library/SpringBoard/HomeBackground.jpg";
NSString *homePath2 = @"/private/var/mobile/Library/SpringBoard/HomeBackgroundPortrait.jpg";
NSString *lockPath1 = @"/private/var/mobile/Library/SpringBoard/LockBackground.jpg";
NSString *lockPath2 = @"/private/var/mobile/Library/SpringBoard/LockBackgroundPortrait.jpg";

这些示例是我在Cydia应用程序中使用的。它们并没有太多其他的内容,但应该能够帮助您朝着正确的方向前进。


2
壁纸路径不再有效。 - EightyEight
32
无需点踩。这些回答在问题提出并被选为正确答案时是有效的。 - WrightsCS
2
我不能告诉你新路径,但我可以告诉你苹果使用了一种新的图像格式。它是cpbitmap,所以如果你想保存这个图像,你需要先将.png或.jpeg转换为.cpbitmap。 - David Gölzhäuser
@WrightsCS,您能否更新iOS 9.x的新路径? - GoodSp33d
如何在 Objective-C 中以编程方式更改铃声 - Ramani Hitesh

2
WrightsCS的答案因为iOS的某些变化而失效。如果你想使用未记录的特性,则不得不接受这一点。
如果你仍然需要这样做,那么仅适用于非App Store应用程序,这段代码在iOS 9.3中有效。但是,它可能会在任何未来的iOS版本中停止工作。(参见下面的评论:在iOS 10中不再起作用)
#import "SBSUIWallpaperPreviewViewController.h"
#import <dlfcn.h>

// open the private framework dynamically
void *handle = dlopen("/System/Library/PrivateFrameworks/SpringBoardUIServices.framework/SpringBoardUIServices", RTLD_NOW);

UIImage *wallpaper = [UIImage imageNamed: @"background.jpg"];

Class sbClass = NSClassFromString(@"SBSUIWallpaperPreviewViewController");
// we create a view controller, but don't display it. 
//  just use it to load image and set wallpaper
SBSUIWallpaperPreviewViewController *controller = (SBSUIWallpaperPreviewViewController*)[[sbClass alloc] initWithImage: wallpaper];
[controller setWallpaperForLocations: 3];  // 3 -> set both for lock screen and home screen

dlclose(handle);

您需要将私有API头文件添加到您的项目中。您可以通过一些搜索通常在线找到这些文件,例如这里
在上面的示例中,使用参数3调用了[SBSUIWallpaperPreviewViewController setWallpaperForLocations:]:3表示该图像应用于锁定和主屏幕。1表示仅锁定屏幕。2表示仅主屏幕。
关于为什么我以动态方式打开此框架的解释,请参见我的相关答案
我没有关于铃声的答案。这真的应该是一个单独的问题:完全不同的API在起作用。

1
很不幸,这在iOS 10上不再起作用。@Nate你有关于如何在iOS 10上运行它的信息吗?(对于iOS 10,他的代码会崩溃并显示以下错误: Assertion failed: (0), function SBSUIWallpaperClearVideo, file /BuildRoot/Library/Caches/com.apple.xbs/Sources/SpringBoardUIServices/SpringBoard-3563.15.8.9/SBSUIWallpaperUtilities.m, line 143.) 可能他们添加了一些智能断言...) - Guntis Treulands
2
@GuntisTreulands,是的,我也注意到了。我正在查看iOS 10 headers,看起来API仍然存在。现在可能受到权限保护。我记得过去找到其他方法来做这件事,所以让我花点时间在周末尝试其他方法来使其工作。 - Nate
@GuntisTreulands,我也尝试在PLStaticWallpaperImageViewController中使用相似的方法,但是它也失败了。看起来iOS认为该应用程序试图更改其沙盒外的某些内容。我还看到PhotoLibrary中还有另一个API,但我需要进行一些反向工程才能弄清楚它所采取的参数。我会在这里及时更新。 - Nate

1
如果可以的话,请使用私有API,检查PLStaticWallpaperImageViewController

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接