Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

Программирование Android

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 19, средняя оценка - 4.95
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
#1

Повторное воспроизведение музыки после кнопки home (media-player) - Программирование Android

20.08.2013, 20:41. Просмотров 2483. Ответов 11
Метки нет (Все метки)

Собственно, погуглил, и нашел, что у всех обратная проблема - "как остановить музыку, если нажата кнопка home". У меня такой проблемы нет, наоборот, музыка останавливается сама, но при возврате в приложение уже не воспроизводится (только музыка (setLoop(true)), со звуками всё впорядке). При попытке в методе onPause вызывать mediaPlayer.pause(), а в onResume mediaPlayer.start() - ничего.
Как же останавливать и продолжать MP корректно? Читал, что вроде как !обязательно! нужно делать stop(), release() даже при onPause(), но ведь тогда невозможно будет продолжить с момента, на котом пришел onPause(), да и заново подгружать музыку как-то..
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.08.2013, 20:41
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Повторное воспроизведение музыки после кнопки home (media-player) (Программирование Android):

Не работает приложение после нажатия кнопки home - Программирование Android
Добрый день, дорогие форумчане.:) Волнует такой вопрос - написала приложение под android(intelij idea), запускаю на девайсе. Всё...

IllegalStateException media player - Программирование Android
Делаю проигрователь. Запускаю, выбираю песню. Играет,все ок. Но потом нажимаю назад и выхожу из программы. Запускаю опять...И при выборе...

Воспроизведение музыки при выключенном звуке - Программирование Android
Как воспроизвести звук, если он выключен или стоит вибро? Т.е. как звук включить, воспроизвести нужный трек и выключить обратно

Завершення работи Media Player - Программирование Android
В об'єкті View є екземпляр Media Player, що працює в зацикленому режимі. mediaPlayer = MediaPlayer.create(context, R.raw.sound1); ...

Media player долго грузится поток - Программирование Android
Доброго времени суток. Написал небольшое приложение для прослушивания аудио потока. Но не нравится то, что после нажатия "Старт"...

Определить нажатие кнопки Home и кнопки сворачивания приложения - Программирование Android
По аналогии с backPressed: @Override public void onBackPressed() { }

11
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
22.08.2013, 12:00  [ТС] #2
who knows?
0
Wenceslaus
Android Developer
130 / 130 / 4
Регистрация: 05.07.2013
Сообщений: 205
22.08.2013, 12:35 #3
nexen, я всегда отталкиваюсь от позиции, что нажатие на кнопку Home равноценно выходу из приложения. Многие могут со мной не согласится (и частично они правы), но если мыслить именно так, то это сокращает некоторое количество проблем. Одна из них ваша. Я не совсем согласен, что в onPause() нужно вызывать release(), но в onStop() действительно обязательно. Я не знаю, что происходит у вас в коде, но одно из решений следующего характера: в onStop() сохранить адрес к текущему треку, сохранить текущее время воспроизведения и освободить память от MediaPlayer'а, а при старте Activity заново инициализировать MediaPlayer с сохранённым треком и перемотать до сохранённой позиции.
1
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
22.08.2013, 12:56  [ТС] #4
Wenceslaus, даже когда я делаю release() в onPause, а затем заново в onResume() пересоздаю mediaPlayer с нужным треком, используя id ресурса - всё равно нет звука. Но только у музыки. Все звуки как работали до паузы, так и работают (ведь их я не останавливаю и не пересоздаю, даже при home).

