Подтвердить что ты не робот

Android Stop Background Music

РЕДАКТИРОВАТЬ - НАЙДИТЕ ЛЕГКОЕ РЕШЕНИЕ 5-10 ЛИНЕЙ!!! См. МОЙ СОБСТВЕННЫЙ ОТВЕТ НИЖЕ!!! YAY!!!!!!!!!

Я искал 5 часов, десятки сообщений SO, никаких ответов, и это кажется самой простой очевидной чертой!

EDIT- btw, это НЕ приложение для музыкального плеера, просто приложение для просмотра рисунков и текста, открывает несколько видов деятельности, таких как меню и около, просмотр типов типов изображений и т.д. Я просто хочу воспроизвести простую фоновую музыку, глядя через фото и текст, почему это так сложно?

другой EDIT - кажется, главный вопрос: "ПОЧЕМУ ПРЕКРАТИТЬ ДОМАШНУЮ КНОПКУ, НЕ ВЫЗЫВАЮТ onPause или onStop?" - Так я могу знать, когда остановить медиаплеер? и как игры, которые я скачиваю на рынок, выполняют это?

начало активной активности

затем

запускается медиаплеер:

player = MediaPlayer.create(this, R.raw.idil);
player.setLooping(true);
player.setVolume(100,100);
player.start();

Игрок, объявленный за пределами onCreate

MediaPlayer player;

Когда открываются другие действия, фоновая музыка продолжается непрерывно, а это ХОРОШО, это то, что я хочу.

Теперь, когда я закончил с помощью своего простого очень простого приложения (которое просто показывает некоторые фотографии и тексты в действиях diff), я либо несколько раз нажимаю BACK, чтобы перейти к домашнему/оригинальному действию, и затем еще один раз, чтобы "выйти" , ИЛИ, я просто нажимаю на дом, чтобы "выйти" , потому что im DONE с этим приложением, и мне больше не нужно слушать эту музыку.


ВАРИАНТ 1

Вызов player.stop(); в переопределении onPause, это не, что я хочу, потому что фоновая музыка останавливается, когда я покидаю домашнюю активность для других действий, таких как "меню" и "около", я также не нужно использовать паузу и возобновлять при открытии новых действий, потому что я не хочу, чтобы прекрасная фоновая музыка "пропускала" или прерывалась.


ВАРИАНТ 2

@Override
    protected void onPause() {
        super.onPause();
        if (this.isFinishing()){
            player.stop();
        }
    }

Это лучше, потому что фоновая музыка не останавливается между действиями, и когда я нажимаю BACK из моей домашней активности, музыка останавливается, и я могу продолжать наслаждаться моим телефоном с Android-телефоном в тишине и покое, , но проблема заключается в том, что при нажатии кнопки HOME для выхода из моего приложения эта пристойная фоновая музыка продолжает играть.


Как ни странно

@Override
protected void onStop() {
        super.onStop();
        if (this.isFinishing()){
            player.stop();
        }
    }

Делает то же самое, что и onPause (и я понимаю фактические различия)

