Hello. I try to implement the following: There is an activity where audio is played. I want one sign to appear on an incoming call to TextView , and when the call ends, there is another sign. Did so, but does not work:

MainActivity

 public class MainActivity extends AppCompatActivity { private String stream; private boolean isPlay; private ImageButton btnPLayPause; private TextView txtRadio; BandwidthMeter bandwidthMeter; TrackSelector trackSelector; SimpleExoPlayer player; private SimpleExoPlayerView simpleExoPlayerView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnPLayPause = (ImageButton) findViewById(R.id.btnPLayPause); txtRadio = (TextView) findViewById(R.id.txtRadio); stream = "http://193.242.149.55:8000/kfm"; bandwidthMeter = new DefaultBandwidthMeter(); TrackSelection.Factory streamSelectionFactory = new AdaptiveVideoTrackSelection.Factory(bandwidthMeter); trackSelector = new DefaultTrackSelector(streamSelectionFactory); player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, new DefaultLoadControl()); simpleExoPlayerView = new SimpleExoPlayerView(this); simpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.player_view); simpleExoPlayerView.setUseController(true); simpleExoPlayerView.requestFocus(); simpleExoPlayerView.setPlayer(player); Uri streamUri = Uri.parse(stream); DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "yourApplicationName"), bandwidthMeter); ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory(); MediaSource mediaSource = new ExtractorMediaSource(streamUri, dataSourceFactory, extractorsFactory, null, null); player.prepare(mediaSource); player.setPlayWhenReady(true); isPlay = true; if (player.getPlayWhenReady() == true) { btnPLayPause.setImageResource(R.drawable.icon_stop); } CallReceiver calls = new CallReceiver(); calls.onIncomingCallStarted(this, null, null); calls.onOutgoingCallStarted(this, null, null); calls.onIncomingCallEnded(this, null, null, null); calls.onOutgoingCallEnded(this, null, null, null); calls.onMissedCall(this, null, null); } @Override protected void onDestroy() { NotificationManager notifManager= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notifManager.cancelAll(); super.onDestroy(); player.release(); } public void onPlayPause(View view) { if (isPlay == true) { if (player.getPlayWhenReady() == true) { player.setPlayWhenReady(false); isPlay = false; btnPLayPause.setImageResource(R.drawable.icon_play); } } else if (isPlay == false) { if (player.getPlayWhenReady() == false) { player.setPlayWhenReady(true); isPlay = true; btnPLayPause.setImageResource(R.drawable.icon_stop); } } } public class CallReceiver extends PhonecallReceiver { @Override protected void onIncomingCallStarted(Context ctx, String number, Date start) { txtRadio.setText("Звонит 1!"); } @Override protected void onOutgoingCallStarted(Context ctx, String number, Date start) { txtRadio.setText("Звонит 2!"); } @Override protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end) { txtRadio.setText("Звонит 3!"); } @Override protected void onOutgoingCallEnded(Context ctx, String number, Date start, Date end) { txtRadio.setText("Звонит 4!"); } @Override protected void onMissedCall(Context ctx, String number, Date start) { txtRadio.setText("Звонит 5!"); } } } 

Class PhonecallReceiver

 public class PhonecallReceiver extends BroadcastReceiver { private static int lastState = TelephonyManager.CALL_STATE_IDLE; private static Date callStartTime; private static boolean isIncoming; private static String savedNumber; //because the passed incoming is only valid in ringing @Override public void onReceive(Context context, Intent intent) { //We listen to two intents. The new outgoing call only tells us of an outgoing call. We use it to get the number. 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; } onCallStateChanged(context, state, number); } } //Derived classes should override these to respond to specific events of interest protected void onIncomingCallStarted(Context ctx, String number, Date start){} protected void onOutgoingCallStarted(Context ctx, String number, Date start){} protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end){} protected void onOutgoingCallEnded(Context ctx, String number, Date start, Date end){} protected void onMissedCall(Context ctx, String number, Date start){} //Deals with actual events //Incoming call- goes from IDLE to RINGING when it rings, to OFFHOOK when it's answered, to IDLE when its hung up //Outgoing call- goes from IDLE to OFFHOOK when it dials out, to IDLE when hung up public void onCallStateChanged(Context context, int state, String number) { if(lastState == state){ //No change, debounce extras return; } switch (state) { case TelephonyManager.CALL_STATE_RINGING: isIncoming = true; callStartTime = new Date(); savedNumber = number; onIncomingCallStarted(context, number, callStartTime); break; case TelephonyManager.CALL_STATE_OFFHOOK: //Transition of ringing->offhook are pickups of incoming calls. Nothing done on them if(lastState != TelephonyManager.CALL_STATE_RINGING){ isIncoming = false; callStartTime = new Date(); onOutgoingCallStarted(context, savedNumber, callStartTime); } break; case TelephonyManager.CALL_STATE_IDLE: //Went to idle- this is the end of a call. What type depends on previous state(s) if(lastState == TelephonyManager.CALL_STATE_RINGING){ //Ring but no pickup- a miss onMissedCall(context, savedNumber, callStartTime); } else if(isIncoming){ onIncomingCallEnded(context, savedNumber, callStartTime, new Date()); } else{ onOutgoingCallEnded(context, savedNumber, callStartTime, new Date()); } break; } lastState = state; } } 
  • The call itself should be blocked or not (the call reception interface should appear) and should work only when activating with the player in the foreground or even if the application is closed? - pavlofff
  • Natalia, the code in your question is identical to the code from Mute the sound . How did this happen? Are you working on one project? - Nick Volynkin

1 answer 1

When there is no incoming call, “Not ringing” appears in the TextView callState ; when dialing, the message “Is ringing” appears, when resetting / ending the call, it is replaced by “Not ringing” again. The call receiving interface appears on the screen. It works only when activating in the foreground. If actions on the call must occur before the destruction of the activation (if it is, for example, in the background), then the code from onPause() must be transferred to onDestroy()

Work requires permission in the manifest:

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

code:

 public class MainActivity extends Activity { private TelephonyManager tm; TextView callState; CallStateListener callStateListener; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE); callStateListener = new CallStateListener(); tm.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE); callState = (TextView) findViewById(R.id.callState); } @Override protected void onPause() { super.onPause(); tm.listen(callStateListener, PhoneStateListener.LISTEN_NONE); } private class CallStateListener extends PhoneStateListener { @Override public void onCallStateChanged(int state, String incomingNumber) { switch (state) { case TelephonyManager.CALL_STATE_RINGING: callState.setText("Is Ringing"); break; case TelephonyManager.CALL_STATE_IDLE: callState.setText("Not ringing"); break; } } } } 
  • And how to make it work when activations are not in the foreground too? - user215435