Android使用带有广播接收器的服务来消息来电

时间:2016-02-15 06:32:17

标签: android sip android-broadcast android-broadcastreceiver

Hai每个人实际上我正在尝试创建一个支持通过基于SIP的互联网进行音频呼叫的应用程序,这里使用原生sip,我正面临来电问题,我已完成注册部分有服务,但在打电话时我无法接听电话,请帮帮我

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());
}
}

这里我附上了广播的Receiver文件     BroadCast接收器文件

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);
}
}

这里我附上了我的传入屏幕源代码     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());
        }
    });

}
}

这是我的错误日志

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
请帮助我解决

2 个答案:

答案 0 :(得分:0)

我迟到了,但它可能会帮助别人。

虽然我正在研究类似的问题,但据我所知,与Android中的前台应用程序(活动)所需的权限相比,后台服务需要单独的权限。

如果您的Android Manifest中有特定的权限类型,那么这不足以让您在服务中使用相同的代码。例如,当我使用代码注册SIP服务器时,USES_SIP权限给出了错误。相同的代码可以从活动中正常工作。

现在我启动一个活动来接收呼叫并从活动中注册BroadcastReceiver,因此授予了权限。

你的NullPointerException不是很复杂,但很可能是因为权限。

HTH

答案 1 :(得分:-1)

当您编写" native sip"时,您的意思是带有Android的预打包SIP或与您的应用程序捆绑的本机SIP二进制文件,并且可能是您构建的(例如PJSIP,Linphone)等等)?

如果是后者,则无法通过Android API执行您正在执行的操作。您需要使用SIP堆栈的API。