The idea behind is to place a call and to listen to the phone state change to switch on the speaker when the call is established.
package com.danielthat.loudspeaker; import android.media.AudioManager; import android.net.Uri; import android.os.Bundle; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.view.View; import android.widget.Button; import android.widget.EditText; public class Loudspeaker extends Activity { Button mButton; EditText mEdit; TelephonyManager manager; StatePhoneReceiver myPhoneStateListener; boolean callFromApp=false; // To control the call has been made from the application boolean callFromOffHook=false; // To control the change to idle state is from the app call @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.layout_loudspeaker); //To be notified of changes of the phone state create an instance //of the TelephonyManager class and the StatePhoneReceiver class myPhoneStateListener = new StatePhoneReceiver(this); manager = ((TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE)); mEdit = (EditText)findViewById(R.id.editText1); mButton = (Button) findViewById(R.id.button1); mButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { String phoneNumber = mEdit.getText().toString(); manager.listen(myPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); // start listening to the phone changes callFromApp=true; Intent i = new Intent(android.content.Intent.ACTION_CALL, Uri.parse("tel:+" + phoneNumber)); // Make the call startActivity(i); } }); } // Monitor for changes to the state of the phone public class StatePhoneReceiver extends PhoneStateListener { Context context; public StatePhoneReceiver(Context context) { this.context = context; } @Override public void onCallStateChanged(int state, String incomingNumber) { super.onCallStateChanged(state, incomingNumber); switch (state) { case TelephonyManager.CALL_STATE_OFFHOOK: //Call is established if (callFromApp) { callFromApp=false; callFromOffHook=true; try { Thread.sleep(500); // Delay 0,5 seconds to handle better turning on loudspeaker } catch (InterruptedException e) { } //Activate loudspeaker AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); audioManager.setMode(AudioManager.MODE_IN_CALL); audioManager.setSpeakerphoneOn(true); } break; case TelephonyManager.CALL_STATE_IDLE: //Call is finished if (callFromOffHook) { callFromOffHook=false; AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); audioManager.setMode(AudioManager.MODE_NORMAL); //Deactivate loudspeaker manager.listen(myPhoneStateListener, // Remove listener PhoneStateListener.LISTEN_NONE); } break; } } } }
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.danielthat.loudspeaker" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.CALL_PHONE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.danielthat.loudspeaker.Loudspeaker" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".Loudspeaker" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Number to call with loudspeaker on:" /> <EditText android:id="@+id/editText1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView1" android:layout_below="@+id/textView1" android:ems="10" android:inputType="phone" /> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/editText1" android:layout_below="@+id/editText1" android:text="Call" /> </RelativeLayout>
Excellent post. Very helpful
ReplyDeleteđźđŤđŻđŞđšđŻđťđłđšđżđşđżđšđˇđ¸đˇđťđŽđšđąđšđťđ¸đŞđšđ°đ¨đđšđłđšđšđ¸đžđšđ˛đžđŞđşđŹđšđđťđŞđŹđŞđ´ó §ó ˘ó ˇó Źó łó ż I lost my job few months back and there was no way to get income for my family, things was so tough and I couldn’t get anything for my children, not until a met a recommendation on a page writing how Mr Bernie Wilfred Doran helped a lady in getting a huge amount of profit every 6 working days on trading with his management on the cryptocurrency Market, to be honest I never believe it at first but I took the risk to take a loan, and I contacted him unbelievable and I was so happy I earned 15,500.00 with an investment of $1500 within 7 days of investment , the most joy is that I can now take care of my family, i am just sharing my testimony. I don’t know how to appreciate your good work Mr. Bernie Doran God will continue to bless you for being a life saver I have no way to appreciate you than to tell people about your good services. For a perfect investment and good strategies contact Mr Bernie Doran via Gmail : Berniedoransignals@gmail.com
Deleteđšđźđ´ó §ó ˘ó łó Łó ´ó żđşđžđđšđđ¸đ¤đ️đđžđŹđźđŹđŠđŹđľđŽđ´đŹđşđđ°đłđşđ°đŹđŻđ´đŻđ˛đŽđŠ
Hello, your code works perfectly fine. I have implemented it in different manner, as I have given a custom button on my custom screen from where user can set Speaker phone On/Off. this also works fine. but the problem is, When the User sets the Speaker Off, the Speaker sound gets normal. but the Native Speaker button still shows the Speaker On. How ca I handle it. My Code for On is,
ReplyDeleteif(!audioManager.isSpeakerphoneOn()) {
audioManager.setSpeakerphoneOn(true);
}
And for Off is:
if(audioManager.isSpeakerphoneOn()) {
audioManager.setSpeakerphoneOn(false);
audioManager.setMode(AudioManager.MODE_NORMAL);
}
Please let me know any corrections i have to implement.
Hi Azharuddin,
DeleteI would say that when you are turning On the speaker you need do it as:
if(!audioManager.isSpeakerphoneOn()) {
audioManager.setMode(AudioManager.MODE_IN_CALL)
audioManager.setSpeakerphoneOn(true);
}
If you need further support, please send the complete code of your app to support@danielthat.com and I will take a deeper look.
Cheers,
Daniel
Hi Daniel! Thanks for your quick reply.
DeleteYes, I am already setting the mode as "AudioManager.MODE_IN_CALL", as per your sample above. My Issue is, When I do setSpeakerOn(true), the loudspeaker is activated and also the default caller Loudspeaker button is highlighted (denoting the action).
but when I call the setSpeakerOn(false), the loudspeaker is put to OFF but the default caller Loudspeaker button is still highlighted. How can I handle the default Speaker button to get Unhighlighted.
Hi again,
DeleteTheoretically, when you set up the loudspeaker off, the default buttion should get unhighlighted as well...
Please send me the code files and I will run it to see if I can sort out the problem.
Send the files to support@danielthat.com
Daniel
Ok, will send you. Please let me know If you found any Problem.
DeleteThanks & regards,
Azhar
Great post! This code worked perfectly util android 5.
ReplyDeleteDo you know how to enable speaker on Android 5 devices?
Looks like
audioManager.setMode(AudioManager.MODE_IN_CALL);
audioManager.setSpeakerphoneOn(true);
doesn't work.
I want to play audio during call can u help me???
ReplyDeleteThis comment has been removed by the author.
ReplyDeletepublic void speakerOn() {
ReplyDeleteAudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audioManager.setMode(AudioManager.MODE_IN_CALL);
audioManager.setSpeakerphoneOn(true);
}
public void speakerOff() {
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audioManager.setMode(AudioManager.MODE_NORMAL);
audioManager.setSpeakerphoneOn(false);
}
Not working for me. Please suggest the solution.
Hi,
ReplyDeleteif(!audioManager.isSpeakerphoneOn()){
audioManager.setMode(AudioManager.MODE_IN_CALL);
audioManager.setSpeakerphoneOn(true);
}
is not working on API 21 and above. Please help.
Thanks
Nice post.
ReplyDeleteWorks perfectly.
ReplyDeleteThanks.
This code working well till android Oreo. after that code execute without error. but speaker did not turn on. anyone idea please share how to turn speaker on.
ReplyDeleteI have an "activity_main.xml" file (which has nothing) and a "MainActivity..java" file. Below is the complete code of "MainActiviti.java"
ReplyDeletepackage com.example.phonecall;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_CALL = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_make_call);
makePhoneCall();
}
private void makePhoneCall() {
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audioManager.setMode(AudioManager.MODE_NORMAL);
audioManager.setSpeakerphoneOn(true);
String number="1234";
if (number.trim().length() >0) {
if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[] {Manifest.permission.CALL_PHONE}, REQUEST_CALL);
} else {
String dial ="tel:" + number;
startActivity(new Intent(Intent.ACTION_CALL, Uri.parse(dial)));
}
} else {
Toast.makeText(this, "Enter Phone Number", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int [] grantResults) {
if (requestCode ==REQUEST_CALL) {
if (grantResults.length > 0 && grantResults[0]==PackageManager.PERMISSION_GRANTED) {
makePhoneCall();
} else {
Toast.makeText(this, "Pemission DENIGNED",Toast.LENGTH_SHORT).show();
}
}
}
}
Before that I wrote in "Manifest.xml"
/