РЕДАКТИРОВАТЬ - ТАКЖЕ, это не имеет значения, если player.stop(); выше или ниже super.onStop(); но это влияет на что-то, чего я не вижу, в любом случае, все еще нет РЕШЕНИЕ: (

OOOOO

OOOOO

ИЗМЕНИТЬ ДРУГОЙ ВАРИАНТ - НО НЕ РАБОТАЕТ

public void onUserLeaveHint() {
    player.stop();
    super.onUserLeaveHint();
}

это останавливает музыку, когда я нажимаю HOME, но также останавливает ее при запуске новых действий: (

РЕДАКТИРОВАТЬ - ОЧЕНЬ ОБЩАЯ РАБОТА ВОКРУГ IVE ВИДЕТЬ МНОЖЕСТВЕННЫЕ МЕСТА, но, похоже, нужно делать смешно:

важно следить за количеством открытых и закрытых действий (onResume и onPause будет лучше, но это не имеет значения), и когда этот счет достигнет 0, остановите фоновую музыку. ДА, это довольно просто, но почему я должен программно делать это, на самом деле БОЛЬШОЙ ВОПРОС ДЛЯ ЭТОГО ПОЧТА:

ПОЧЕМУ НАЖМИТЕ ГЛАВНУЮ КНОПКУ, НЕ ВЫЗЫВАЮЩУ ВПРАВО или onStop???

Чтобы включить его в onDestroy, это не вариант, потому что onDestroy вызывается только в том случае, когда система неактивна в памяти, или вы принудительно закрываете приложение, и это хорошо документировано.

Переопределение кнопки HOME также не является вариантом, поскольку я прочитал его "невозможно", и я прочитал его "чрезвычайно нахмуренный", в любом случае Im, избегая этого

Я не вижу необходимости создавать SERVICE, и даже если бы я это сделал, когда бы я остановил службу, похоже, у меня была бы такая же проблема.

СЕЙЧАС ЗДЕСЬ - это то, что полностью отравляет мой разум, каждая игра и каждое приложение, которое я загрузил с Android-рынка, имеет очень красивую фоновую музыку, и когда я нажимаю BACK или HOME, потому что я закончил играть в эту прекрасную игру , музыка останавливается, не сохраняя воспроизведение в фоновом режиме.

Я очень расстроен, и я чувствую это, потому что чувствую, что я пропустил что-то очень просто, потому что это одна из самых основных проблем жизненного цикла в любом приложении.

Я потратил месяц, читая каждую страницу developer.android.com, включая Руководство по Dev, учебные пособия, примеры проектов и исследование раздела Refernece, а также googleing этого раздела в течение 5 часов.

Я также не понимаю, почему 6 или 7 SO-потоков с темой точной, имеют небыло получено ответное сообщение, каждое загружаемое приложение на рынке перестает воспроизводить музыку (если только оно не является фоновым музыкальным проигрывателем), когда вы нажимаете HOME или BACK или что-то еще, чтобы "выйти" из приложения, чтобы сделать что-то еще на вашем телефоне.

Что мне не хватает?

4b9b3361

Ответ 1

Сегодня я очень рад, и у меня все еще есть волосы:) Я тестировал это, и он работает!!!

Сначала добавьте это в свой манифест:

<uses-permission android:name="android.permission.GET_TASKS"/>

Во-вторых, добавьте это в свою "главную/основную" активность/класс:

  @Override
  protected void onPause() {
    if (this.isFinishing()){ //basically BACK was pressed from this activity
      player.stop();
      Toast.makeText(xYourClassNamex.this, "YOU PRESSED BACK FROM YOUR 'HOME/MAIN' ACTIVITY", Toast.LENGTH_SHORT).show();
    }
    Context context = getApplicationContext();
    ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    List<RunningTaskInfo> taskInfo = am.getRunningTasks(1);
    if (!taskInfo.isEmpty()) {
      ComponentName topActivity = taskInfo.get(0).topActivity; 
      if (!topActivity.getPackageName().equals(context.getPackageName())) {
        player.stop();
        Toast.makeText(xYourClassNamex.this, "YOU LEFT YOUR APP", Toast.LENGTH_SHORT).show();
      }
      else {
        Toast.makeText(xYourClassNamex.this, "YOU SWITCHED ACTIVITIES WITHIN YOUR APP", Toast.LENGTH_SHORT).show();
      }
    }
    super.onPause();
  }

И, очевидно, замените xYourClassNamex, ну, ваше имя класса:)

