Sunday, June 9, 2013

Android - Make a phone call with speaker on programatically

In this post, I'm sharing with you the Android code to turn on the speaker when making a call in a programatically way .

The idea behind is to place a call and to listen to the phone state change to switch on the speaker when the call is established.

package com.danielthat.loudspeaker;

import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class Loudspeaker extends Activity {

 Button mButton;
 EditText mEdit;
 TelephonyManager manager;
 StatePhoneReceiver myPhoneStateListener;
 boolean callFromApp=false; // To control the call has been made from the application
 boolean callFromOffHook=false; // To control the change to idle state is from the app call


 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.layout_loudspeaker);

  //To be notified of changes of the phone state create an instance
  //of the TelephonyManager class and the StatePhoneReceiver class
  myPhoneStateListener = new StatePhoneReceiver(this);
  manager = ((TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE));

  mEdit   = (EditText)findViewById(R.id.editText1);
      
  mButton = (Button) findViewById(R.id.button1);
  mButton.setOnClickListener(new View.OnClickListener() {
  
   public void onClick(View v) {
  
    String phoneNumber = mEdit.getText().toString();
    manager.listen(myPhoneStateListener,
    PhoneStateListener.LISTEN_CALL_STATE); // start listening to the phone changes
    callFromApp=true;
    Intent i = new Intent(android.content.Intent.ACTION_CALL,
                          Uri.parse("tel:+" + phoneNumber)); // Make the call       
    startActivity(i);   
   } 
  }); 
 }


 // Monitor for changes to the state of the phone
 public class StatePhoneReceiver extends PhoneStateListener {
     Context context;
     public StatePhoneReceiver(Context context) {
         this.context = context;
     }

     @Override
     public void onCallStateChanged(int state, String incomingNumber) {
         super.onCallStateChanged(state, incomingNumber);
        
         switch (state) {
        
         case TelephonyManager.CALL_STATE_OFFHOOK: //Call is established
          if (callFromApp) {
              callFromApp=false;
              callFromOffHook=true;
                  
              try {
                Thread.sleep(500); // Delay 0,5 seconds to handle better turning on loudspeaker
              } catch (InterruptedException e) {
              }
          
              //Activate loudspeaker
              AudioManager audioManager = (AudioManager)
                                          getSystemService(Context.AUDIO_SERVICE);
              audioManager.setMode(AudioManager.MODE_IN_CALL);
              audioManager.setSpeakerphoneOn(true);
           }
           break;
        
        case TelephonyManager.CALL_STATE_IDLE: //Call is finished
          if (callFromOffHook) {
                callFromOffHook=false;
                AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
                audioManager.setMode(AudioManager.MODE_NORMAL); //Deactivate loudspeaker
                manager.listen(myPhoneStateListener, // Remove listener
                      PhoneStateListener.LISTEN_NONE);
             }
          break;
         }
     }
 }
}

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.danielthat.loudspeaker"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
  
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.danielthat.loudspeaker.Loudspeaker"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".Loudspeaker" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Number to call with loudspeaker on:" />

    <EditText
        android:id="@+id/editText1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/textView1"
        android:layout_below="@+id/textView1"
        android:ems="10"
        android:inputType="phone" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/editText1"
        android:layout_below="@+id/editText1"
        android:text="Call" />

</RelativeLayout>



Wednesday, May 29, 2013

java.lang.NoClassDefFoundError - Android

After updating the SDK and the ADT, when running your Android application, if you get the following error: java.lang.NoClassDefFoundError, make sure that "Android Private Libraries" and "Android Dependencies" are checked for Export.

To do so:

1) Right click on your project,  then Build Path, then Configure Build Path.



2) In the "Order and Export" tab, check the "Android Private Libraries" and "Android Dependencies" and then OK.



3) Then Clean and Build (if not done automatically).



4) Go to Android SDK Manager (located on Window menu) and verify that you have the Android SDK Build-tools installed, if not do it.



That's it.

Monday, May 27, 2013

Android programming - Activate loudspeaker for outgoing call

In this post, I'm sharing with you the Android code to activate automatically the loudspeaker when making a call in a programatically way .

The idea behind is to place a call and to listen to the phone state change to switch on the speaker when the call is established.

package com.danielthat.loudspeaker;

