Android net.sip: manager.makeAudioCall(..) throws sip session error - android

I'm trying to establish a call using sip on Android. The permissions in my manifest are:
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.USE_SIP"/>
<uses-permission android:name="android.permission.INTERNET"/>
The CALL_PHONE permission is there because my app also calls regular numbers.
This is the activity code:
package x.x.x;
import java.text.ParseException;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.net.sip.SipAudioCall;
import android.net.sip.SipException;
import android.net.sip.SipManager;
import android.net.sip.SipProfile;
import android.os.Bundle;
import android.util.Log;
public class CallScreen extends Activity{
public SipManager manager = null;
public SipProfile me = null;
public SipAudioCall call = null;
//IncomingCallReceiver callReceiver;
String domain = "myserver.net";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.callscreen);
initManager();
Log.d("Z:","Done initManger()");
Thread waiter = new Thread(){
#Override
public void run() {
// TODO Auto-generated method stub
try {
sleep(10000);
Log.d("Z:","Done waiting");
initCall();
Log.d("Z:","Done initCall");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
waiter.start();
//initCall();
}
public void initManager()
{
manager = SipManager.newInstance(this);
initLocalProfile();
}
public void initLocalProfile()
{
String username = "user";
String password = "12345";
String domain = "myserver.net";
try {
SipProfile.Builder builder = new SipProfile.Builder(username,domain);
builder.setPassword(password);
me = builder.build();
//Intent intent = new Intent();
//PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent, Intent.FILL_IN_DATA);
//manager.open(me,pi,null);
manager.open(me);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SipException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void initCall()
{
SipAudioCall.Listener listener = new SipAudioCall.Listener(){
#Override
public void onCallEstablished(SipAudioCall call) {
// TODO Auto-generated method stub
//super.onCallEstablished(call);
call.startAudio();
call.setSpeakerMode(true);
call.toggleMute();
}
#Override
public void onCallEnded(SipAudioCall call) {
// TODO Auto-generated method stub
super.onCallEnded(call);
}
};
try {
call = manager.makeAudioCall(me.getUriString(), "12345678910", listener, 30);
} catch (SipException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The error shown on logcat:
01-26 22:20:25.710: D/SipAudioCall(31060): sip session error: CLIENT_ERROR: libcore.io.ErrnoException: getaddrinfo failed: ENOENT (No such file or directory)
I'm trying to make this tiny example work before i organize this code a little differently (username and pass not hard-coded, for example). I'm also not very familier with sip. Really appriciate any advice.
any ideas? Thanks!

The problem is on the following line:
call = manager.makeAudioCall(me.getUriString(), "12345678910", listener, 30);
The second parameter of makeAudioCall method must be the URI of the SIP profile to make the call to, but you provided only its username (i.e: "12345678910"). Change it to something like:
call = manager.makeAudioCall(me.getUriString(), "sip:12345678910#myserver.net", listener, 30);

Related

Android - broadcast receiver for incoming calls stays alive after unregistering it

I have a broadcast receiver for listening to incoming call event. It is defined programmatically not in the manifest. The purpose is to block all calls when that is chosen by the user. But after I unregister the broadcast receiver and close the service that registered it the receiver stays active and still blocks calls.
what I have tried:
1) I tried implementing this receiver inside another broadcast receiver class I already have in this app and works fine...which means that after unregistering it it stops listening to the other events. And while it stops listening to the other events it keeps listening to incoming call events. (which is just utterly weird)
2) I tried implementing the incoming calls receiver in a seperate broacast receiver class and register it in a seperate service. even after i kill this service it still stays alive.
The calls receiver dies only when the whole app closes.
3)I tried the same thing using an activity instead of a service.
OnDestory is called in the case of service. And the problem persists when using an activity as well.
How is this explained and how can I solve this problem???
this is my code for the seperate broacast receiver class and seperate service implementation:
package com.android.internal.telephony;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.widget.Toast;
public class CallBlockBroadcastReceiver extends BroadcastReceiver{
BroadcastReceiver CallBlocker;
TelephonyManager telephonyManager;
ITelephony telephonyService;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
String number=intent.getExtras().getString("incoming_number");
Toast.makeText(context, number, Toast.LENGTH_SHORT).show();
telephonyManager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
//Java Reflections
Class c = null;
try { c = Class.forName(telephonyManager.getClass().getName());}
catch (ClassNotFoundException e) { e.printStackTrace(); }
Method m = null;
try { m = c.getDeclaredMethod("getITelephony");}
catch (SecurityException e) { e.printStackTrace(); }
catch (NoSuchMethodException e) { e.printStackTrace(); }
m.setAccessible(true);
try { telephonyService = (ITelephony)m.invoke(telephonyManager);}
catch (IllegalArgumentException e) {e.printStackTrace();}
catch (IllegalAccessException e) {e.printStackTrace();}
catch (InvocationTargetException e) {e.printStackTrace();}
telephonyManager.listen(callBlockListener, PhoneStateListener.LISTEN_CALL_STATE);
}
PhoneStateListener callBlockListener = new PhoneStateListener(){
public void onCallStateChanged(int state, String incomingNumber){
if(state==TelephonyManager.CALL_STATE_RINGING){
try {
telephonyService.endCall();
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
}
ITelephony class:
package com.android.internal.telephony;
interface ITelephony {
boolean endCall();
void answerRingingCall();
void silenceRinger();
}
my service
import android.app.Service;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import com.android.internal.telephony.CallBlockBroadcastReceiver;
public class BroadcastService extends Service{
CallBlockBroadcastReceiver callBlockBroadcastReceiver = new CallBlockBroadcastReceiver();
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
getBaseContext().registerReceiver(callBlockBroadcastReceiver, new IntentFilter("android.intent.action.PHONE_STATE"));
return START_STICKY;
}
#Override
public void onDestroy() {
getBaseContext().unregisterReceiver(callBlockBroadcastReceiver);
// TODO Auto-generated method stub
super.onDestroy();
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
I would guess that onDestroy() is not getting called in your service. Are there any bindings left to the service? Are you sure you're calling stopService(intent) on the service?

Authenticate Android App

I am new to android and I am building an app that I want to authenticate using the local users google account. Unfortunately I have gotten myself in a bit of a bind looking at Auth 2.0 and logging in via the google services.
What is the recommended route to authenticate (and hopefully not require typing a login name)? I tried many of the samples that I saw but much of it seems deprecated.
Any example code would be very helpful as well.
I was using this tutorial but it is a bit outdated and I believe that it is much simplier now.
http://blog.notdot.net/2010/05/Authenticating-against-App-Engine-from-an-Android-app
Thanks,
Craig
Here is how I solved it. Don't know if it is the recommended approach but it works...
in OnCreate of my entry activity (main) I put...
AccountManager accountManager = AccountManager.get(this);
Account[] accounts = accountManager.getAccountsByType("com.google");
AccountManagerFuture<Bundle> futur;
futur = accountManager.getAuthToken(accounts[0],AUTH_TOKEN_TYPE_USERINFO_PROFILE, null, null,
new OnTokenAcquired(), new Handler(new OnError()));
In that same activity I created...
private class OnTokenAcquired implements AccountManagerCallback<Bundle> {
#Override
public void run(AccountManagerFuture<Bundle> result) {
// Get the result of the operation from the AccountManagerFuture.
Bundle bundle;
try {
bundle = result.getResult();
// The token is a named value in the bundle. The name of the
// value
// is stored in the constant AccountManager.KEY_AUTHTOKEN.
String token = bundle.getString(AccountManager.KEY_AUTHTOKEN);
//If token isn't null then let them in and also make sure Crunchy accounts are created
if(token!=null){
ProcessToken pt = new ProcessToken(token);
pt.execute("");
}
Intent launch = (Intent) bundle.get(AccountManager.KEY_INTENT);
if (launch != null) {
startActivityForResult(launch, 0);
return;
}
}catch (OperationCanceledException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (AuthenticatorException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I also created an asyncTask to process the token (because I do a bit more logic to setup account and set a cookie). It looks like this (much of my processing/cookie logic is not completed yet)
package com.craig.activities.login;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import android.os.AsyncTask;
import android.util.Log;
public class ProcessToken extends AsyncTask<String,Integer,Long>{
private static final String AUTH_ACCESS_TOKEN_URL = "https://www.googleapis.com/oauth2/v1/userinfo?access_token=";
private static final String DEBUG_TAG = "OnTokenAcquired.class";
private static String token="";
public ProcessToken(String tokenValue){
token=tokenValue;
}
#Override
protected Long doInBackground(String... params) {
try {
URL url = new URL(AUTH_ACCESS_TOKEN_URL+token);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
int serverCode= con.getResponseCode();
if(serverCode==200){
Log.i(DEBUG_TAG, "code 200!!!");
//PUT MY LOGIC IN HERE....
}
else{
Log.i(DEBUG_TAG, "Oops, We had an error on authentication");
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
Not sure if this is the best but it seems to be working for me....

http-request from Button VS from Class

i got a class i made, that makes a simple GET request and displays toast messege with the response...
if i call the function from a bottom event click it displays the messege with the data returned, just ok.
but if i call the same function from a brodcast reciver class, it just showing the massege with the data '' (null)
i belive that it showing the massege before i could get the data, and with the button it waits for the data..
how can i make it work from the brodcast reciver?
the class:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import android.app.Activity;
import android.content.Context;
import android.widget.Toast;
public class myclass{
public static void doHttpRequest(String param1, Context context){
String ret="";
try {
URL url = new URL("http://website.com/page?param="+param1);
HttpURLConnection con = (HttpURLConnection) url
.openConnection();
ret=readStream(con.getInputStream());
} catch (Exception e) {
e.printStackTrace();
}
CharSequence text = "return data- "+ret;
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
private static String readStream(InputStream in) {
BufferedReader reader = null;
String line = "";
String alllines = "";
try {
reader = new BufferedReader(new InputStreamReader(in));
while ((line = reader.readLine()) != null) {
alllines=alllines+line;
}
return alllines;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return alllines;
}
}
from the button it works fine:
final Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
myclass.doHttpRequest("blabla", getBaseContext());
}});
from the brodcast reciver witch in different class it won't return data, but shows the toast..
public class CustomBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "CustomBroadcastReceiver";
#Override
public void onReceive(Context context, Intent intent) {
myclass.doHttpRequest("blabla", context);
break;
} }
}
please HELP.... :) THANKS
All fixed.. it's seems to be a project settings error, or premmisions error (but i had the premissions in the manifest... must not apply in the apk while compiling)
i copied the classes to enother project made by erlier version of eclipse, and it's works there like a charm...
thanks anyway..
i tried for hours to fix it in the code.. and it was the settings....
I created a myclass.java and CustomBroadcastReceiver.java and tried your code by removing the break statement and one extra curly brace from the CustomBroadcastReceiver.java class and it worked fine for me.
The following code in Activity class demonstrates registering, uninteresting receiver and a Handler for a sample/test broadcast.
CustomBroadcastReceiver customBroadcastReceiver;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
customBroadcastReceiver = new CustomBroadcastReceiver();
registerReceiver(cusoBroadcastReceiver, new IntentFilter("com.example.app.testbroadcast"));
// For test broadcast only.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
sendBroadcast(new Intent("com.example.app.testbroadcast"));
}
}, 2000);
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
unregisterReceiver(customBroadcastReceiver);
}
Hope this helps.

Getting force close error in android when using threading

In my application i want to do bluetooth chat. I'm facing a problem in threading. In my application my android phone will work as server which has a blocking statement
socket=mServerSocket.accept();
for this purpose i've created a child thread so that it will run separately. But before finishing this child thread main thread goes down giving Force Close and if i use the .join() method it hangs up my UI.
What is the solution to run both threads parallel?
this is my code
main Activity
package com.my.bluechat_2_1;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class BlueChat extends Activity {
/** Called when the activity is first created. */
private BlueHandler btHandler=null;
private BluetoothAdapter btAdapter = null;
private Context context=this;
TextView chatWindow=null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
chatWindow=(TextView)findViewById(R.id.textView1);
doStart();
}
private void doStart(){
Button btnStart=(Button)findViewById(R.id.button1);
btnStart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// Get local Bluetooth adapter
btAdapter = BluetoothAdapter.getDefaultAdapter();
// If the adapter is null, then Bluetooth is not supported
if(btAdapter == null)
{
Toast.makeText(context, "Device does not support Bluetooth", Toast.LENGTH_LONG).show();
}
if (!btAdapter.isEnabled()) {
Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
}
chatWindow.append("Waiting for connection...\n");
btHandler=new BlueHandler(context,chatWindow,btAdapter);
Thread acceptThread=new Thread(btHandler);
acceptThread.start();
}
});
}
}
BlueHandler
package com.my.bluechat_2_1;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.widget.TextView;
import android.widget.Toast;
public class BlueHandler implements Runnable{
// Name for the SDP record when creating server socket
private static final String SMARTCAM_BT_SERVICE_NAME = "SmartCam";
// Unique UUID for this application
private static final UUID SMARTCAM_BT_SERVICE_UUID = UUID.fromString("95b82690-4c94-11e1-b86c-0800200c9a66");
private BluetoothAdapter btAdapter = null;
private BluetoothServerSocket btServerSocket = null;
private BluetoothSocket btSocket = null;
private InputStream btInputStream=null;
private Context contextObj=null;
private TextView textView;
public BlueHandler(Context contextObj,TextView textView,BluetoothAdapter btAdapter){
this.contextObj=contextObj;
this.btAdapter=btAdapter;
this.textView=textView;
try {
btServerSocket=this.btAdapter.listenUsingRfcommWithServiceRecord(SMARTCAM_BT_SERVICE_NAME, SMARTCAM_BT_SERVICE_UUID);
} catch (IOException e) {
// TODO Auto-generated catch block
Toast.makeText(this.contextObj, "Service not created", Toast.LENGTH_LONG);
}
}
#Override
public void run() {
// TODO Auto-generated method stub
textView.append("Inside child thread.\n");
textView.append(btServerSocket+"\n");
while (true) {
try {
btSocket = btServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (btSocket != null) {
// Do work to manage the connection (in a separate thread)
try {
btServerSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
textView.append("Connected.\n");
try {
btInputStream=btSocket.getInputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte[] buffer = new byte[1024]; // buffer store for the stream
String s;
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes=btInputStream.read(buffer);
s= new String(buffer);
// Send the obtained bytes to the UI Activity
textView.append("received ::" +s+"\n");
} catch (IOException e) {
break;
}
}
}
}
You're probably getting a crash because you're accessing a textView on the worker thread. You'll need to use TextView.post(Runnable) to make that not happen.
In reality you should be using a bindable Service to do this kind of work. You can post back to the UI via broadcast intents or callback methods, That way you don't have to worry about rotation bugs.
Are you performing a long operation in the constructor of your children thread? Each long operation must be done in the run() method.

Android Facebook API Authorizes/Remembers on it's side, but not on mine?

In my code I can get Facebook to show up, show the requested permissions and authorize, everytime I return after it remembers who I am.
In my app itself though it can not seem to recognize that it is logged in, the call to Authorize never returns through the DialogListener interface. The somewhat incomplete code of my apps adapter is included.
package com.metalrain.ca.newschoolshooter_full;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import Hammer.App.MyLibs.APPSTATICS;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import com.facebook.android.AsyncFacebookRunner;
import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.FacebookError;
import com.facebook.android.Facebook.DialogListener;
public class FacebookIntegrator implements DialogListener{
public static final String APP_ID = "176680882361390";
private final Facebook mFacebook;
//private final AsyncFacebookRunner mAsyncRunnoner;
Context ctx;
String[] Permissions = new String[] {"publish_stream", "read_stream", "offline_access"};
FacebookIntegrator(final Context ctx) {
this.ctx = ctx;
this.mFacebook = new Facebook(FacebookIntegrator.APP_ID);
//this.mAsyncRunner = new AsyncFacebookRunner(this.mFacebook);
}
public void SubmitScore() {
Log.e("MetalRain", "Started SubmitScore"+mFacebook.getAccessToken());
//I use the class from the login button to do this
//final LoginButton lb = new LoginButton(this.ctx);
if (mFacebook.isSessionValid()) {
Log.i("MetalRain", "There is a valid facebook sessi");
Bundle b = new Bundle();
try {
mFacebook.request("/me/feed", b, "POST");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
b.putString("status", "This is a test: name");
} else {
Log.i("MetalRain","Authorizing facebook");
mFacebook.authorize((Activity) this.ctx,this.Permissions,
this);
}
Log.e("MetalRain", "Finished SubmitScore");
}
public void onComplete(Bundle values) {
if (!values.containsKey("post_id"))
{
try
{
Bundle parameters = new Bundle();
parameters.putString("message", "this is a test");// the message to post to the wall
mFacebook.dialog(APPSTATICS.CTX, "stream.publish", parameters, this);// "stream.publish" is an API call
}
catch (Exception e)
{
// TODO: handle exception
System.out.println(e.getMessage());
}
}
Log.e("MetalRain", "On Complete");
}
public void onFacebookError(FacebookError error) {
Log.e("MetalRain","fbFAILURE "+error.getMessage());
}
public void onError(DialogError error) {
Log.e("MetalRain","FAILURE "+error.getMessage());
}
public void onCancel() {
Log.e("MetalRain","CANCELED");
}
}
I am not seeing any errors or any log messages post-return. It just returns to my activity and acts as if nothing is happening.
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
fbi.mFacebook.authorizeCallback(requestCode, resultCode, data);
}
This was required by the newest version, since it was a fully activity and not some form of remote dialog. Once I added this it all worked (added to my Activity, not the code above, fbi is FacebookIntegrator, the class linked above).

Categories

Resources