Теперь, очевидно, вам не нужны "Тосты", но он расскажет вам, что происходит. Самое интересное, когда вы нажимаете BACK из своей "домашней/основной" деятельности, вы, очевидно, получаете 2 тоста, "ВЫ НАЖМИТЕ НАЗАД ИЗ ВАШЕЙ ДОМА/ОСНОВНОЙ ДЕЯТЕЛЬНОСТИ", а второй тост "ВЫ ПЕРЕКЛЮЧАЕТЕ ДЕЯТЕЛЬНОСТЬ В РАМКАХ ВАШЕГО ПРИЛОЖЕНИЯ". Кажется, я знаю, почему это происходит, но это не имеет значения, потому что я называю "player.stop()"; из двух сценариев, которые означают, что мое приложение больше не используется. Очевидно, сделать больше работы, чем "player.stop();" если вам нужно:) И также очевидно, что вам не нужно "else" для "ВЫ ПЕРЕКЛЮЧЕННЫЕ МЕРОПРИЯТИЯ В РАМКАХ ВАШЕГО ПРИЛОЖЕНИЯ", потому что нет оснований "останавливать/приостанавливать" фоновую музыку, и это то, что мне нужно, но если вы Нужно что-то делать, когда начинаются новые действия, ну вот вы:)

Надеюсь, это поможет любому, кто хочет знать, когда пользователь "уходит/выходит/завершается" с помощью приложения:)

СПАСИБО ЗА ВСЕ КОММЕНТАРИИ ПОСЛЕ И ПОМОЧЬ КАЖДОМУ!!! YAY!

ИЗМЕНИТЬ -

Эта часть должна быть в КАЖДОЙ деятельности onPause:

Context context = getApplicationContext();
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningTaskInfo> taskInfo = am.getRunningTasks(1);
        if (!taskInfo.isEmpty()) {
          ComponentName topActivity = taskInfo.get(0).topActivity; 
          if (!topActivity.getPackageName().equals(context.getPackageName())) {
            player.stop();
            Toast.makeText(xYourClassNamex.this, "YOU LEFT YOUR APP", Toast.LENGTH_SHORT).show();
          }
        }

чтобы вы узнали, покинул ли пользователь ваше приложение из ЛЮБОЙ из действий. это полезно знать:)

Ответ 2

Способ работы медиаплеера заключается в том, что его запуск как службы, а затем остановлен MANUALLY, когда пользователь останавливает его в самом приложении.

Пример:

Когда медиаплеер воспроизводит песню, а пользователь ударяет по дому, очевидно, что пользователь все еще хочет прослушать песню в качестве фоновой задачи. После того, как пользователь выполнит прослушивание, пользователь вручную остановит его, перейдя в приложение и остановив (Aka, останавливая службу, воспроизводящую песню), или если плейлист будет выполнен, а затем остановится. Простой.

Это ожидаемое поведение. И именно так работает приложение Music.

UPDATE

@Override
    protected void onPause() {
        super.onPause();
        if (this.isFinishing()){
            player.stop();
        }
    }

Необходимо изменить на

@Override
    protected void onPause() {
        super.onPause();
        if (mediaPlayer != null){
            mediaPlayser.stop();
            if (isFinishing()){
            mediaPlayer.stop();
            mediaPlayer.release();
            }
        }
    }

Объяснение:

Причина, по которой мы проверяем, что объект не является нулевым, очевиден. Однако; когда мы входим в паузу, мы хотим, чтобы медиаплеер останавливался. НО, если мы уйдем и песня будет почти закончена, а затем остановите ее и отпустите.

ОБНОВЛЕНИЕ 2

Посмотрите ссылку здесь:

fooobar.com/questions/235396/...

Это можно использовать для определения того, было ли ваше приложение перенесено из текущего наконечника стека приложений.

Ответ 3

У меня была такая же проблема. Я скажу вам свое решение. Я переопределил onStop, включил каждую активность и подсчитал начальную активность с некоторой задержкой, и количество отсчетов достигло нуля, я приостановил музыку.

Ответ 4

как это о un/register в качестве слушателя @службы в onStart() и onStop() методе ваших действий, и каждый раз, когда слушатель регистрируется (un), ваш сервис проверяет, осталось ли у некоторых слушателей в своем ArrayList<Listener>. если listOfListeners.size() 0, то ваш сервис вызывает свой метод stopSelf() и сам убивает.

по крайней мере, что я бы это сделал...