import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class Loudspeaker extends Activity {
 
 Button mButton;
 EditText mEdit;
 TelephonyManager manager;
 StatePhoneReceiver myPhoneStateListener;
 boolean callFromApp=false; // To control the call has been made from the application
 boolean callFromOffHook=false; // To control the change to idle state is from the app call

 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.layout_loudspeaker);
  
  //To be notified of changes of the phone state create an instance 
  //of the TelephonyManager class and the StatePhoneReceiver class
  myPhoneStateListener = new StatePhoneReceiver(this);
  manager = ((TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE));
  
  mEdit   = (EditText)findViewById(R.id.editText1);
        
  mButton = (Button) findViewById(R.id.button1);
  mButton.setOnClickListener(new View.OnClickListener() {
   
   public void onClick(View v) {
    
    String phoneNumber = mEdit.getText().toString(); 
    manager.listen(myPhoneStateListener,
    PhoneStateListener.LISTEN_CALL_STATE); // start listening to the phone changes
    callFromApp=true;
    Intent i = new Intent(android.content.Intent.ACTION_CALL, 
                          Uri.parse("tel:+" + phoneNumber)); // Make the call        
    startActivity(i);    
   }  
  });  
 }

 
 // Monitor for changes to the state of the phone
 public class StatePhoneReceiver extends PhoneStateListener {
     Context context;
     public StatePhoneReceiver(Context context) {
         this.context = context;
     }

     @Override
     public void onCallStateChanged(int state, String incomingNumber) {
         super.onCallStateChanged(state, incomingNumber);
         
         switch (state) {
         
         case TelephonyManager.CALL_STATE_OFFHOOK: //Call is established
          if (callFromApp) {
              callFromApp=false;
              callFromOffHook=true;
                    
              try {
                Thread.sleep(500); // Delay 0,5 seconds to handle better turning on loudspeaker
              } catch (InterruptedException e) {
              }
           
              //Activate loudspeaker
              AudioManager audioManager = (AudioManager) 
                                          getSystemService(Context.AUDIO_SERVICE);
              audioManager.setMode(AudioManager.MODE_IN_CALL);
              audioManager.setSpeakerphoneOn(true);
           }
           break;
         
        case TelephonyManager.CALL_STATE_IDLE: //Call is finished
          if (callFromOffHook) {
                callFromOffHook=false;
                AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
                audioManager.setMode(AudioManager.MODE_NORMAL); //Deactivate loudspeaker
                manager.listen(myPhoneStateListener, // Remove listener
                      PhoneStateListener.LISTEN_NONE);
             }
          break;
         }
     }
 }
}

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.danielthat.loudspeaker"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
    
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.danielthat.loudspeaker.Loudspeaker"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".Loudspeaker" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Number to call with loudspeaker on:" />

    <EditText
        android:id="@+id/editText1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/textView1"
        android:layout_below="@+id/textView1"
        android:ems="10"
        android:inputType="phone" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/editText1"
        android:layout_below="@+id/editText1"
        android:text="Call" />

</RelativeLayout>

Saturday, May 11, 2013

Android programming - How to convert a date string to a date as milisecond value

Here is a function to convert a date string to a date as a millisecond value. The value is the number of milliseconds since Jan. 1, 1970, midnight GMT.

public long longDate (String sdate){
  
  long longDate = System.currentTimeMillis(); //Initializes var with current time in case parsing fails
   
  SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy, HH:mm", Locale.US); //Describes date pattern
  format.setLenient(false); //enforces strict pattern matching  
    
  try {
   Date date = format.parse(sdate); //converts string to a date object
   longDate = date.getTime(); 
  } catch (ParseException e) {
  }
    
  return longDate;  
  }


So basically you would call the function like longDate (11/05/2013, 22:25).

Sunday, March 24, 2013

How to display code in blogger posts

In this post, I'm going to show step by step how to display code nicely in blogger posts using SyntaxHighlighter.

1) First, we need to add the html code below on the head section of our blogger template. To do this, inside blogger:
  • Select Template on the left hand side.
  • Click Edit HTML.
  • Then copy the code below just before the closing head tag (i.e </head>). You can easily find it by using the search box accessing to it with Control+F.

<link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeEclipse.css' rel='stylesheet' type='text/css'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'/>
<script language='javascript' type='text/javascript'>
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.all();
</script>

On line 4 and 5 (violet color), I'm loading the syntax template for Java code and XML code, but there are much more like PHP, Perl, SQL,... you can find the complete list here.


