From c24879880b277d1ec537692840d512d61c6e12ca Mon Sep 17 00:00:00 2001 From: Gil Shahar Date: Sat, 25 Feb 2017 18:30:58 +0200 Subject: [PATCH] Updated for Version 1.2 -Added iOS 9 support -Added preference pane to disable the tweak on the lockscreen and displaying album name as the title of the banner -Added support to the folowing apps: SoundCloud, Saavn, VOX, Doppi and Tidal. --- Makefile | 6 ++- Tweak.xm | 46 +++++++++++++----- control | 2 +- notifymusicprefs/Makefile | 14 ++++++ notifymusicprefs/Resources/Info.plist | 24 +++++++++ notifymusicprefs/Resources/NotifyMusic@2x.png | Bin 0 -> 5391 bytes notifymusicprefs/Resources/Root.plist | 41 ++++++++++++++++ notifymusicprefs/entry.plist | 21 ++++++++ notifymusicprefs/nmpRootListController.h | 5 ++ notifymusicprefs/nmpRootListController.m | 13 +++++ 10 files changed, 158 insertions(+), 14 deletions(-) create mode 100644 notifymusicprefs/Makefile create mode 100644 notifymusicprefs/Resources/Info.plist create mode 100644 notifymusicprefs/Resources/NotifyMusic@2x.png create mode 100644 notifymusicprefs/Resources/Root.plist create mode 100644 notifymusicprefs/entry.plist create mode 100644 notifymusicprefs/nmpRootListController.h create mode 100644 notifymusicprefs/nmpRootListController.m diff --git a/Makefile b/Makefile index 0dec3e6..e23ca7b 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,16 @@ ARCHS = armv7 arm64 VALID_ARCHS = armv7 armv7s arm64 -include theos/makefiles/common.mk +include $(THEOS)/makefiles/common.mk TWEAK_NAME = NotifyMusic NotifyMusic_FILES = Tweak.xm -NotifyMusic_FRAMEWORKS = UIKit +NotifyMusic_FRAMEWORKS = UIKit MediaPlayer NotifyMusic_LIBRARIES = bulletin include $(THEOS_MAKE_PATH)/tweak.mk after-install:: install.exec "killall -9 SpringBoard" +SUBPROJECTS += notifymusicprefs +include $(THEOS_MAKE_PATH)/aggregate.mk diff --git a/Tweak.xm b/Tweak.xm index 672b8f5..c661b50 100644 --- a/Tweak.xm +++ b/Tweak.xm @@ -1,8 +1,22 @@ #import +@interface SBApplication +@end + +@interface SpringBoard ++(SpringBoard *)sharedApplication; +-(SBApplication *)_accessibilityFrontMostApplication; +@end + +@interface SBLockScreenManager ++(SBLockScreenManager *)sharedInstance; +-(BOOL)isUILocked; +@end + @interface MPUNowPlayingMetadata @property (nonatomic,readonly) NSString * title; @property (nonatomic,readonly) NSString * artist; + @property (nonatomic,readonly) NSString * album; @end @interface MPUNowPlayingController @@ -10,6 +24,7 @@ @property (nonatomic,readonly) NSString * nowPlayingAppDisplayID; @property (nonatomic,readonly) MPUNowPlayingMetadata * currentNowPlayingMetadata; @property (nonatomic,readonly) UIImage * currentNowPlayingArtwork; + @property (nonatomic,readonly) NSDictionary * currentNowPlayingInfo; @end @interface JBBulletinManager : NSObject @@ -26,22 +41,31 @@ %hook MPUNowPlayingController static NSString *cachedTitle; static NSString *artist; + static NSString *album; -(void)_updateCurrentNowPlaying{ %orig; + NSString *settingsPath = @"/var/mobile/Library/Preferences/com.gilshahar7.notifymusicprefs.plist"; + NSMutableDictionary *prefs = [[NSMutableDictionary alloc] initWithContentsOfFile:settingsPath]; + BOOL enablewhilelocked = [[prefs objectForKey:@"enablewhilelocked"] boolValue]; + BOOL showalbumname = [[prefs objectForKey:@"showalbumname"] boolValue]; double delayInSeconds = 0.5; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ - if(self.isPlaying && ([self.nowPlayingAppDisplayID isEqualToString:@"com.apple.Music"] || [self.nowPlayingAppDisplayID isEqualToString:@"com.spotify.client"]) && ![cachedTitle isEqualToString:self.currentNowPlayingMetadata.title]){ - cachedTitle = [self.currentNowPlayingMetadata.title copy]; - if([self.currentNowPlayingMetadata.artist length] > 1){ - artist = [NSString stringWithFormat: @"\nBy: %@", self.currentNowPlayingMetadata.artist]; - }else{ - artist = @""; - } - if(self.currentNowPlayingArtwork != nil){ - [[objc_getClass("JBBulletinManager") sharedInstance] showBulletinWithTitle:@"Now Playing" message:[NSString stringWithFormat: @"%@%@", self.currentNowPlayingMetadata.title, artist] bundleID:self.nowPlayingAppDisplayID hasSound:false soundID:0 vibrateMode:0 soundPath:@"" attachmentImage:self.currentNowPlayingArtwork overrideBundleImage:nil]; - }else{ - [[objc_getClass("JBBulletinManager") sharedInstance] showBulletinWithTitle:@"Now Playing" message:[NSString stringWithFormat: @"%@%@", self.currentNowPlayingMetadata.title, artist] bundleID:self.nowPlayingAppDisplayID]; + if(![cachedTitle isEqualToString:self.currentNowPlayingInfo[@"kMRMediaRemoteNowPlayingInfoTitle"]]){ + cachedTitle = [self.currentNowPlayingInfo[@"kMRMediaRemoteNowPlayingInfoTitle"] copy]; + if((enablewhilelocked || (![[%c(SBLockScreenManager) sharedInstance] isUILocked])) && self.isPlaying && ([self.nowPlayingAppDisplayID isEqualToString:@"com.aspiro.TIDAL"] || [self.nowPlayingAppDisplayID isEqualToString:@"com.ondalabs.doppi"] || [self.nowPlayingAppDisplayID isEqualToString:@"com.coppertino.VoxMobile"] || [self.nowPlayingAppDisplayID isEqualToString:@"com.soundcloud.TouchApp"] || [self.nowPlayingAppDisplayID isEqualToString:@"com.Saavn.Saavn"] || [self.nowPlayingAppDisplayID isEqualToString:@"com.apple.Music"] || [self.nowPlayingAppDisplayID isEqualToString:@"com.spotify.client"] || [self.nowPlayingAppDisplayID isEqualToString:@"com.pandora"] || [self.nowPlayingAppDisplayID isEqualToString:@"com.rhapsody.iphone.Rhapsody3"] || [self.nowPlayingAppDisplayID isEqualToString:@"com.google.PlayMusic"] || [self.nowPlayingAppDisplayID isEqualToString:@"com.deezer.Deezer"] || [self.nowPlayingAppDisplayID isEqualToString:@"com.michaelclay.Cesium"])){ + artist = [NSString stringWithFormat: @"\n%@", self.currentNowPlayingInfo[@"kMRMediaRemoteNowPlayingInfoArtist"]]; + + if([self.currentNowPlayingInfo[@"kMRMediaRemoteNowPlayingInfoAlbum"] length] > 1 && showalbumname){ + album = self.currentNowPlayingInfo[@"kMRMediaRemoteNowPlayingInfoAlbum"]; + }else{ + album = @"Now Playing"; + } + if(self.currentNowPlayingArtwork != nil){ + [[objc_getClass("JBBulletinManager") sharedInstance] showBulletinWithTitle:album message:[NSString stringWithFormat: @"%@%@", self.currentNowPlayingInfo[@"kMRMediaRemoteNowPlayingInfoTitle"], artist] bundleID:self.nowPlayingAppDisplayID hasSound:false soundID:0 vibrateMode:0 soundPath:@"" attachmentImage:self.currentNowPlayingArtwork overrideBundleImage:nil]; + }else{ + [[objc_getClass("JBBulletinManager") sharedInstance] showBulletinWithTitle:album message:[NSString stringWithFormat: @"%@%@", self.currentNowPlayingInfo[@"kMRMediaRemoteNowPlayingInfoTitle"], artist] bundleID:self.nowPlayingAppDisplayID]; + } } } }); diff --git a/control b/control index 4025208..5d20b4b 100644 --- a/control +++ b/control @@ -1,7 +1,7 @@ Package: com.gilshahar7.notifymusic Name: NotifyMusic Depends: mobilesubstrate, net.limneos.libbulletin -Version: 1.0 +Version: 1.2 Architecture: iphoneos-arm Description: Creates a banner notification with song metadata when song is changed. Maintainer: gilshahar7 diff --git a/notifymusicprefs/Makefile b/notifymusicprefs/Makefile new file mode 100644 index 0000000..2ea0301 --- /dev/null +++ b/notifymusicprefs/Makefile @@ -0,0 +1,14 @@ +ARCHS = armv7 arm64 +include $(THEOS)/makefiles/common.mk + +BUNDLE_NAME = notifymusicprefs +notifymusicprefs_FILES = nmpRootListController.m +notifymusicprefs_INSTALL_PATH = /Library/PreferenceBundles +notifymusicprefs_FRAMEWORKS = UIKit +notifymusicprefs_PRIVATE_FRAMEWORKS = Preferences + +include $(THEOS_MAKE_PATH)/bundle.mk + +internal-stage:: + $(ECHO_NOTHING)mkdir -p $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences$(ECHO_END) + $(ECHO_NOTHING)cp entry.plist $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences/notifymusicprefs.plist$(ECHO_END) diff --git a/notifymusicprefs/Resources/Info.plist b/notifymusicprefs/Resources/Info.plist new file mode 100644 index 0000000..9bfa5e0 --- /dev/null +++ b/notifymusicprefs/Resources/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + notifymusicprefs + CFBundleIdentifier + com.gilshahar7.notifymusicprefs + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + NSPrincipalClass + nmpRootListController + + diff --git a/notifymusicprefs/Resources/NotifyMusic@2x.png b/notifymusicprefs/Resources/NotifyMusic@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..fde9da88b6d7bed8f282cbb7c811f112acffbf11 GIT binary patch literal 5391 zcmV+q74YhbP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRa5l}SWFRCwCVntPDlXL;X0&-1>&-#KS5(yn$TtyY$7OO|}Mv4wHN)poeFnc6j- zni*Qa1e}DH4if@Rm=-3X8JJ<3PNq#JnIsJ@VCtkMp{C$~jY9z!e8B;`uEF>sOSbN- zU9I+Z&hPhopQnHP&N*5Mt+aBP!f*8MX!o4+p7;A)zt8i$;_kft&DSF$lx4}((HXL4 zlj);J$r=M}-mnf;Sn3q~$z5M!a?1sPu;;m_Ir!2ZzH{G~xcJg5(B?4fCpOV&4RZOl zui}w!-p~DC_#BO)A#VPszl^0sN{Jnpzk+6Kko|j~Ll)=Rzx(^R8z2BQ@|?f^+Pxgy zH^srdQ%qd2jYl5;9ziOGTY-&@jEN;x&n;2LJ)(Dz>| z(xV6S?7_j&u^%p)QMpL~U%ubZCD4=-Ax61)=Y?*E4-Q^Bu;y2HEOPtseCx{dj?HUJ z=5U-~vy_s(@<6NcD+h)fGjp4Vzp{H|;3J2NrF{pBN(Ib+K7cwRLI|-h{}2L$LxXZ; z=9pi;cJ0LEfrFnJ|JH+V-r07>3J`-b8VgxPvoeNLo1wJG1q)$x`slHDOkRBcRR>>l z%|H3#zC+JcDXD_}jDb2Ky1%X*@(t5)yk+lux9(a)9PMelH z(Tz<-#cPhXUw6D!{hPmS?)%qsnkoSOSsHGYO2#KP^S%%LTPDZGk>fLjPTSeHZ}YZC zpa1aW?xO?|Ix%9BvnV+~-ZX-J@*@m?{!bYC(1!^O(<}^^k|Y%+iIMg^H!ay68}=W3 zxReML!AeYwfe;DzJizgHzmL%; zokb!^G0;DC>jtE zV$9^iotF)cZJcZpo1I3pRf%ZF%xq|QO}OOhT@zWWnMCxksGFXgCxeJIMMB%m%0{!v zRoB0EWMe3AT>s>sUnOZ8Qv(+gkklD24SDQwa^UdL0x5F_ijsywp&6Crv{FG*NSavR zw#geW*>*lKeHx%HopwiJ%>JZPyg3@Xg|M?mMGD|rM4dNl1QB|8igWhpnkDVRJc}<5}gR@&@`WjN9TV5 z`2I;iV~o;iFX`*w^bgY8-}Ua-UA^nN+X?wELb#x7tAOKf#4PLQK2aq|z|@g0tLd3G z2r+An&`lm@$ps{Yh^SPV>Q=QBsLJCOSyyCERw+Y(bWPnvFcHKB6DPTmn_&u-1}Y%) z0x=<}5DlWktR^nJ?4tAgrn|J%rc)Hm&K%QQZhL$B$R~dPSAkD>Duyu^cQ+Ri0TWRb z1$TE5(XKSjtxG~g#LTGQj?{v2bBEqG?&2bdi3BlllM-jx9ekj{@P^GOKfnPO$Fv3; zP{aWY6R;RalJ|un^0~Rms$mqcS?NIowJ*--bW)0CS zm!PUDqNmrC7pd#8JY9^Lw#3uQ!UCaP3 zifBXubpv;l2q;mN93do#CAfR-qphK}e&JAGV*J$XVdTf4ln+T z53uFXeqwYaI<2ZhiO|u2iPP{vRsaM9m>q0X505nd^z+Aef6QNOE{<*9Ed8ka>Nngl z9%ADvb3;VK%b{`|gdp{XeK=ajEiKvt@4bodwxvq!PHIR=gvwAw;e zb~to+fyqlQhXBog{8lz?Xmad>pG3a*C{0QRfuImgx`K5|&8R|TCg#;c1Nw(wU8f&= zyq)Gprw+^bc(v5C9cxq@|^KoMrbxzf63122fuy)2fzH4zxte9xYhHa5gmK_89A^p z?Y=A@M1TV?yr>(uZgEkPnYpU2-bcHUYx*nSz`y-4<9U;oC|S(w?X$q~W*~{;E{J3} zin&s%(#bLwvIe9`N>&H5P`kN_fjE-1WkT`H&$tNH2Kr|-GPcc26f z7Gl6pNqP~$lQl&ox_h6#o$C|l3)X9kq1eI$6hSFPF(P@&s8EtB9U_%RQVd{%q2!*C z6@ggf%qImLqo#7EMkgfl6bPjt(J4g`bE3E*w&&^#w;XuKZMQPtX|wmGm->~IFRPd$ zK-SC#(GYO=mx&X!L8zLzwP)Eh= zoT2kJFtC0N$DTOI_rCftqbfBMI7^)G9?|RKA`FgBoOc?^d4iy>1oWJrR?#3Ua~2zc z{a#|3B8{BR*dQ`F#>nPLh9|~oZ5pRFI!qYOPwH=!ZDsBO7zzk|R(u9TfbAkdaX zCj?RmaP~maQ$|8WagS#^_D=z5S0f>E*o`aR_!>t3{-u56a=>uR>b8hGh$xvtFej-Y z5^!-`Sq4&8FfIqY1P>tM^@i=UWs5FQw`DfrAm>a2-E&gPuz`pJ$*miC>xQf%I8IdU zeogI1Y5@t3tFROY>0}uqX9^PnuCa$$M4ZZkxt}2+WT$G>1-t^z8E9!am1k6;t_cH) zQX*Cr$tWf3 zPjy73PJOF#1i?f}S)dBK+ORL(OjC+kapoM~2ih}mf7yAol$?SbTV@QQxAQXpS>D_A zWsoXSma<5Z1(K{T!F%6H-OhIOcya)emkqX%oHh+o-@X0pDOpa`u7wDTG0=&jc3)qm zN=2HuG|y%NvFn=66OEu=JMA1bsyU_RSPy6|?z3pb5btqY=me#sik(Zv51@M1imTVI zY`&ba-$}z;B9-LWs-)EWtaY=hQ>ju!q11D-DLD~DR{_*W%Pi~+aoT#ZE@32+bic!( zvW#Ogf^}PR)B~hly#5E4G9H~Fe{OE7BR`X)|}1&&z8GsJ=Zo{c`fr% zUnv+Z4;~^_H|__NfZ&LfAX1lLn&Zea50!4gRS{h4;Nu2b*Q9MC^9zA}a|?Xusc8xs z!TLd8R^Uh|oZQf&n_(pq@q= zf+Ey~wbQK&vy4ZcJUXm5sc z_DvIr5h=O{38aqk>{Ii+u)mGvEsQ#fO3gv*dj|*&RbH4X_}tfb^HSP~4zEQ*gHkF8 zOO!EESwZF98yPq?`CV!&GcYW&lDGn?)DMmJs2S+{CvCY9zssu4>QupWVT*B_^fZ|=z3Et(p0?V4% z?)6NmBRujqhk59}DVC;3QPv|NLz<2aI8`>)RlF8kF+P+L(K81BQ!ieT>I)ew=a$%Y0{5~jSOe=ompgjxnZ1KQ`QQu>+%-*_*~*%M zb+m?ZbRbf-pq&NEd=U%X-dxwDT%;eMwwyPHutZrU3NqRfSqhOQZIQ}(*2`h8-_|1Q zS2wF@D0`2iD=V+=PZbF@Lv{geLTJ_EN-k0%;#gt)-NT0vCW(z9DuIrcv}2+ZJCv?e z)*xArO{V^^LM?!oT)BOKS6v~{*+aYCrl=~cbBr+e66=cn+(?@?xe~%K39ScPzh8aP(`DoffO<-gOEqojI@@; z2gmD;2v)Hs!0k6)$cA-O{NULmbUFp2YcsY@@`Cq23~#B`MmJ-K4uqY2|7TMK-)VMOUKx7-eGRN zbvr{%>Or=Iu4Yrsp(NI4sEkZIjK>O8!BS1rdW{XqFo|c-sVBrc{XnWZ^Y#1g{o2QV z^EU|H+cKv<4?nZ7e)F?W|8QaZT_sK z=rArJ2rMle|Ka0*_t;Vpp=@`~?4w`(n=cpde9wCxI`6`rHzT3x_1%vyyAq`4bqE>m zjz(wANWVX|Eai2>+)0|y9&Q5Qy}eFbtI7$)E9OxVJT&Y72>bWG@a2Vt`GsveF7A&X zRxHz=dF}=7{Oo7$6b*;Pt#?#8iMZD)p?|Ap`K1dvd7Ul6ue4Ungv9VrOY^x$zWbdo z?AiUCm^c-7+SS+S=-Od<^6@A39zD4Kx5qYa`r~e^zuO5H<>d~ZeyX=#y~kV>wF#$~GOx;NKBZLp^4lk;+&20D z^`w-llu~JCDWzm?KGj*A``CMLyH&;&y=bh(nU;IEusn9`IF?L4^XdQGx#zF`+j~Ui z&q53VCz_i(ZV5O4e`yn*y9!U5Z+h)Gs;Uck=hNT)pZEXKHy-$!H=9^l6r5@GeKgN= z1_lSL)oRLb{`v>n|MHGs{!ph1?g~NtG{#^x zD=&Z`P=OaJ%(&aUd)Sn!v{%LF)$IodUfliQV-J7#fp7oq*Qfr+7r!8H`)BX;(RE|1 zEpkq7rMNp9)KrzjhYrbS@4V~SkAM8k-C3(~_tex;Zn^oE$=~_-@2-;=gNQh8y)h-y zZ9<7Ecyi1frIMQNL^1Pj^p;+h5KE>iZmDt=O%l|=ODt7ZmZ7t_xOd;)=j{*w-6wfz t&kIa!o+Oo}Zr(g;DW!UFwaVxJ4gfrk9Ov=>!G!<-002ovPDHLkV1k&Zc258R literal 0 HcmV?d00001 diff --git a/notifymusicprefs/Resources/Root.plist b/notifymusicprefs/Resources/Root.plist new file mode 100644 index 0000000..6abf357 --- /dev/null +++ b/notifymusicprefs/Resources/Root.plist @@ -0,0 +1,41 @@ + + + + + items + + + cell + PSGroupCell + label + NotifyMusic + + + cell + PSSwitchCell + default + + defaults + com.gilshahar7.notifymusicprefs + key + enablewhilelocked + label + Enable while locked + + + cell + PSSwitchCell + default + + defaults + com.gilshahar7.notifymusicprefs + key + showalbumname + label + Show album name in title + + + title + NotifyMusic + + diff --git a/notifymusicprefs/entry.plist b/notifymusicprefs/entry.plist new file mode 100644 index 0000000..4354057 --- /dev/null +++ b/notifymusicprefs/entry.plist @@ -0,0 +1,21 @@ + + + + + entry + + bundle + notifymusicprefs + cell + PSLinkCell + detail + nmpRootListController + icon + NotifyMusic.png + isController + + label + NotifyMusic + + + diff --git a/notifymusicprefs/nmpRootListController.h b/notifymusicprefs/nmpRootListController.h new file mode 100644 index 0000000..53a1403 --- /dev/null +++ b/notifymusicprefs/nmpRootListController.h @@ -0,0 +1,5 @@ +#import + +@interface nmpRootListController : PSListController + +@end diff --git a/notifymusicprefs/nmpRootListController.m b/notifymusicprefs/nmpRootListController.m new file mode 100644 index 0000000..f9ddd0e --- /dev/null +++ b/notifymusicprefs/nmpRootListController.m @@ -0,0 +1,13 @@ +#include "nmpRootListController.h" + +@implementation nmpRootListController + +- (NSArray *)specifiers { + if (!_specifiers) { + _specifiers = [[self loadSpecifiersFromPlistName:@"Root" target:self] retain]; + } + + return _specifiers; +} + +@end