#android #service #android-mediaplayer #android-audiomanager
#Android #Обслуживание #android-медиаплеер #android-audiomanager
Вопрос:
привет, я новичок в Android и создаю простое приложение для онлайн-радио для моей церкви проблема в том, что мне нужно, чтобы служба воспроизведения останавливалась и перезапускалась, когда на телефон поступает звонок, и завершала его. пока я могу остановить службу просто отлично, но когда она снова запускается, просто вылетает, поэтому я не знаю, чтоя делаю неправильно
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.content.res.Resources;
import android.os.IBinder;
import android.os.PowerManager.WakeLock;
import android.support.v4.app.NotificationCompat;
import com.spoledge.aacdecoder.MultiPlayer;
public class RadioService extends Service{
WakeLock wakelock;
//TelephonyManager teleManager= null;
//PhoneStateListener listener;
NotificationManager mNotificationManager;
public static MultiPlayer aacPlayer;
public static String radio;
private static Boolean isTuning;
// private TeleListener myListener = null;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate(){
super.onCreate();
setTuning(false);
setRadio(getString(R.string.rhema));
aacPlayer = new MultiPlayer();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId){
setTuning(true);
setTuning(true);
aacPlayer.playAsync(radio);
//CallReceiver.setTuning(true);
Resources r= getResources();
String[] Notify = r.getStringArray(R.array.PlayNotify);
// prepare intent which is triggered if the
// notification is selected
Intent inten = new Intent(this, PlayerActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, inten, 0);
// build notification
// the addAction re-use the same intent to keep the example short
NotificationCompat.Builder n = new NotificationCompat.Builder(this)
.setContentTitle(Notify[0])
.setContentText(Notify[1])
.setSmallIcon(R.drawable.noti_icon)
.setContentIntent(pIntent)
.setAutoCancel(true)
.setOngoing(true)
.setContentIntent(pIntent);
Notification hola = n.build();
startForeground(100, hola);
//startForeground(startId, notification);
return START_STICKY;
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
pause();
//CallReceiver.setTuning(false);
super.onDestroy();
}
public static boolean getTuning() {
return isTuning;
}
public void setTuning(boolean Tuning) {
isTuning = Tuning;
}
public void setRadio(String r){
radio = r;
}
public void PlayNotify(){
Resources r= getResources();
String[] Notify = r.getStringArray(R.array.PlayNotify);
// prepare intent which is triggered if the
// notification is selected
Intent intent = new Intent(this, RadioService.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
// build notification
// the addAction re-use the same intent to keep the example short
NotificationCompat.Builder n = new NotificationCompat.Builder(this)
.setContentTitle(Notify[0])
.setContentText(Notify[1])
.setSmallIcon(R.drawable.noti_icon)
.setContentIntent(pIntent)
.setAutoCancel(true);
n.setOngoing(true);
n.setContentIntent(pIntent);
//NotificationManager mNotificationManager =(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(100, n.build());
}
public static void play(){
aacPlayer.playAsync(radio);
}
public static void pause(){
aacPlayer.stop();
}
}
и это трансляция
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
public class CallReceiver extends BroadcastReceiver{
TelephonyManager telManager;
Context context;
public static boolean Tuning = false;
PlayerActivity mainActivity;
NotificationManager mNotificationManager;
@Override
public void onReceive(Context context, Intent intent) {
mainActivity=new PlayerActivity();
this.context=context;
telManager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
telManager.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
}
private final PhoneStateListener phoneListener = new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
try {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING: {
//PAUSE
if(Tuning){
context.stopService(new Intent(context,RadioService.class));
}
break;
}
case TelephonyManager.CALL_STATE_OFFHOOK: {
if(Tuning){
context.stopService(new Intent(context,RadioService.class));
}
break;
}
case TelephonyManager.CALL_STATE_IDLE: {
//PLAY
if(Tuning){
showNotification(context);
context.stopService(new Intent(context,RadioService.class));}
break;
}
default: { }
}
} catch (Exception ex) {
}
}
};
public static void setTuning(boolean r){
Tuning = r;
}
private void showNotification(Context context) {
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, PlayerActivity.class), 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.noti_icon)
.setContentTitle("Rhema Stereo")
.setContentText("Vuelve a Sintonizarnos.");
mBuilder.setContentIntent(contentIntent);
mBuilder.setDefaults(Notification.DEFAULT_SOUND);
mBuilder.setAutoCancel(true);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder.build());}
}
проблема в том, что из действий я могу запускать и останавливать службу просто отлично, но здесь я могу только остановить ее. Итак, на данный момент я использую уведомление, чтобы вернуться к действию и перезапустить сервис
Комментарии:
1. я думаю, вам нужно добавить код для запуска сервиса в TelephonyManager.CALL_STATE_IDLE случай
Ответ №1:
Если позволите, я бы предложил другой подход к этой проблеме. Вы заявляете, что:
мне нужно, чтобы служба воспроизведения останавливалась и перезапускалась, когда на телефон поступает вызов
Однако проблема более сложная. Вы также должны остановить воспроизведение, например, при поступлении уведомления или при запуске пользователем другого музыкального проигрывателя. Вместо того, чтобы отслеживать все эти возможности независимо, Android предоставляет встроенную поддержку этой концепции — она называется audio focus. В широком смысле это означает, что только одно приложение может фокусироваться на звуке в один момент времени, и вы должны отказаться, если оно попросит.
Такое поведение может быть получено с помощью OnAudioFocusChangeListener
.
В принципе, вы должны:
- Перед началом воспроизведения запросите фокусировку звука.
- Начинайте воспроизведение только в том случае, если вы его эффективно получили.
- Отключите фокус при остановке воспроизведения.
- Обработайте потерю фокуса звука (либо уменьшив громкость, либо полностью остановив воспроизведение).
Пожалуйста, ознакомьтесь со статьей «Управление аудиофокусом» в документации Android.
Комментарии:
1. Спасибо! Это было именно то, что мне было нужно, оно работает безупречно
2. @user3739754 Я рад! Не забудьте принять ответ, если он показался вам полезным 🙂
Ответ №2:
вам необходимо добавить этот фрагмент в ваше текущее действие
IntentFilter receiverFilter = new IntentFilter(
Intent.ACTION_HEADSET_PLUG);
BootBroadcast receiver = new BootBroadcast();
registerReceiver(receiver, receiverFilter);
затем то же самое нужно зарегистрировать в приемнике manifest.xml
например:
<receiver
android:name="YOUR_ACTION_STRING.BootCompletedReceiver"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Также добавьте этот флаг в класс BootBroadcast
newIntent .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);