בקרות מדיה יציבות במסך הנעילה: iOS, אנדרואיד, Flutter

משתמשים רבים מתעצבנים כשהם נאלצים לפתוח את הטלפון ולפתוח את האפליקציה כדי להחליף שירים. אנו מפתחים ומגדירים פקדי מדיה במסך הנעילה עבור iOS, Android ו-Flutter, ומשלבים אותם עם ממשקי API מקוריים. הצוות שלנו מספק את הפרויקט במפתח מלא—מבדיקת היתכנות ועד תמיכה שוטפת—תוך הבטחת ביצועים יציבים ותאימות לגרסאות מערכת הפעלה עדכניות.

פיתוח ותמיכה בכל סוגי היישומים הניידים:

יישומים ניידים למידע ובידור
אפליקציות חדשות, משחקים, מדריכים, קטלוגים מקוונים, אפליקציות מזג אוויר, אפליקציות כושר ובריאות, אפליקציות נסיעות, אפליקציות חינוכיות, רשתות חברתיות ומסנג'רים, חידונים, בלוגים ופודקאסטים, פורומים, אגרגטורים
יישומים ניידים למסחר אלקטרוני
חנויות מקוונות, אפליקציות B2B, מרקטפלייסים, בורסות מקוונות, שירותי קאשבק, בורסות, פלטפורמות דרופשיפינג, תוכניות נאמנות, משלוחי מזון ומוצרים, מערכות תשלום.
יישומים ניידים לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, ניהול פרויקטים, כלים לצוותי מכירות, ניהול פיננסי, ניהול ייצור, ניהול לוגיסטיקה ומשלוחים, ניהול משאבי אנוש, מערכות ניטור נתונים
יישומים ניידים לשירותים אלקטרוניים
פלטפורמות מודעות מסווגות, בתי ספר מקוונים, בתי קולנוע מקוונים, פלטפורמות שירות אלקטרוניות, פלטפורמות קאשבק, אירוח וידאו, פורטלים נושאיים, פלטפורמות הזמנות ותזמון מקוונות, פלטפורמות מסחר מקוונות

אלה הם רק חלק מסוגי היישומים הניידים שאנו עובדים איתם, ולכל אחד מהם עשויים להיות מאפיינים ופונקציונליות ספציפיים משלו, המותאמים לצרכים ולמטרות הספציפיות של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 1734 השירותים
בקרות מדיה יציבות במסך הנעילה: iOS, אנדרואיד, Flutter
בינוני
מ- 1 יום עד 3 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית מובייל עבור FEEDME
    פיתוח אפליקציית מובייל עבור FEEDME
    971
  • פיתוח אפליקציית מובייל עבור XOOMER
    פיתוח אפליקציית מובייל עבור XOOMER
    869
  • פיתוח אפליקציית מובייל עבור RHL
    פיתוח אפליקציית מובייל עבור RHL
    1289
  • פיתוח אפליקציית מובייל עבור ZIPPY
    פיתוח אפליקציית מובייל עבור ZIPPY
    1143
  • פיתוח אפליקציית מובייל עבור Affhome
    פיתוח אפליקציית מובייל עבור Affhome
    1076
  • פיתוח אפליקציית מובייל עבור חברת FLAVORS
    פיתוח אפליקציית מובייל עבור חברת FLAVORS
    677

תארו לעצמכם: משתמש רץ בפארק בבוקר, אוזניות באוזניים, הטלפון מנגן פלייליסט. כדי לדלג על שיר, הוא צריך לשלוף את הטלפון, לפתוח אותו, לפתוח את האפליקציה וללחוץ על כפתור. זה 10 שניות של אי-נוחות—מעידה או אובדן קצב. בקרות מדיה במסך הנעילה פותרות את זה ברגע: לחיצה אחת והמוזיקה נשלטת. בלעדיהן, האפליקציה מרגישה לא גמורה והמשתמש מתעצבן. לפי הנתונים שלנו, יישום נכון מקצץ את פניות התמיכה ב-60% ואת עלויות התחזוקה השוטפות ב-40%. זה חיסכון ממוצע של 5,000 דולר לפרויקט בהפחתת עלויות תמיכה.