2) Now that the blogger template is ready, we need to prepare the code to ensure correct rendering. Basically, we need to HTML escape some characters like right angle brackets, e.g. all < must be replaced with &lt;. To do so, you can use one of the following online tools:

http://www.accessify.com/tools-and-wizards/developer-tools/quick-escape/default.php


3) Once you have the code with escaped characters, you can copy it on your blogger post inside <pre> tags. In the title you can choose a title for the code block and in the class you choose the code template to use.

<pre title="here goes a title" class="brush:xml;">
...
</pre>


4) And that's it, here is an example:
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeEclipse.css' rel='stylesheet' type='text/css'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'/>
<script language='javascript' type='text/javascript'>
    SyntaxHighlighter.config.bloggerMode = true;
    SyntaxHighlighter.all();
</script>

Saturday, March 23, 2013

Android programming - Call forwarding

In this post, I'm sharing with you the Android code to activate/deactivate call forwarding programatically.

The idea behing is to instruct the phone to send the MMI codes to tell the network operator to activate/deactivate the call forwaring. Please notice, that your operator must allow you to use this service otherwise it will not work.

In the exemple below, the call forwarding applies to all calls but you can use other options such as only when you are busy or you don't answer. You can find additional info here: http://en.wikipedia.org/wiki/Call_forwarding#Keypad_codes

package com.danielthat.callforwarding;

import android.net.Uri;
import android.os.Bundle;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.view.View;
import android.widget.Button;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;

public class CallForwarding extends Activity 
{
 Button buttonCallForwardOn;
 Button buttonCallForwardOff;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) 
 {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.call_forwarding_layout);
  
  buttonCallForwardOn = (Button) findViewById(R.id.buttonCallForwardOn);
  buttonCallForwardOn.setOnClickListener(new View.OnClickListener()
  {
   public void onClick(View v)
   {
    callforward("*21*0123456789#"); // 0123456789 is the number you want to forward the calls.
   }
  });
  
  buttonCallForwardOff = (Button) findViewById(R.id.buttonCallForwardOff);
  buttonCallForwardOff.setOnClickListener(new View.OnClickListener()
  {
   public void onClick(View v)
   {
    callforward("#21#");
   }
  });
 }
 
 private void callforward(String callForwardString)
    {
        PhoneCallListener phoneListener = new PhoneCallListener();
        TelephonyManager telephonyManager = (TelephonyManager)
         this.getSystemService(Context.TELEPHONY_SERVICE);
        telephonyManager.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
              
        Intent intentCallForward = new Intent(Intent.ACTION_CALL);
        Uri mmiCode = Uri.fromParts("tel", callForwardString, "#");
        intentCallForward.setData(mmiCode);
        startActivity(intentCallForward);
    }
 
 private class PhoneCallListener extends PhoneStateListener 
 {
        private boolean isPhoneCalling = false;        

        @Override
        public void onCallStateChanged(int state, String incomingNumber) 
        {
            if (TelephonyManager.CALL_STATE_RINGING == state)
            {
                // phone ringing
            }

            if (TelephonyManager.CALL_STATE_OFFHOOK == state) 
            {
                // active
                isPhoneCalling = true;
            }

            if (TelephonyManager.CALL_STATE_IDLE == state) 
            {
                // run when class initial and phone call ended, need detect flag
                // from CALL_STATE_OFFHOOK
                if (isPhoneCalling)
                {
                    // restart app
                    Intent i = getBaseContext().getPackageManager()
                            .getLaunchIntentForPackage(getBaseContext().getPackageName());
                    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    startActivity(i);
                    isPhoneCalling = false;
                }
            }
        }
    }
}

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.danielthat.callforwarding"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
    
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.CALL_PHONE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.danielthat.callforwarding.CallForwarding"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".CallForwarding" > 
    
    <Button
        android:id="@+id/buttonCallForwardOn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Activate Call forward" />

    <Button
        android:id="@+id/buttonCallForwardOff"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/buttonCallForwardOn"
        android:layout_below="@+id/buttonCallForwardOn"
        android:text="Cancel Call forward" />

</RelativeLayout>

Monday, February 25, 2013

No ringback tone asterisk

no ringback tone asterisk








You have callers calling in to your Asterisk server using a SIP trunk and they don't hear ringback tone?

Here is what it worked for me.

In the sip.conf file, located in /etc/asterisk/sip.conf:

- In the [general] context check that the parameter prematuremedia=no is present.

- For the related peer (trunk) use the parameter progressinband=yes.