Отключить громкость звонка во время разговора в андроиде

Моя цель - сообщить пользователю, кто звонит. Я использую TextToSpeech для этой задачи в службе.

Поэтому я решил отключить громкость звонка во время разговора:

  mAudioManager=(AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
            volume = mAudioManager.getStreamVolume(AudioManager.STREAM_RING);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                mAudioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_MUTE, 0);
            } else {
                mAudioManager.setStreamMute(AudioManager.STREAM_MUSIC, true);
            }

Я знаю, что это код для добавления, но где? Это класс, который расширяет широковещательный приемник?

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

Мой файл манифеста выглядит следующим образом:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sairaman63yahoo.callerannouncer">
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <receiver android:name=".CalReceiver">
        <intent-filter>
            <action android:name="android.intent.action.PHONE_STATE"/>
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
        </intent-filter>


    </receiver>
    <service android:name=".CallService" android:enabled="true"></service>

    <activity
        android:name=".DetectPhoneCallsActivity"
        android:label="@string/app_name"
        android:theme="@style/AppTheme.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest>

Мой класс PhoneCallReceiver, который расширяет широковещательный приемник:

public abstract class PhoneCallReceiverbase extends BroadcastReceiver {

private int mRingVolume=0;
public static int lastState= TelephonyManager.CALL_STATE_IDLE;
public  static Date callstartTime;
public static boolean isIncoming;
public static String savedNumber;
private static  AudioManager mAudioManager;
private int volume;

@Override
public void onReceive(Context context, Intent intent) {
    if(intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")){
        savedNumber=intent.getExtras().getString("android.intent.extra.PHONE_NUMBER");
    }
    else
    {
        String stateStr=intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
        String number=intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
        int state=0;
        if(stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE))
            state=TelephonyManager.CALL_STATE_IDLE;
        else if(stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK))
            state=TelephonyManager.CALL_STATE_OFFHOOK;
        else  if(stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
            state= TelephonyManager.CALL_STATE_RINGING;
            onCallStateChaned(context,state,number);

        }



    }
}

private void onCallStateChaned(Context context, int state, String number) {
    if(lastState==state){
        return;
    }

  //  mAudioManager.setStreamMute(AudioManager.STREAM_RING, true);

    switch (state){
        case TelephonyManager.CALL_STATE_RINGING:
      //  AudioManager manager=(AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
            isIncoming = true;
          callstartTime = new Date();
          savedNumber = number;
          onIncomingCallReceived(context, number, callstartTime);
            break;
        case TelephonyManager.CALL_STATE_OFFHOOK:
            //offhook are pickup calls....nothing is done on them
            if(lastState!=TelephonyManager.CALL_STATE_RINGING)
            {
                isIncoming=false;
                callstartTime=new Date();
                onOutGoingCallStarted(context,number,callstartTime);

            }
            else
            {
                isIncoming=true;
                callstartTime=new Date();
                onIncomingCallAnswered(context,number,callstartTime);

            }
            break;
        case TelephonyManager.CALL_STATE_IDLE:
            if(lastState==TelephonyManager.CALL_STATE_RINGING){
                onMissedCall(context,number,callstartTime);
            }
            else if(isIncoming)
                onIncomingCallEnded(context,number,callstartTime,new Date());
            else
                onOutGoingCallEnded(context,number,callstartTime,new Date());
            break;
    }
    lastState=state;

}

protected abstract void onIncomingCallReceived(Context context,String number,Date start);
protected abstract void onIncomingCallAnswered(Context context,String number,Date start);
protected abstract void onIncomingCallEnded(Context context,String number,Date start,Date end);
protected abstract void onOutGoingCallStarted(Context context,String number,Date start);
protected abstract void onOutGoingCallEnded(Context context,String number,Date start,Date end);
protected abstract void onMissedCall(Context context,String number,Date start);
}

Мой класс CallReceiver, который расширяет класс PhoneCallReceiver:

public class CalReceiver extends PhoneCallReceiverbase {

TextToSpeech toSpeech;
private AudioManager mAudioManager;
private int volume;


@Override
protected void onIncomingCallReceived(Context context, String number, Date start) {

    mAudioManager=(AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
    volume = mAudioManager.getStreamVolume(AudioManager.STREAM_RING);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        mAudioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_MUTE, 0);
    } else {
        mAudioManager.setStreamMute(AudioManager.STREAM_MUSIC, true);
    }
    Intent intent1 = new Intent(context.getApplicationContext(), CallService.class);
    intent1.putExtra("call", "CALL RECEIVED");
    context.startService(intent1);

   // Toast.makeText(context, "CALL RECIEVED", Toast.LENGTH_LONG).show();


    final ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
    final List<ActivityManager.RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);

    for (ActivityManager.RunningServiceInfo runningServiceInfo : services) {
        if (runningServiceInfo.service.getClassName().equals(CallService.class)) {
            Log.v("SERVICE", "RUNNING");

        }
    }
}