Добавлено через 9 минут
И ещё, если я теряю ссылку на MediaPlayer, который уже был запущен при помощи start() на воспроизведение и у GC дошли руки до него, остановится ли воспроизведение? Или только после конца воспроизведения GC его соберет?
(этот вопрос не относится к вопросу в шапке)
0
Wenceslaus
Android Developer
130 / 130 / 4
Регистрация: 05.07.2013
Сообщений: 205
22.08.2013, 15:59 #5
nexen, как стартуете и останавливаете MediaPlayer с музыкой? Как воспроизводите звуки?
Об GC: когда системе потребуется больше свободной памяти, воспроизведение будет остановлено и MediaPlayer со всеми ресурсами будет выгружен из неё. Но я не советую доводить до такого состояния.
1
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
22.08.2013, 16:14  [ТС] #6
Wenceslaus,
Общий_класс для_музыки_и_звука
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
static abstract class Audio implements IPlayable
    {
        public MediaPlayer mediaPlayer;
        public float volume = 0f;
        public int resourceId;
        
        public Audio()
        {
            
        }
        
        public Audio(int id)
        {
            resourceId = id;
            mediaPlayer = MediaPlayer.create(ZGame.context, id);
        }
        
        public Audio(Audio d)
        {
            resourceId = d.resourceId;
            mediaPlayer = MediaPlayer.create(ZGame.context, d.resourceId);
            volume = d.volume;
        }
        
        public void set(int id, int _volume)
        {
            resourceId = id;
            mediaPlayer = MediaPlayer.create(ZGame.context, id);
            volume = GetVolumeFloat(_volume);
        }
        
        public void setVolume(int _volume)
        {
            volume = GetVolumeFloat(_volume);
        }
        
        public boolean isPlaying()
        {
            return mediaPlayer.isPlaying();
        }
        
        @Override
        public void stop()
        {
            mediaPlayer.stop();
        }
 
        @Override
        public void resume() 
        {
            mediaPlayer.start();    
        }
 
        @Override
        public void pause() 
        {
            mediaPlayer.pause();
        }
    }

start()_музыки
Java
1
2
3
4
5
6
7
@Override
        public void start() 
        {
            mediaPlayer.setLooping(true);
            mediaPlayer.setVolume(volume, volume);
            mediaPlayer.start();
        }

start()_звука
Java
1
2
3
4
5
6
@Override
        public void start() 
        {
            mediaPlayer.setVolume(volume, volume);
            mediaPlayer.start();
        }

Звуки, как уже сказал, не останавливаю вообще. По истечению времени (MediaPlayer.isPlaying == false) просто Sound-объект устанавливаю в null. Даже release() не делаю.
С музыкой:
onResume()_onPause()_activity
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void onResume() 
    {
        level.map.sequencerData.music.resume();
        updateLock.release();
        Graphics.OnResume();
    }
 
    public void onPause() 
    {
        try 
        {
            level.map.sequencerData.music.pause();
            updateLock.acquire();
            Graphics.OnPause();
        } 
        catch (InterruptedException e) 
        {
            e.printStackTrace();
        }
    }

По факту, в onCreate() у меня ещё создается отдельный поток, в котором вызывается:
Java
1
level.map.sequencerData.music.start();
+ ещё и по onResume() вызывается Audio.resume(), который на самом деле вызывает MP.start() (был в шоке, когда увидел, что чтобы продолжить, надо тот же MP.start() вызывать), но, как я понял, это ничего плохого не делает, и MP.start() сам внутри проверяет isPlaying()-ли дорожка или нет

А по поводу второго моего вопроса.. Просто у меня уничтожался объект с MediaPlayer'ом, а я то думал, почему звук внезапно перестает проигрываться Спасибо.
0
Wenceslaus
Android Developer
130 / 130 / 4
Регистрация: 05.07.2013
Сообщений: 205
22.08.2013, 19:02 #7
nexen, так и не увидел у вас пересоздания MediaPlayer'а. Не совсем понял зачем делать класс Audio абстрактным и статическим(!). В отдельном потоке вызов music.start(), а music.pause() вызывается из UI. Мне довольно сложно сказать конкретно, где узкое место (не вижу весь код и нет возможности его пощупать), но то, что меня смущало - я указал..
1
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
22.08.2013, 19:15  [ТС] #8
Wenceslaus, пересоздания в данном случае нет. Как я и говорил, звуки продолжают работать даже при кнопке home, вот я и не пересоздаю их, но вот музыка перестает работать. Audio у меня в другом классе объявлена, поэтому static, от него наследуется music/sound-классы, поэтому и абстрактный.
Насчет разных потоков - я думал, что не имеет разницы, из какого потока вызываешь остановку или start(), ведь MediaPlayer.start() все равно создает новый поток, который не имеет ничего общего с тем потоком, который его породил.

