Android Sip incoming Call using Service with Broadcast Receiver

 ̄綄美尐妖づ 提交于 2019-12-11 12:22:36

问题


Hai Every one Actually am trying to create an application which supports for making a audio call over the internet with SIP based,here am using native sip,and i was facing the problem with the incoming call,i have done the registration part with service,but while doing the incoming call i can not able to answer the call kindly please help me

Service file

package example.com.myapplication;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.net.sip.SipAudioCall;
import android.net.sip.SipException;
import android.net.sip.SipManager;
import android.net.sip.SipProfile;
import android.net.sip.SipRegistrationListener;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcelable;
import android.provider.Settings;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import java.text.ParseException;

import static android.content.Intent.FILL_IN_ACTION;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;

import example.com.myapplication.splash.SplashScreen;

public class MyService extends Service {
public static final int notifyID = 9001;
public IncomingReceiver callReceiver=new IncomingReceiver();
public SipProfile mSipProfile = null;
public SipProfile.Builder builder = null;
public SipAudioCall call = null;
public SipManager mSipManager = null;
public static SipManager sipManager2;
public String username,password,domain;
public String Status;
@Override
public IBinder onBind(Intent intent) {
    return null;
}

public void load()
{
    Context ctx = getApplicationContext();
    SharedPreferences   sharedPreferences=getSharedPreferences("Login",Context.MODE_PRIVATE);
   username= sharedPreferences.getString("username1","Error" );
    password= sharedPreferences.getString("password1","Error" );
    domain= sharedPreferences.getString("domain1","Error" );
}
@Override
public void onCreate()
{   super.onCreate();
    IntentFilter filter = new IntentFilter();
    filter.addAction("example.com.myapplication.INCOMING_CALL");
    callReceiver = new IncomingReceiver();
    this.registerReceiver(callReceiver, filter);
  if(mSipManager == null) {
       mSipManager = SipManager.newInstance(getApplicationContext());
   }

}
@Override
public int onStartCommand(Intent intent,int flags,int startId)
{
    load();
    Log.d("Username",username);
    Log.d("Password", password);
    Log.d("Domain",domain);
    Toast.makeText(getApplicationContext(), "Service Started", Toast.LENGTH_SHORT).show();
    try {
        builder = new SipProfile.Builder(username, domain);
        builder.setPassword(password);
        builder.setPort(5060);
        builder.setOutboundProxy("10.0.2.51");
        builder.setProtocol("UDP");
        builder.setAutoRegistration(true);
        builder.setSendKeepAlive(true);
        mSipProfile = builder.build();
        Intent intent1 = new Intent();
        intent1.setAction("example.com.myapplication.INCOMING_CALL");
        PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), 0, intent1, FILL_IN_ACTION);
        mSipManager.open(mSipProfile, pi, null);
        Toast.makeText(getApplication(),"listener Started",Toast.LENGTH_SHORT).show();
        mSipManager.setRegistrationListener(mSipProfile.getUriString(), new SipRegistrationListener() {

            @Override
            public void onRegistering(String localProfileUri) {
                Log.d("Trying", "Register");
            }

            @Override
            public void onRegistrationDone(String localProfileUri, long expiryTime) {
                Status = "done";
                sendNotification();
                sipManager2=mSipManager;
                Log.d("Manager",mSipManager.toString());
                Log.d("Success", "complete");
            }

            @Override
            public void onRegistrationFailed(String localProfileUri, int errorCode, String errorMessage) {
                Log.d("Failed", Integer.toString(errorCode));
                sendNotification1();
            }
        });
    } catch (SipException e) {
        e.printStackTrace();
        Toast.makeText(getApplication(),"SipListener failed",Toast.LENGTH_SHORT).show();
        Log.d("reg","error");
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return super.onStartCommand(intent,flags,startId);
}
public void onDestory()
{
    super.onDestroy();
    sipManager2=null;
    if (call != null) {
      call.close();
    }

   closeLocalProfile();

    if (callReceiver != null) {
        this.unregisterReceiver(callReceiver);
    }
}
public void closeLocalProfile() {
    if (mSipManager == null) {
        return;
    }
    try {
        if (mSipProfile != null) {
            mSipManager.close(mSipProfile.getUriString());
        }
    } catch (Exception ee) {
        Log.d("Sip Profile Error", ee.toString());
    }
}
private void sendNotification() {
    NotificationCompat.Builder mNotifyBuilder;
    NotificationManager mNotificationManager;
    mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    mNotifyBuilder = new NotificationCompat.Builder(this)
            .setContentTitle("Account is Ready")
            .setContentText("Registration Success")

            .setSmallIcon(R.drawable.success);
    mNotifyBuilder.setContentText("Ready");
    mNotificationManager.notify(notifyID, mNotifyBuilder.build());
}
private void sendNotification1() {

    NotificationCompat.Builder mNotifyBuilder;
    NotificationManager mNotificationManager;
    mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    mNotifyBuilder = new NotificationCompat.Builder(this)
            .setContentTitle("Account is Not Ready")
            .setContentText("Registration Failed")

            .setSmallIcon(R.drawable.failed);

    mNotifyBuilder.setContentText("Failed");
    mNotifyBuilder.setAutoCancel(true);
    mNotificationManager.notify(notifyID, mNotifyBuilder.build());
}
}