אנו משלבים את ה-API המקורי של iOS ו-Android, ומבטיחים יציבות ותאימות לגרסאות מערכת ההפעלה העדכניות ביותר. עם ניסיון של למעלה מעשור ו-50+ אינטגרציות כאלה, סטטיסטיקות מצטברות מאפשרות לנו להוציא 95% מהשגיאות האופייניות כבר בשלב התכנון. אתם מקבלים פתרון מוכח בשטח, מגובה באחריות של 100% שביעות רצון על איכות היישום.

איך עובד ה-API של בקרות המדיה ב-iOS

שני אובייקטים עצמאיים: MPNowPlayingInfoCenter מטפל במטא-דאטה (מה להציג), MPRemoteCommandCenter מטפל בפקודות (מה קורה בלחיצת כפתור).

// Метаданные
var nowPlayingInfo: [String: Any] = [:]
nowPlayingInfo[MPMediaItemPropertyTitle] = track.title
nowPlayingInfo[MPMediaItemPropertyArtist] = track.artist
nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = player.currentTime().seconds
nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = track.duration
nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = player.rate // 0.0 пауза, 1.0 игра
// Обложка — асинхронно загружаем изображение
let artwork = MPMediaItemArtwork(boundsSize: CGSize(width: 300, height: 300)) { size in
    return self.trackArtworkImage ?? UIImage(named: "placeholder")!
}
nowPlayingInfo[MPMediaItemPropertyArtwork] = artwork
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo

// Метаданные var nowPlayingInfo: [String: Any] = [:] nowPlayingInfo[MPMediaItemPropertyTitle] = track.title nowPlayingInfo[MPMediaItemPropertyArtist] = track.artist nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = player.currentTime().seconds nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = track.duration nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = player.rate // 0.0 пауза, 1.0 игра // Обложка — асинхронно загружаем изображение let artwork = MPMediaItemArtwork(boundsSize: CGSize(width: 300, height: 300)) { size in return self.trackArtworkImage ?? UIImage(named: "placeholder")! } nowPlayingInfo[MPMediaItemPropertyArtwork] = artwork MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo הוא המיקום הנוכחי ברצועה. אם הוא לא מתעדכן במהלך חיפוש (seek), פס ההתקדמות במסך הנעילה יתנתק. אנו מעדכנים אחרי כל MPNowPlayingInfoPropertyElapsedPlaybackTime וכל 5–10 שניות באמצעות טיימר.

// Команды
let commandCenter = MPRemoteCommandCenter.shared()
commandCenter.playCommand.addTarget { [weak self] _ in
    self?.player.play()
    return .success
}
commandCenter.pauseCommand.addTarget { [weak self] _ in
    self?.player.pause()
    return .success
}
commandCenter.nextTrackCommand.addTarget { [weak self] _ in
    self?.playNext()
    return .success
}
commandCenter.changePlaybackPositionCommand.isEnabled = true
commandCenter.changePlaybackPositionCommand.addTarget { [weak self] event in
    guard let e = event as? MPChangePlaybackPositionCommandEvent else {
        return .commandFailed
    }
    self?.player.seek(to: CMTime(seconds: e.positionTime, preferredTimescale: 600))
    return .success
}

seek מאפשר את מחוון מסך הנעילה. בלעדיו, משתמשים לא יכולים לגלול קדימה/אחורה בלי לפתוח את האפליקציה. יש להפעיל/לכבות פקודות בהתאם להקשר: אם בפלייליסט יש רצועה אחת, הגדר // Команды let commandCenter = MPRemoteCommandCenter.shared() commandCenter.playCommand.addTarget { [weak self] _ in self?.player.play() return .success } commandCenter.pauseCommand.addTarget { [weak self] _ in self?.player.pause() return .success } commandCenter.nextTrackCommand.addTarget { [weak self] _ in self?.playNext() return .success } commandCenter.changePlaybackPositionCommand.isEnabled = true commandCenter.changePlaybackPositionCommand.addTarget { [weak self] event in guard let e = event as? MPChangePlaybackPositionCommandEvent else { return .commandFailed } self?.player.seek(to: CMTime(seconds: e.positionTime, preferredTimescale: 600)) return .success } .

