Форум программистов, компьютерный форум 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. Просмотров 2427. Ответов 11
Метки нет (Все метки)

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

Добавлено через 9 минут
И ещё, если я теряю ссылку на MediaPlayer, который уже был запущен при помощи start() на воспроизведение и у GC дошли руки до него, остановится ли воспроизведение? Или только после конца воспроизведения GC его соберет?
(этот вопрос не относится к вопросу в шапке)
Wenceslaus
Android Developer
130 / 130 / 4
Регистрация: 05.07.2013
Сообщений: 205
22.08.2013, 15:59     Повторное воспроизведение музыки после кнопки home (media-player) #5
nexen, как стартуете и останавливаете MediaPlayer с музыкой? Как воспроизводите звуки?
Об GC: когда системе потребуется больше свободной памяти, воспроизведение будет остановлено и MediaPlayer со всеми ресурсами будет выгружен из неё. Но я не советую доводить до такого состояния.
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
22.08.2013, 16:14  [ТС]     Повторное воспроизведение музыки после кнопки home (media-player) #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'ом, а я то думал, почему звук внезапно перестает проигрываться Спасибо.
Wenceslaus
Android Developer
130 / 130 / 4
Регистрация: 05.07.2013
Сообщений: 205
22.08.2013, 19:02     Повторное воспроизведение музыки после кнопки home (media-player) #7
nexen, так и не увидел у вас пересоздания MediaPlayer'а. Не совсем понял зачем делать класс Audio абстрактным и статическим(!). В отдельном потоке вызов music.start(), а music.pause() вызывается из UI. Мне довольно сложно сказать конкретно, где узкое место (не вижу весь код и нет возможности его пощупать), но то, что меня смущало - я указал..
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
22.08.2013, 19:15  [ТС]     Повторное воспроизведение музыки после кнопки home (media-player) #8
Wenceslaus, пересоздания в данном случае нет. Как я и говорил, звуки продолжают работать даже при кнопке home, вот я и не пересоздаю их, но вот музыка перестает работать. Audio у меня в другом классе объявлена, поэтому static, от него наследуется music/sound-классы, поэтому и абстрактный.
Насчет разных потоков - я думал, что не имеет разницы, из какого потока вызываешь остановку или start(), ведь MediaPlayer.start() все равно создает новый поток, который не имеет ничего общего с тем потоком, который его породил.

Да остальной код и не нужен. Всё, что нужно было, я скинул. Кидать проект смысла нет, там много чего и разобраться сходу не выйдет.
Wenceslaus
Android Developer
130 / 130 / 4
Регистрация: 05.07.2013
Сообщений: 205
22.08.2013, 19:31     Повторное воспроизведение музыки после кнопки home (media-player) #9
nexen, что ж, всё, что предполагал, я уже сказал. Мыслей больше нет. Возможно кто-то из более опытных коллег заметит/знает то, чего не вижу/знаю я..
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
24.08.2013, 10:12  [ТС]     Повторное воспроизведение музыки после кнопки home (media-player) #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, даже не изменив его и все равно воспроизведение пошло!
Wenceslaus
Android Developer
130 / 130 / 4
Регистрация: 05.07.2013
Сообщений: 205
27.08.2013, 20:38     Повторное воспроизведение музыки после кнопки home (media-player) #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;
    }
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.08.2013, 10:46     Повторное воспроизведение музыки после кнопки home (media-player)
Еще ссылки по теме:
Сдвинуть аппаратные кнопки в Blue Stacks App Player Basic4Android
Как закрыть приложение при нажатии кнопки back или home? Basic4Android
Android Не удается остановить воспроизведение потока после закрытия и открытия приложения
Вывод изображения после нажатия кнопки Android
Кнопки удаляются после закрытия приложения Android

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

Или воспользуйтесь поиском по форуму:
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
28.08.2013, 10:46  [ТС]     Повторное воспроизведение музыки после кнопки home (media-player) #12
Wenceslaus, а причем тут ndk?
Кстати, если я запускаю/останавливаю музыку, в логе всегда Uri is null-ошибка (хотя звуки играют..), если только не использовать тот способ с setDataResource(), который и указывает uri.
Yandex
Объявления
28.08.2013, 10:46     Повторное воспроизведение музыки после кнопки home (media-player)
Ответ Создать тему
Опции темы

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