问题
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