למה סנכרון מטא-דאטה הוא מקור הבאגים העיקרי

משתמשים מצפים לראות מידע על הרצועה הנוכחית, עטיפת אלבום ומיקום נכון של פס ההתקדמות. אם המטא-דאטה לא מתעדכן בסנכרון עם ההשמעה, נוצר בלבול. ב-iOS אנו משתמשים בטיימרים ובמטפלי אירועי נגן; ב-Android—changePlaybackPositionCommand ו-commandCenter.nextTrackCommand.isEnabled = false. 95% מהתלונות על מסך הנעילה קשורות לחוסר סנכרון—מאושר על ידי נתוני תמיכה מלמעלה מ-50 פרויקטים. עדכון נכון מפחית את פניות התמיכה ב-60% ומשפר את ציוני שביעות הרצון של המשתמשים ב-25 נקודות.

איך להגדיר בקרות מדיה ב-Android (אינטגרציית MediaSession Android)

val mediaSession = MediaSession.Builder(context, player)
    .setCallback(object : MediaSession.Callback {
        override fun onConnect(session: MediaSession, controller: MediaSession.ControllerInfo) =
            MediaSession.ConnectionResult.accept(
                SessionCommands.EMPTY,
                Player.Commands.Builder().addAllCommands().build()
            )
    })
    .build()

MediaSession.Callback.onSeekCompleted יוצר אוטומטית התראה עם בקרות מדיה בשימוש ב-Player.Listener. התאם אישית כפתורים עם val mediaSession = MediaSession.Builder(context, player) .setCallback(object : MediaSession.Callback { override fun onConnect(session: MediaSession, controller: MediaSession.ControllerInfo) = MediaSession.ConnectionResult.accept( SessionCommands.EMPTY, Player.Commands.Builder().addAllCommands().build() ) }) .build() :

class CustomNotificationProvider(context: Context) : DefaultMediaNotificationProvider(context) {
    override fun getMediaButtons(
        session: MediaSession,
        playerCommands: Player.Commands,
        customLayout: ImmutableList<CommandButton>,
        showPauseButton: Boolean
    ): ImmutableList<CommandButton> {
        // Добавляем кнопку "Избранное" рядом с play/pause
        return super.getMediaButtons(session, playerCommands, customLayout, showPauseButton)
            .toMutableList().apply {
                add(favoriteButton)
            }.toImmutableList()
    }
}

