我正在开发一个基于SipDemo应用程序的SIP客户端。我的应用程序首先成功接收来电,但一段时间后我的应用程序无法接听电话。 BroadcastReceiver
没有收到任何内容。什么可能导致这种情况?
我的清单文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.kasenna.android.kasip">
<uses-permission android:name="android.permission.USE_SIP" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-feature android:name="android.hardware.sip.voip" android:required="true" />
<uses-feature android:name="android.hardware.wifi" android:required="true" />
<uses-feature android:name="android.hardware.microphone" android:required="true" />
<application android:icon="@drawable/icon" android:label="KaSip">
<activity android:name=".MainActivity"
android:launchMode="singleTask"
android:taskAffinity="">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".SipSettings" android:label="Настройки"/>
<receiver android:name=".IncomingCallReceiver" android:label="Call Receiver"/>
<service android:name=".MainService" android:exported="false"/>
</application>
</manifest>
主要活动:
package com.kasenna.android.kasip;
public class MainActivity extends FragmentActivity implements
IncallFragmentClass.IncallButtonsEventListener,
IncallCallEndFragmentClass.IncallCallEndButtonsEventListener,
MakeCallFragmentClass.MakeCallButtonsEventListener,
DialpadFragmentClass.DialpadButtonsEventListener
{
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.main);
mswitch=(Switch)findViewById(R.id.regswitch);
mswitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked){
if(isChecked){
SharedPreferences prefs=PreferenceManager.getDefaultSharedPreferences(getBaseContext());
String username=prefs.getString("namePref","");
String password=prefs.getString("passPref","");
if(username.length()==0||password.length()==0){
showDialog(UPDATE_SETTINGS_DIALOG);
}else {
accRegistered = true;
//registrationWorker("start");
initializeLocalProfile();
}
}else{
SharedPreferences prefs=PreferenceManager.getDefaultSharedPreferences(getBaseContext());
String username=prefs.getString("namePref","");
String password=prefs.getString("passPref","");
if(username.length()==0||password.length()==0){
}else {
accRegistered = false;
//registrationWorker("stop");
closeLocalProfile();
}
}
}
});
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
AudioManager manager=(AudioManager)getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
manager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
Uri notification=RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
ring = RingtoneManager.getRingtone(getApplicationContext(),notification);
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container_dialpad, (new DialpadFragmentClass())).commit();
ImageButton delButton = (ImageButton) findViewById(R.id.buttonDel);
delButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
TextView labelView=(TextView)findViewById(R.id.sipLabelDialpad);
String currentString = labelView.getText().toString();
String needText = currentString.equals("") ? "" : currentString.substring(0,currentString.length()-1);
updateStatus(needText,true);
if((!currentString.equals(""))&(needText.equals(""))){
getSupportFragmentManager().beginTransaction().remove(mMakeCallClass).commit();
}
}
});
initializeManager();
}
public void initializeManager(){
IntentFilter filter = new IntentFilter();
filter.addAction("android.KaSip.INCOMING_CALL");
callReceiver = new IncomingCallReceiver();
this.registerReceiver(callReceiver,filter);
if(manager == null){
manager = SipManager.newInstance(this);
Log.v("KaSip_logs","manager created: "+manager.toString());
}
}
public void initializeLocalProfile(){
if(manager == null){
return;
}
if(me != null){
closeLocalProfile();
}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
String username = prefs.getString("namePref","");
String password = prefs.getString("passPref","");
try{
SipProfile.Builder builder = new SipProfile.Builder(username,"cgp.cittel.ru");
builder.setPassword(password);
ConnectivityManager connManager=(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mWifi=connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if(mWifi.isConnected()){
builder.setProtocol("TCP");
}else{
builder.setProtocol("UDP");
}
builder.setSendKeepAlive(true);
builder.setAutoRegistration(true);
me=builder.build();
updateStatus("регистрация...");
Intent mServiceIntent = new Intent(this,MainService.class);
String dataUrl = me.getUriString();
mServiceIntent.setData(Uri.parse(dataUrl));
startService(mServiceIntent);
Intent i = new Intent();
i.setAction("android.KaSip.INCOMING_CALL");
PendingIntent pi = PendingIntent.getBroadcast(this,0,i,Intent.FILL_IN_DATA);
Log.v("KaSip_logs","SipProfile="+me.getUriString());
manager.open(me,pi,null);
Log.v("KaSip_logs","after manager open");
SipRegistrationListener mListener = new SipRegistrationListener(){
public void onRegistering(String localProfileUri){
}
public void onRegistrationDone(String localProfileUri,long expiryTime){
updateStatus("зарегистрирован");
}
public void onRegistrationFailed(String localProfileUri,int errorCode,String errorMessage){
Log.v("KaSip_logs","SipRegistrationListener error="+errorMessage);
}
};
manager.setRegistrationListener(me.getUriString(),mListener);
manager.register(me,60,mListener);
Log.v("KaSip_logs","manager register");
}catch(ParseException pe){
pe.printStackTrace();
}catch(SipException se){
Log.v("KaSip_logs","SipException="+se.getMessage());
}
}
public void closeLocalProfile(){
if(manager==null){
return;
}
try{
if(me!=null){
manager.close(me.getUriString());
}
}catch(Exception ee){
ee.printStackTrace();
}
updateStatus("не зарегистрирован");
}
public void updatePreferences(){
Intent settingsActivity=new Intent(getBaseContext(),
SipSettings.class);
startActivity(settingsActivity);
}
public void onReceiveCallBroadcast(Intent intent){
SipAudioCall.Listener listener=new SipAudioCall.Listener(){
@Override
public void onRinging(SipAudioCall call,SipProfile caller){
super.onRinging(call,caller);
remoteCall=call;
Log.v("KaSip_logs","onReceiveCallBroadcast, onRinging, caller="+caller.getUriString());
}
@Override
public void onCallEnded(SipAudioCall call){
super.onCallEnded(call);
callTimer("stop");
updateStatus("", true);
if(ring.isPlaying()){
ring.stop();
}
if (loadedActionFragment.equals("incall")) {
getSupportFragmentManager().beginTransaction().remove(mIncallFragmentClass).commit();
loadedActionFragment = "";
}else if (loadedActionFragment.equals("incallcallstart")){
getSupportFragmentManager().beginTransaction().remove(mIncallCallEndFragmentClass).commit();
loadedActionFragment = "";
}
}
@Override
public void onCallEstablished(SipAudioCall call){
super.onCallEstablished(call);
callTimer("start");
createUI("incallcallstart");
}
@Override
public void onError(SipAudioCall call, int errorCode, String errorMessage){
super.onError(call,errorCode,errorMessage);
callTimer("stop");
updateStatus("",true);
if (loadedActionFragment.equals("incall")) {
getSupportFragmentManager().beginTransaction().remove(mIncallFragmentClass).commit();
loadedActionFragment = "";
}else if (loadedActionFragment.equals("incallcallstart")){
getSupportFragmentManager().beginTransaction().remove(mIncallCallEndFragmentClass).commit();
loadedActionFragment = "";
}
}
};
try{
incomingCall=manager.takeAudioCall(intent,listener);
}catch(SipException se){
Log.v("KaSip_logs","onReceiveCallBroadcast error="+se.getMessage());
if(incomingCall!=null){
incomingCall.close();
}
if(remoteCall!=null){
remoteCall.close();
}
}
Window window=this.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
ring.play();
updateStatus(incomingCall);
}
@Override
public void OnClick_buttonStart() {
updateStatus("",true);
if (ring.isPlaying()) {
ring.stop();
}
try {
if (remoteCall != null) {
remoteCall.answerCall(30);
}
incomingCall.answerCall(30);
incomingCall.startAudio();
if (incomingCall.isMuted()) {
incomingCall.toggleMute();
}
} catch (SipException se) {
Log.v("KaSip_logs", "onReceiveCallBroadcast error=" + se.getMessage());
if (incomingCall != null) {
incomingCall.close();
}
if (remoteCall != null) {
remoteCall.close();
}
}
}
@Override
public void OnClick_buttonStop() {
if (ring.isPlaying()) {
ring.stop();
}
try {
if (remoteCall != null) {
remoteCall.endCall();
}
if (incomingCall != null) {
incomingCall.endCall();
incomingCall.close();
}
if (remoteCall != null) {
remoteCall.close();
}
} catch (SipException se) {
Log.v("KaSip_logs", "onReceiveCallBroadcast error=" + se.getMessage());
}
callTimer("stop");
synchronized (this) {
try {
this.wait(1000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
updateStatus("", true);
getSupportFragmentManager().beginTransaction().remove(mIncallFragmentClass).commit();
loadedActionFragment = "";
}
@Override
public void OnClick_buttonCallEnd() {
try {
if (remoteCall != null) {
remoteCall.endCall();
}
if (incomingCall != null) {
incomingCall.endCall();
incomingCall.close();
}
if (outgoingCall != null) {
outgoingCall.endCall();
outgoingCall.close();
}
if (remoteCall != null) {
remoteCall.close();
}
} catch (SipException se) {
Log.v("KaSip_logs", "onReceiveCallBroadcast error=" + se.getMessage());
}
callTimer("stop");
generateRingback("stop");
updateStatus("", true);
getSupportFragmentManager().beginTransaction().remove(mIncallCallEndFragmentClass).commit();
loadedActionFragment = "";
}
@Override
public void OnClick_buttonMakeCall(){
if (accRegistered) {
createUI("incallcallstart");
TextView labelView = (TextView) findViewById(R.id.sipLabelDialpad);
sipAddress = labelView.getText().toString();
try {
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
@Override
public void onCallEstablished(SipAudioCall call) {
super.onCallEstablished(call);
generateRingback("stop");
call.startAudio();
callTimer("start");
updateStatus("", true);
}
@Override
public void onCallEnded(SipAudioCall call) {
super.onCallEnded(call);
callTimer("stop");
generateRingback("stop");
updateStatus("", true);
getSupportFragmentManager().beginTransaction().remove(mIncallCallEndFragmentClass).commit();
loadedActionFragment = "";
}
@Override
public void onCallBusy(SipAudioCall call) {
super.onCallBusy(call);
generateRingback("stop");
updateStatus("номер занят", true);
generateBusy("start");
getSupportFragmentManager().beginTransaction().remove(mIncallCallEndFragmentClass).commit();
loadedActionFragment = "";
}
@Override
public void onRingingBack(SipAudioCall call) {
super.onRingingBack(call);
updateStatus("ждём ответа", true);
generateRingback("start");
}
@Override
public void onError(SipAudioCall call, int errorCode, String errorMessage) {
super.onError(call, errorCode, errorMessage);
callTimer("stop");
generateRingback("stop");
updateStatus("", true);
getSupportFragmentManager().beginTransaction().remove(mIncallCallEndFragmentClass).commit();
loadedActionFragment = "";
}
};
outgoingCall = manager.makeAudioCall(me.getUriString(), sipAddress + "@cgp.cittel.ru", listener, 30);
} catch (Exception e) {
e.printStackTrace();
if (me != null) {
try {
manager.close(me.getUriString());
} catch (Exception ee) {
ee.printStackTrace();
}
}
if (outgoingCall != null) {
outgoingCall.close();
}
}
}else{
Toast.makeText(this,"Сначала зарегистрируйтесь",Toast.LENGTH_LONG).show();
}
}
@Override
public void OnClick_buttonDialPad(final String button_description){
this.runOnUiThread(new Runnable(){
public void run(){
TextView labelView=(TextView)findViewById(R.id.sipLabelDialpad);
if ((loadedActionFragment.equals(""))&&(labelView.getText().toString().equals(""))){
mMakeCallClass = new MakeCallFragmentClass();
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container_call_buttons, mMakeCallClass).commit();
}
updateStatus(labelView.getText()+button_description,true);
}
});
try {
if (incomingCall != null) {
if (button_description.equals("0")) {
incomingCall.sendDtmf(0);
} else if (button_description.equals("1")) {
incomingCall.sendDtmf(1);
} else if (button_description.equals("2")) {
incomingCall.sendDtmf(2);
} else if (button_description.equals("3")) {
incomingCall.sendDtmf(3);
} else if (button_description.equals("4")) {
incomingCall.sendDtmf(4);
} else if (button_description.equals("5")) {
incomingCall.sendDtmf(5);
} else if (button_description.equals("6")) {
incomingCall.sendDtmf(6);
} else if (button_description.equals("7")) {
incomingCall.sendDtmf(7);
} else if (button_description.equals("8")) {
incomingCall.sendDtmf(8);
} else if (button_description.equals("9")) {
incomingCall.sendDtmf(9);
} else if (button_description.equals("*")) {
incomingCall.sendDtmf(10);
} else if (button_description.equals("#")) {
incomingCall.sendDtmf(11);
} else if (button_description.equals("A")) {
incomingCall.sendDtmf(12);
} else if (button_description.equals("B")) {
incomingCall.sendDtmf(13);
} else if (button_description.equals("C")) {
incomingCall.sendDtmf(14);
} else if (button_description.equals("D")) {
incomingCall.sendDtmf(15);
}
}
if (outgoingCall != null) {
if (button_description.equals("0")) {
outgoingCall.sendDtmf(0);
} else if (button_description.equals("1")) {
outgoingCall.sendDtmf(1);
} else if (button_description.equals("2")) {
outgoingCall.sendDtmf(2);
} else if (button_description.equals("3")) {
outgoingCall.sendDtmf(3);
} else if (button_description.equals("4")) {
outgoingCall.sendDtmf(4);
} else if (button_description.equals("5")) {
outgoingCall.sendDtmf(5);
} else if (button_description.equals("6")) {
outgoingCall.sendDtmf(6);
} else if (button_description.equals("7")) {
outgoingCall.sendDtmf(7);
} else if (button_description.equals("8")) {
outgoingCall.sendDtmf(8);
} else if (button_description.equals("9")) {
outgoingCall.sendDtmf(9);
} else if (button_description.equals("*")) {
outgoingCall.sendDtmf(10);
} else if (button_description.equals("#")) {
outgoingCall.sendDtmf(11);
} else if (button_description.equals("A")) {
outgoingCall.sendDtmf(12);
} else if (button_description.equals("B")) {
outgoingCall.sendDtmf(13);
} else if (button_description.equals("C")) {
outgoingCall.sendDtmf(14);
} else if (button_description.equals("D")) {
outgoingCall.sendDtmf(15);
}
}
}catch (Exception e){
e.printStackTrace();
}
}
private class generateRingbackTask extends AsyncTask<Void, Void, Void> {
Context mContext;
public generateRingbackTask(Context context) {
super();
mContext = context;
}
@Override
protected Void doInBackground(Void... voids) {
int counter = 0;
ToneGenerator mRingback = new ToneGenerator(0,ToneGenerator.MAX_VOLUME);
synchronized (this) {
while (!this.isCancelled()) {
mRingback.startTone(ToneGenerator.TONE_SUP_DIAL,1000);
try {
this.wait(1000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
mRingback.stopTone();
try {
this.wait(1500);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
counter = counter + 2;
}
}
return null;
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void generateRingback(String action){
if(action.equals("start")){
synchronized(this){
mringbackTask = new generateRingbackTask(this);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
mringbackTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
else {
mringbackTask.execute();
}
}
}else{
if (mringbackTask !=null){
mringbackTask.cancel(true);
}
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void generateBusy(String action){
if(action.equals("start")){
synchronized(this){
mbusyTask = new generateBusyTask(this);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
mbusyTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
else {
mbusyTask.execute();
}
}
}else{
if (mbusyTask !=null){
mbusyTask.cancel(true);
}
}
}
private class generateBusyTask extends AsyncTask<Void, Void, Void> {
Context mContext;
public generateBusyTask(Context context) {
super();
mContext = context;
}
@Override
protected void onPostExecute(Void voids) {
updateStatus("", true);
}
@Override
protected Void doInBackground(Void... voids) {
int counter;
ToneGenerator mBusy = new ToneGenerator(0,ToneGenerator.MAX_VOLUME);
synchronized (this) {
for(counter=0;counter<5;counter++){
mBusy.startTone(ToneGenerator.TONE_SUP_DIAL,300);
try {
this.wait(300);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
mBusy.stopTone();
try {
this.wait(100);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
return null;
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void registrationWorker(String action){
if(action.equals("start")){
synchronized(this){
mregistrationTask = new registrationWorkerTask(this);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
mregistrationTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
else {
mregistrationTask.execute();
}
}
}else{
if (mregistrationTask !=null){
mregistrationTask.cancel(true);
}
}
}
private class registrationWorkerTask extends AsyncTask<Void, Void, Void> {
Context mContext;
public registrationWorkerTask(Context context) {
super();
mContext = context;
}
@Override
protected void onPreExecute(){
if ((callReceiver == null)&&(manager == null)){
initializeManager();
}
}
@Override
protected void onProgressUpdate(Void... voids){
initializeLocalProfile();
}
@Override
protected Void doInBackground(Void... voids) {
synchronized (this) {
while (!this.isCancelled()) {
publishProgress(null);
try {
this.wait(58000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
Log.v("KaSip_logs", "registrationWorkerTask stopped");
return null;
}
}
}
和IncomingCallRecever.java
:
package com.kasenna.android.kasip;
public class IncomingCallReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context,
MainActivity.class);
context.startActivity(i);
MainActivity mainActivity = (MainActivity) context;
mainActivity.createUI("incall");
mainActivity.onReceiveCallBroadcast(intent);
}
}