Итак, вам понадобятся следующие вещи:

  • 2 Интерфейсы (Observer, Observable)

  • реализовать Observer в Activity, Observable в Service

  • ArrayList<Observer> in Service

  • registerObserver(Observer o) и unregisterObserver(Observer o) в Service

но это только моя точка зрения...

Ответ 5

Почему бы вам просто не сделать кнопку, чтобы остановить музыку намного проще, и вам не нужно заставлять закрываться каждый раз

Button exit =(Button) findViewById(R.id.exit);

    exit.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v)
            {
                // TODO: Implement this method

                startActivity(new Intent("com.justme.worldexplorer.EXIT"));             
                finish();
                Music I'd.stop();}});}

Там вы идете, и поэтому ключевая аппаратная кнопка возвращается дозатором, если вы нажмете случайно

public boolean onKeyDown(int KeyCode,KeyEvent event){


    return false;
}

И что он настроил его в манифесте и запустил, если какие-либо проблемы дадут мне знать

Ответ 6

private static HashMap<String, Boolean> focus = new HashMap<String, Boolean>();

public static void check(Context context, boolean hasFocus)
{
    handler.removeMessages(0);
    focus.put(((Activity)context).getLocalClassName(), hasFocus);
    handler.sendEmptyMessageDelayed(0, 500);
}

public static void check(String classname, boolean hasFocus)
{
    handler.removeMessages(0);
    focus.put(classname, hasFocus);
    handler.sendEmptyMessageDelayed(0, 500);
}

private static Handler handler = new Handler()
{
    @Override
    public void handleMessage(Message msg)
    {
        Iterator<Boolean> it = focus.values().iterator();
        while(it.hasNext())
        {
            if(it.next())
                return;
        }
        pause();
        super.handleMessage(msg);
    }
};

это методы класса менеджера.

каждый вид реализации, как после кода

@Override
public void onWindowFocusChanged(boolean hasFocus)
{
    MusicManager.check(this, hasFocus);
    super.onWindowFocusChanged(hasFocus);
}

Я использую этот код с моей игрой, которая опубликована и отлично работает.

Какая часть этого кода ужасна? и где лучшее решение? Я хочу знать, существуют ли.

Майк, ты ответил мне, что мой ответ ужасен и не работает. Что случилось с этим?

Ответ 7

В каждом действии привязывайтесь к службе в onStart() и отвязывайтесь от службы в onStop(). При запуске службы связывайтесь только с ней и не вызывайте startService (...).

Вызывая startService(), служба будет продолжать работать до вызова stopService(), независимо от количества связанных с ней действий. Если вы не вызываете услугу "старт", служба автоматически остановится, как только все действия будут отключены от нее.

Таким образом, привязывая и отменяя каждый метод onStart() и onStop(), вы обнаружите, что служба (музыка) будет продолжаться до тех пор, пока вы не оставите свое приложение с помощью кнопки "домой", "назад", "тайм-аут экрана" и т.д.

Ответ 8

Для тех, кто все еще ищет решение в леденец или просто без использования прав, я придумал другое решение в качестве последнего ресурса. Мы можем измерить время, когда пользователь был afk. Если это было больше, чем X ms, то вы можете подумать, что он оставил приложение и остановил музыку.

Итак, я использую приложение child, где храню время afk и BaseActivity для переопределения onPause и onResume всех моих действий.

Ответ 9

Я столкнулся с той же проблемой с моим процессом разработки.

Я решил это, используя onPause и onResume и методы pause() и start() в проигрывателе, которые я сохранил в своем основном контейнере, вызывая фрагменты вместо действий.

Я держал флаг на синглете, чтобы узнать, когда пользователь отключил музыку.

Еще одна проблема, которую я обнаружил, заключается в том, что мое приложение (idk, если оно является частью сборки orroid или не работает) запускало метод onResume прямо до того, как он снова включил плеер, поэтому я запустил цикл while, чтобы получить плеер не как нулевой указатель, и он работает, потому что он работает в другом потоке, поэтому позволяет приложению запускать onResume без сбоев и музыку рядом с ним.

Я нахожу это лучше (меньший код для записи) и не разрешающий инвазивный;).