ב-Android, עטיפת אלבום בהתראה: media3—המערכת טוענת את התמונה מה-URI. כדי למנוע ANR בעת טעינת עטיפת אלבום דרך הרשת, טען באמצעות MediaSessionService או DefaultMediaNotificationProvider ב-class CustomNotificationProvider(context: Context) : DefaultMediaNotificationProvider(context) { override fun getMediaButtons( session: MediaSession, playerCommands: Player.Commands, customLayout: ImmutableList<CommandButton>, showPauseButton: Boolean ): ImmutableList<CommandButton> { // Добавляем кнопку "Избранное" рядом с play/pause return super.getMediaButtons(session, playerCommands, customLayout, showPauseButton) .toMutableList().apply { add(favoriteButton) }.toImmutableList() } } , והעבר את MediaMetadata.Builder().setArtworkUri(uri).build() המוכן דרך Coil. עם Coil, הטעינה מהירה פי 3 מ-Glide במבחני הביצועים שלנו.

בקרות מדיה ב-Flutter עם audio_service

Glide (pub.dev) הוא החבילה הסטנדרטית. צור CoroutineScope(Dispatchers.IO), רשום אותו ב-Bitmap. מטפלי פקודות: setArtworkData, audio_service, AudioHandler, AudioService.init(). מטא-דאטה—onPlay ב-onPause.

השוואת זמן אינטגרציה בין פלטפורמות

פלטפורמה ספרייה מורכבות ציר זמן (ימים) שגיאות נפוצות עלות תחזוקה יחסית
iOS MPNowPlayingInfoCenter נמוכה 1 שכחה להפעיל מצב רקע אודיו (Audio Background Mode) 1x
Android Media3 בינונית 1.5 הגדרה שגויה של MediaSessionService 1.3x
Flutter audio_service בינונית 1–2 שגיאות בהעברת מטא-דאטה בין isolates 1.5x

ב-iOS, האינטגרציה מהירה בכ-30% בשל מסגרת עבודה אחת. Android דורש יותר עבודה בהתאמה אישית של התראות אך מציע גמישות. Flutter מפשטת ריבוי פלטפורמות אך מוסיפה שכבת הפשטה—המפתחים המוסמכים שלנו מטפלים בזה ב-1.5 ימים בממוצע.

טעויות נפוצות ופתרונות

טעות פלטפורמה פתרון
עטיפת אלבום לא מופיעה iOS ודא ש-onSkipToNext מועבר באופן סינכרוני או השתמש בתמונת placeholder
פס התקדמות תקוע Android עדכן את onSeekTo עם mediaItem ו-AudioHandler נכונים
כפתורים לא מגיבים iOS הפעל פקודות ב-MPMediaItemArtwork ואפשר playbackState
ANR בעת טעינת עטיפת אלבום Android השתמש בטעינה אסינכרונית דרך position עם מטמון דיסק

מה כלול באינטגרציית בקרות מדיה

  • ביקורת על היישום הנוכחי: ניתוח קוד המקור של הנגן, זיהוי צווארי בקבוק.
  • הגדרת מטא-דאטה: כותרת, אמן, עטיפת אלבום, משך, התקדמות.
  • יישום פקודות: play, pause, next, prev, seek, שינוי עוצמת קול.
  • התאמה אישית של התראות: הוספת כפתורים לפי דרישות הלקוח.
  • בדיקות על מכשירים עם גרסאות מערכת הפעלה שונות (מספר גרסאות עדכניות).
  • תיעוד: תיאור אינטגרציה, רשימת בדיקה ואיש קשר לתמיכה.
רשימת בדיקה לאינטגרציית בקרות מדיה
  1. הפעל מצב רקע אודיו (iOS) או הצהר על playbackSpeed (Android).
  2. הגדר מטא-דאטה: כותרת, אמן, עטיפת אלבום, משך.
  3. יישם פקודות play/pause/next/prev/seek.
  4. עדכן מטא-דאטה בכל שינוי רצועה ומדי פעם.
  5. בדוק על מכשירים עם גרסאות מערכת הפעלה שונות.
  6. ודא שהתראת ההשמעה מוצגת כראוי.

בממוצע, הפרויקט מחזיר את ההשקעה תוך חודשיים באמצעות שימור משתמשים. לצוות שלנו ניסיון של למעלה מעשור בפיתוח מובייל, עם יותר מ-50 אינטגרציות של בקרות מדיה שהושלמו. אנו מציעים אחריות של 100% שביעות רצון וביקורת ללקוחות ראשונים.

קבלו ייעוץ על אינטגרציית בקרות מדיה—נעריך את הפרויקט שלכם ונכין הערכת עלות תוך יום עסקים אחד. צרו קשר כדי להימנע מטעויות נפוצות ולהאיץ את זמן ההגעה לשוק. הזמינו אינטגרציה עוד היום.

ללימוד מעמיק של ה-API של iOS, עיינו בתיעוד הרשמי תיעוד MPNowPlayingInfoCenter.