CallActivity
public class CallingActivity extends AppCompatActivity {
ImageButton btnSpeaker, btnMute, btnAnswer, btnReject, btnEnd;
TextView statusTv;
LinearLayout vIncomingCall, v_CallControl;
private StringeeCall call;
private boolean isIncomingCall = false;
private String to;
private String callId;
StringeeCall.SignalingState mSignalingState;
StringeeCall.MediaState mMediaState;
StringeeAudioManager audioManager;
boolean isSpeaker = false;
boolean isMicOn = true;
@SuppressLint("MissingInflatedId")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calling);
//init
btnEnd = findViewById(R.id.btnEnd);
vIncomingCall = findViewById(R.id.vIncomingCall);
btnSpeaker = findViewById(R.id.btnSpeaker);
btnMute = findViewById(R.id.btnMute);
btnAnswer = findViewById(R.id.btnAnswer);
btnReject = findViewById(R.id.btnReject);
statusTv = findViewById(R.id.statusTv);
v_CallControl = findViewById(R.id.v_CallControl);
if(getIntent() != null){
callId = getIntent().getStringExtra("callId");
to = getIntent().getStringExtra("to");
System.out.println("to: " + to);
isIncomingCall = getIntent().getBooleanExtra("isIncomingCall", false);
}
vIncomingCall.setVisibility(isIncomingCall ? View.VISIBLE : View.GONE);
btnEnd.setVisibility(isIncomingCall ? View.GONE : View.VISIBLE);
addEvent();
}
private void addEvent() {
btnSpeaker.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
runOnUiThread(() ->{
if(audioManager != null){
audioManager.setSpeakerphoneOn(!isSpeaker);
isSpeaker = !isSpeaker;
btnSpeaker.setBackgroundResource(isSpeaker ? R.drawable.speaker : R.drawable.mutespeaker);
}
});
}
});
btnAnswer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
runOnUiThread(()->{
if(call != null){
call.answer(new StatusListener() {
@Override
public void onSuccess() {
}
});
vIncomingCall.setVisibility(View.GONE);
btnEnd.setVisibility(View.VISIBLE);
}
});
}
});
btnMute.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
runOnUiThread(() ->{
if(call != null){
call.mute(!isMicOn);
isMicOn = !isMicOn;
btnMute.setBackgroundResource(isMicOn ? R.drawable.unmute : R.drawable.mute);
}
});
}
});
btnEnd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(call != null){
call.hangup(new StatusListener() {
@Override
public void onSuccess() {
}
});
audioManager.stop();
finish();
}
}
});
btnReject.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
runOnUiThread(()->{
if(call != null){
call.reject(new StatusListener() {
@Override
public void onSuccess() {
}
});
audioManager.stop();
finish();
}
});
}
});
List<String> permissions = new ArrayList<>();
if(ContextCompat.checkSelfPermission(this, android.Manifest.permission.RECORD_AUDIO) != PERMISSION_GRANTED){
permissions.add(android.Manifest.permission.RECORD_AUDIO);
}
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_CONNECT) != PERMISSION_GRANTED) {
permissions.add(Manifest.permission.BLUETOOTH_CONNECT);
}
}if(permissions.size() > 0) {
String[] permissionArray = new String[permissions.size()];
for (int i = 0; i < permissions.size(); i++) {
permissionArray[i] = permissions.get(i);
}
ActivityCompat.requestPermissions(this, permissionArray, 0);
return;
}
initCall();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
boolean isGranted = true;
if(grantResults.length > 0) {
for (int grantResult : grantResults) {
if (grantResult != PERMISSION_GRANTED) {
isGranted = false;
break;
}else{
isGranted = true;
}
}
}
if(requestCode == 0){
if(!isGranted){
finish();
}else{
initCall();
}
}
}
private void initCall() {
if(isIncomingCall) {
call = ChatActivity.callMap.get(callId);
if(call == null){
finish();
return;
}
}else{
call = new StringeeCall(ChatActivity.client , ChatActivity.client.getUserId(), to);
}
call.setCallListener(new StringeeCall.StringeeCallListener() {
@Override
public void onSignalingStateChange(StringeeCall stringeeCall, StringeeCall.SignalingState signalingState, String s, int i, String s1) {
runOnUiThread(() ->{
mSignalingState = signalingState;
switch (signalingState){
case CALLING:
statusTv.setText("Calling...");
break;
case RINGING:
statusTv.setText("Ringing...");
break;
case ANSWERED:
statusTv.setText("Answered");
if(mMediaState == StringeeCall.MediaState.CONNECTED){
statusTv.setText("Connected");
}
break;
case BUSY:
statusTv.setText("Busy");
audioManager.stop();
finish();
break;
case ENDED:
statusTv.setText("Ended");
audioManager.stop();
finish();
break;
}
});
}
@Override
public void onError(StringeeCall stringeeCall, int i, String s) {
runOnUiThread(()->{
finish();
audioManager.stop();
});
}
@Override
public void onHandledOnAnotherDevice(StringeeCall stringeeCall, StringeeCall.SignalingState signalingState, String s) {
}
@Override
public void onMediaStateChange(StringeeCall stringeeCall, StringeeCall.MediaState mediaState) {
runOnUiThread(()->{
mMediaState = mediaState;
if(mediaState == StringeeCall.MediaState.CONNECTED){
if(mSignalingState == StringeeCall.SignalingState.ANSWERED) {
statusTv.setText("Connected");
}
}else{
statusTv.setText("Connecting...");
}
});
}
@Override
public void onLocalStream(StringeeCall stringeeCall) {
}
@Override
public void onRemoteStream(StringeeCall stringeeCall) {
}
@Override
public void onCallInfo(StringeeCall stringeeCall, JSONObject jsonObject) {
}
});
audioManager = new StringeeAudioManager(this);
audioManager.start((audioDevice, set) -> {
});
audioManager.setSpeakerphoneOn(false);
if(isIncomingCall) {
call.ringing(new StatusListener() {
@Override
public void onSuccess() {
}
});
}else{
call.makeCall(new StatusListener() {
@Override
public void onSuccess() {
}
});
}
}
}
Here is my layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".CallingActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
<TextView
android:id="@+id/statusTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:gravity="center"
android:text="Calling"
android:textColor="@color/black"
android:textSize="30sp">
</TextView>
</LinearLayout>
<LinearLayout
android:id="@+id/v_CallControl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginTop="80dp"
android:layout_alignParentBottom="true"
android:gravity="center"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center"
android:gravity="center">
<ImageButton
android:id="@+id/btnSpeaker"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginRight="80dp"
android:src="@drawable/speaker"
android:scaleType="fitXY">
</ImageButton>
<ImageButton
android:id="@+id/btnMute"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginLeft="80dp"
android:src="@drawable/mute"
android:scaleType="fitXY">
</ImageButton>
</LinearLayout>
<LinearLayout
android:id="@+id/vIncomingCall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:orientation="horizontal">
<ImageButton
android:id="@+id/btnAnswer"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginRight="40dp"
android:src="@drawable/accept"
android:scaleType="fitXY">
</ImageButton>
<ImageButton
android:id="@+id/btnReject"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginLeft="40dp"
android:src="@drawable/end"
android:scaleType="fitXY">
</ImageButton>
</LinearLayout>
<ImageButton
android:id="@+id/btnEnd"
android:layout_width="50dp"
android:layout_height="50dp"
android:scaleType="fitXY"
android:layout_marginBottom="20dp"
android:src="@drawable/end">
</ImageButton>
</LinearLayout>
</RelativeLayout>
I am initializing a screen to make calls between users but there is a null error always appearing every time i run on my device, my device runs on android 9, but when i run on virtual machine of Andorid Studio Andorid 14, they run normally and do not report this null error
I tried debugging and got the message that vIncomingCall and btnEnd were accessed before being initialized even though I had already initialized them in the OnCreate function.
Koconut is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.