How to set lock screen , wallpaper and Ringtone programmatically in iPhone?
Asked Answered
L

3

27

In iPhone can we set the lock screen, wallpaper and ringtone programmatically?

If Yes, then please let me know how to set them?

Leatherjacket answered 18/12, 2010 at 5:18 Comment(1)
+1 I seen it in many apps. #15024861Thin
A
39

This can all be done easily, but will be rejected by Apple.

The ringtone can be changed by altering com.apple.SpringBoard.plist, specifically the ringtone key.

The following code can be used to read the actual ringtone title of custom ringtones (synced by 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;

The Wallpapers can be overwritten at:

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

These examples were used in one of my Cydia apps. Theres not really much more to them, but these should get you going in the right direction.

Atman answered 18/12, 2010 at 5:44 Comment(5)
Wallpaper paths are no longer valid.Tazza
No need for the down vote. They were valid at the time the question was asked and chosen as the correct answer.Atman
I cant tell you the new path, but I can tell you that apple uses a new image formate. Its a cpbitmap, so if you like tomsave the image you first need to convert the .png or .jpeg to a .cpbitmapPaly
@Atman Could you please update with the new paths for iOS 9.x ?Amagasaki
how to change programmatically change ringtone objective cWhittemore
K
2

The answer by WrightsCS stopped working at some point due to a change in iOS. Unfortunately, this is something you have to live with if you wish to use undocumented features.

If you still need to do this, for non-App Store apps only, this code works in iOS 9.3. It could stop working in any future iOS release, though. (see comment below: no longer working in 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);

You'll need to add the private API header to your project. You can usually find these online with a little searching, for example, here.

In the example above, [SBSUIWallpaperPreviewViewController setWallpaperForLocations:] is called with an argument of 3: 3 indicates the image should be used for both lock and home screens. 1 indicates Lock screen only. 2 indicates Home screen only.


For an explanation of why I open this framework up dynamically, see my related answer here.

I don't have an answer regarding ringtones. This really should be a separate question: completely different APIs at work.

Kimmy answered 17/8, 2016 at 10:13 Comment(3)
Unfortunately this does not work on iOS 10 anymore. @Kimmy do you have info how to get this running on iOS 10? (For iOS 10 his code crashes with error: Assertion failed: (0), function SBSUIWallpaperClearVideo, file /BuildRoot/Library/Caches/com.apple.xbs/Sources/SpringBoardUIServices/SpringBoard-3563.15.8.9/SBSUIWallpaperUtilities.m, line 143.) Probably they added some smart asserts... )Grishilde
@GuntisTreulands, yes I noticed that, too. I'm looking at iOS 10 headers and it looks like the API is still there. Might be protected by entitlement, now. I do remember in the past finding other ways to do this, so let me spend some time this weekend trying other things to get this working.Kimmy
@GuntisTreulands, I also tried using the similar method in PLStaticWallpaperImageViewController, but it also failed. It looks like iOS recognizes that the app is trying to change something outside its sandbox. I also see there's another API in PhotoLibrary, but I have to do some reverse engineering to figure out what the parameter it takes is. I will keep you updated here.Kimmy
M
1

use private api if you can check PLStaticWallpaperImageViewController

Manteau answered 4/2, 2015 at 9:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.