@Override
protected void onIncomingCallAnswered(Context context, String number, Date start) {

}

@Override
protected void onIncomingCallEnded(Context context, String number, Date start, Date end) {
    Toast.makeText(context,"CALL ENDED",Toast.LENGTH_LONG).show();

}

@Override
protected void onOutGoingCallStarted(Context context, String number, Date start) {
    Toast.makeText(context,"CALL STARTED",Toast.LENGTH_LONG).show();




}

@Override
protected void onOutGoingCallEnded(Context context, String number, Date start, Date end) {
    Toast.makeText(context,"CALL ENDED",Toast.LENGTH_LONG).show();
}

@Override
protected void onMissedCall(Context context, String number, Date start) {
    Toast.makeText(context,"MISSED CALL",Toast.LENGTH_LONG).show();
}
}

Наконец, мой класс обслуживания, который что-то говорит:

public class CallService extends Service implements TextToSpeech.OnInitListener,TextToSpeech.OnUtteranceCompletedListener {

int volume=0;
private TextToSpeech tts;
private String spoken="call started sir!";
private AudioManager mAudioManager;

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onCreate() {
    tts=new TextToSpeech(this,this);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    spoken=(String)intent.getExtras().get("call");
    return super.onStartCommand(intent, flags, startId);
}

@Override
public void onInit(int status) {
if(status==TextToSpeech.SUCCESS)
{
    // mAudioManager.setStreamMute(AudioManager.STREAM_RING, true);
    tts.setLanguage(Locale.ENGLISH);
    //   toSpeech.speak("CALL IS COMING",TextToSpeech.QUEUE_FLUSH,null);
    if (Build.VERSION.RELEASE.startsWith("5")) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            tts.speak(spoken, TextToSpeech.QUEUE_FLUSH, null, null);
        }
    }
    else {
        tts.speak(spoken, TextToSpeech.QUEUE_FLUSH, null);
    }
}
}

@Override
public void onUtteranceCompleted(String utteranceId){
mAudioManager.setStreamMute(AudioManager.STREAM_RING, false);
mAudioManager.setStreamVolume(AudioManager.STREAM_RING,
volume, AudioManager.FLAG_ALLOW_RINGER_MODES);
    stopSelf();
}
}

Резюмируя запрос:

Цель: отключить громкость звонка во время вызова и заставить объект TextToSpeech говорить что-то и продолжать громкость звонка после речи.

Проблема: 1) Где добавить код, который отключает громкость звонка 2) Я добавил код в класс CallReceiver, в onIncomingCallReceived(), но, похоже, он не работает. Мелодия звонка не останавливается

Пожалуйста помоги!

Я знаю, что это длинный вопрос, но я застрял здесь. Спасибо за помощь!


person Sai Raman Kilambi    schedule 14.06.2016    source источник
comment
Насколько мне известно, вы можете только остановить воспроизведение рингтона, но не приостановить его — как только вы остановите его, вы не сможете снова запустить его.   -  person brandall    schedule 14.06.2016
comment
Итак, как мне остановить это?   -  person Sai Raman Kilambi    schedule 14.06.2016


Ответы (1)


Как я уже сказал в своем комментарии, я не смог найти способ, которым мое приложение может делать то, что вы хотите. Я мог только отключить текущую мелодию звонка и не смог ее запустить, за исключением репликации мелодии звонка пользователя после того, как TTS объявил о вызове, и отслеживания их дальнейшего взаимодействия с ожидающим вызовом, что сложно.

Сделать это:

public static void muteRinger(final Context ctx, final boolean mute) {

    final AudioManager am = (AudioManager) ctx.getSystemService(Context.AUDIO_SERVICE);

    switch (am.getRingerMode()) {

        case AudioManager.RINGER_MODE_NORMAL:
            Log.i("TAG", "getRingerMode: RINGER_MODE_NORMAL");
            break;
        case AudioManager.RINGER_MODE_SILENT:
            Log.i("TAG", "getRingerMode: RINGER_MODE_NORMAL");
            break;
        case AudioManager.RINGER_MODE_VIBRATE:
            Log.i("TAG", "getRingerMode: RINGER_MODE_NORMAL");
            break;
        default:
            Log.e("TAG", "getRingerMode: Default??");
            break;
    }


    if(mute){
        Log.i("TAG", "muting ringtone");

    // Save am.getRingerMode() to the shared preferences as the user's default            

        try {
            am.setRingerMode(AudioManager.RINGER_MODE_SILENT);
        } catch (Exception e) {
            e.printStackTrace();
        }

    } else {
        Log.i("TAG", "restoring ringtone");

        try {
            am.setRingerMode(// The default you previously saved);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

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

person brandall    schedule 14.06.2016
comment
Изменено положение, в котором вы сохраняете значение по умолчанию. - person brandall; 14.06.2016