Here i have attached my broadcast Receiver file BroadCast Receiver File

package example.com.myapplication;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.sip.SipAudioCall;
import android.net.sip.SipException;
import android.net.sip.SipProfile;
import android.util.Log;

public class IncomingReceiver extends BroadcastReceiver {
public  SipAudioCall incomingCall=null;
@Override
public void onReceive(Context context, Intent intent) {

    try {
        SipAudioCall.Listener listener = new SipAudioCall.Listener() {
            @Override
            public void onRinging(SipAudioCall call, SipProfile caller) {
                try {
                    call.answerCall(30);
                    Log.d("Incoming", call.toString());
                    Log.d("Name",call.getPeerProfile().getProfileName());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //incomingCall=call;
            }
        };
      //  showIncomingCallGui(intent, context);
        incomeScreen wtActivity = (incomeScreen)context;
        incomingCall = wtActivity.mSipManager.takeAudioCall(intent, listener);
        wtActivity.call = incomingCall;
        Log.d("Manager", wtActivity.mSipManager.toString());
        if(incomingCall.isMuted()) {
            incomingCall.toggleMute();
        }
       showIncomingCallGui(intent,context);

    } catch (Exception e) {
        if (incomingCall != null) {
            incomingCall.close();
        }
    }
}
public void accept()
{
    Log.d("Receiver","Answer");
    try {
            incomingCall.answerCall(30);
            incomingCall.startAudio();
            incomingCall.setSpeakerMode(true);
    } catch (SipException e) {
        Log.d("Call Exception",e.toString());
        e.printStackTrace();
    }
    catch (Exception e)
    {
        Log.d("Exception",e.toString());
    }
}
public void showIncomingCallGui(Intent intent,Context context) {
    Intent incomingCall=new Intent(context,incomeScreen.class);
   incomingCall.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(incomingCall);
}
}

here i have attached my incoming screen source code incomingscreen

package example.com.myapplication;

import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.sip.SipAudioCall;
import android.net.sip.SipException;
import android.net.sip.SipManager;
import android.net.sip.SipProfile;
import android.net.sip.SipRegistrationListener;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.text.ParseException;

public class incomeScreen extends Activity {
public SipProfile mSipProfile = null;
public SipProfile.Builder builder = null;
public MyService service;
public SipAudioCall call = null;
public SipManager mSipManager;
public EditText username,password,domain;
public IncomingReceiver callReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_income_screen);
    //service=new MyService();
    mSipManager=MyService.sipManager2;
    IntentFilter filter = new IntentFilter();
    filter.addAction("example.com.myapplication.INCOMING_CALL");
    callReceiver = new IncomingReceiver();
    this.registerReceiver(callReceiver, filter);
    if(callReceiver!=null)
    {
        unregisterReceiver(callReceiver);
    }
    Button b1 = (Button) findViewById(R.id.Accept);

    b1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            callReceiver.accept();
            Log.d("ManagerSIp",mSipManager.toString());
        }
    });

}
}

Here comes my error log

02-15 12:01:03.334 3921-3921/example.com.myapplication D/Receiver: Answer
02-15 12:01:03.334 3921-3921/example.com.myapplication D/Exception:    java.lang.NullPointerException

kindly please help me to solve


回答1:


I'm late to the party but it may help others.

While I'm working on a similar problem, what I understand , background services need separate permissions as compared to permissions needed for foreground applications (activities) in Android.

If you have for a particular permission type in your Android Manifest, that is not sufficient to allow you to use the same code in a service. For example USES_SIP permission for me was giving error when i used the code for registering with a SIP server. The same code works fine from an activity.

For now I'm launching an activity to receive calls and register BroadcastReceiver from the activity , hence have the permissions granted.

Your NullPointerException is not very elaborate , but most probably its because of the permissions.

HTH




回答2:


When you write "native sip", do you mean the pre-packaged SIP that comes w/Android or a native SIP binary bundled w/your application and presumably built by you (such as PJSIP, Linphone, etc.)?

If it's the latter, you cannot do what you are doing through the Android API. You need to use your SIP stack's API.



来源:https://stackoverflow.com/questions/35402860/android-sip-incoming-call-using-service-with-broadcast-receiver

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!