Да остальной код и не нужен. Всё, что нужно было, я скинул. Кидать проект смысла нет, там много чего и разобраться сходу не выйдет.
0
Wenceslaus
Android Developer
130 / 130 / 4
Регистрация: 05.07.2013
Сообщений: 205
22.08.2013, 19:31 #9
nexen, что ж, всё, что предполагал, я уже сказал. Мыслей больше нет. Возможно кто-то из более опытных коллег заметит/знает то, чего не вижу/знаю я..
0
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
24.08.2013, 10:12  [ТС] #10
up-to-date?

Добавлено через 13 часов 16 минут
Wenceslaus, изначально создавал MediaPlayer из resourceId, но потом нашел ещё один метод, благодоря которому смог таки запустить снова воспроизведение музыки после выхода, но я не понимаю, зачем тогда при создании указывается id, если в реальности нужен Uri?
Java
1
2
mediaPlayer = MediaPlayer.create(ZGame.context, resourceId);
mediaPlayer.setDataSource(ZGame.context, Uri.parse("android.resource://your.package.name/" + resourceId));
Как же всё-таки правильно создавать MP-объект?
Более того, как вы видите в примере выше, я взял your.package.name, даже не изменив его и все равно воспроизведение пошло!
0
Wenceslaus
Android Developer
130 / 130 / 4
Регистрация: 05.07.2013
Сообщений: 205
27.08.2013, 20:38 #11
nexen, сначала думал, что всё дело в prepare(), но откровенно говоря странная ситуация. Лезть в дебри NDK пока желания нет, но я полагаю, что всё дело в native методах..
Для сравнения: исходники
MediaPlayer.create()
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    public static MediaPlayer create(Context context, int resid) {
        try {
            AssetFileDescriptor afd = context.getResources().openRawResourceFd(resid);
            if (afd == null) return null;
 
            MediaPlayer mp = new MediaPlayer();
            mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
            afd.close();
            mp.prepare();
            return mp;
        } catch (IOException ex) {
            Log.d(TAG, "create failed:", ex);
            // fall through
        } catch (IllegalArgumentException ex) {
            Log.d(TAG, "create failed:", ex);
           // fall through
        } catch (SecurityException ex) {
            Log.d(TAG, "create failed:", ex);
            // fall through
        }
        return null;
    }


MediaPlayer.setDataSource()
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
    public void setDataSource(Context context, Uri uri)
        throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
 
        String scheme = uri.getScheme();
        if(scheme == null || scheme.equals("file")) {
            setDataSource(uri.getPath());
            return;
        }
 
        AssetFileDescriptor fd = null;
        try {
            ContentResolver resolver = context.getContentResolver();
            fd = resolver.openAssetFileDescriptor(uri, "r");
            if (fd == null) {
                return;
            }
            // Note: using getDeclaredLength so that our behavior is the same
            // as previous versions when the content provider is returning
            // a full file.
            if (fd.getDeclaredLength() < 0) {
                setDataSource(fd.getFileDescriptor());
            } else {
                setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getDeclaredLength());
            }
            return;
        } catch (SecurityException ex) {
        } catch (IOException ex) {
        } finally {
            if (fd != null) {
                fd.close();
            }
        }
        Log.d(TAG, "Couldn't open file on client side, trying server side");
        setDataSource(uri.toString());
        return;
    }
1
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
28.08.2013, 10:46  [ТС] #12
Wenceslaus, а причем тут ndk?
Кстати, если я запускаю/останавливаю музыку, в логе всегда Uri is null-ошибка (хотя звуки играют..), если только не использовать тот способ с setDataResource(), который и указывает uri.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.08.2013, 10:46
Привет! Вот еще темы с ответами:

Переопределение кнопки Home - Программирование Android
Как переопределить кнопку HomeButton? assert getSupportActionBar() != null; action_bar = getSupportActionBar(); ...

Отловить нажатие кнопки Home - Программирование Android
Всем привет! Как отловить нажатие кнопки Home. В onKeyDown не получается.... Какие ещё варианты?

Воспроизведение музыки из интернета сразу после нажатия кнопки - Objective-C
Для воспроизведения песни в браузере использую GET запрос к сервису. Браузер, в частности гугл хром, начинает сразу её воспроизводить и...

Media Player Classic Home Cinema - Видеопрограммы
здравствуйте, с новым годом! пользуюсь плеером Media Player Classic Home Cinema. сразу отмечу плеер отличный, но захотелось настроить...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Yandex
Объявления
28.08.2013, 10:46
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru