0

I want to know how to make a call in android, without using Intents.

I know it can be done using intents, but I searched through developer.android.com and there is nothing about this topic.

Let's say that I want to write a new dialer for android. How may I do this?

Thanks in advance

vfsoraki
  • 2,186
  • 1
  • 20
  • 45

2 Answers2

2

To make a call,

private void performDial(String numberString) {
if (!numberString.equals("")) {
   Uri number = Uri.parse("tel:" + numberString);
   Intent dial = new Intent(Intent.ACTION_CALL, number);
   startActivity(dial);
}

}

Add this permission into manifest.

<uses-permission android:name="android.permission.CALL_PHONE" />

refer this.

To show a custom dialer screen,Write a receiver for outgoing call

public class OutgoingCallReceiver extends BroadcastReceiver {
 @Override
public void onReceive(final Context context, final Intent intent) {
  //this will receive the outgoing call

}
 }

add these to Manifest

<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

 <receiver android:name=.OutgoingCallReceiver" >
  <intent-filter>
  <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
 </intent-filter>

To show a view on top of the Dialer app when it launches, use this code inside the broadcast receiver

 private WindowManager wm;
    private static LinearLayout ly1;
    private WindowManager.LayoutParams params1;

    // onReceive function of the Broadcast Receiver
    public void onReceive(Context arg0, Intent arg1) {
            String state = arg1.getStringExtra(TelephonyManager.EXTRA_STATE);

            // Adds a view on top of the dialer app when it launches.
            if(state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){
                wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
                params1 = new WindowManager.LayoutParams(
                        LayoutParams.MATCH_PARENT,
                        LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT |
                        WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
                        WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
                        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                        PixelFormat.TRANSPARENT);

                params1.height = 75;
                params1.width = 512;
                params1.x = 265; 
                params1.y = 400;
                params1.format = PixelFormat.TRANSLUCENT;

                ly1 = new LinearLayout(context);
                ly1.setBackgroundColor(Color.BLACK);
                ly1.setOrientation(LinearLayout.VERTICAL);

                wm.addView(ly1, params1);
            }

            // To remove the view once the dialer app is closed.
            if(arg1.getAction().equals("android.intent.action.PHONE_STATE")){
                String state = arg1.getStringExtra(TelephonyManager.EXTRA_STATE);
                if(state.equals(TelephonyManager.EXTRA_STATE_IDLE)){
                    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
                    if(ly1!=null)
                    {
                        wm.removeView(ly1);
                        ly1 = null;
                    }
                }
            }
        }

Note: The above example generated a view having a layout with black background,having dimension as shown above. You have the liberty to add any layout within this view. For example, to include a layout within the view you can modify the above code to include the following code.

 ly1 = new LinearLayout(getApplicationContext());
    ly1.setOrientation(LinearLayout.HORIZONTAL);


    View hiddenInfo = getLayoutInflater().inflate(R.layout.layout1, ly1, false);
    ly1.addView(hiddenInfo);

    wm.addView(ly1, params1);

In your manifest you need to include the following permissions.

 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"></uses-permission>
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
<action android:name="android.intent.action.PHONE_STATE" /

Note: You can also call an activity from the BroadcastReceiver instead of inflating a window. Use the following code for that purpose.

    new Handler().postDelayed(new Runnable() {

     @Override
     public void run() {
         // TODO Auto-generated method stub
         Intent intent = new Intent(context, CustomDialerActivity.class);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         context.startActivity(intent);
     }
 }, 2000);

I am not sure that your custom GUI will always be on top of the default one, because the system broadcast receiver and your receiver are both trying to display its GUI on top of the screen. We are not sure which one is called first, but one tricky work to make your GUI on top of the screen is when the phone is ringing call your activity after 1-2 second(s).I used handler for that.

Community
  • 1
  • 1
Darish
  • 11,032
  • 5
  • 50
  • 70
  • So there is no API for calling a number? As there is some API at `android.telephony.SmsManager` for sending messages? I have to write a n intent receiver? – vfsoraki Nov 18 '14 at 11:23
  • there is no api to make calls – Darish Nov 18 '14 at 11:25
  • You have to make calls using intents. – Darish Nov 18 '14 at 11:26
  • Ok. I have written an app that responds to intent `Intent.ACTION_DIAL`. Now how do I call the number from my app? I should make another intent? This doesn't seem right... – vfsoraki Nov 18 '14 at 11:27
  • I already said that I don't want to use intents. I wanted something to be able to replace the default dialer in android, which seems impossible at the moment. – vfsoraki Nov 18 '14 at 11:34
  • 1
    no impossible,, just make call using this intent. then detect that call using broadcast receiver and populate your own custom UI. – Darish Nov 18 '14 at 11:37
  • 1
    See the link in my answer, that replaces the dialler, but you have to use intents to start the phone call. But otherwise user3756408 is right, you cannot replace the bit that actually accesses the hardware and physically dials the number – Woodi_333 Nov 18 '14 at 11:40
  • Your last sentence was what I needed to know, that bit to access hardware and dial the number! Thanks – vfsoraki Nov 18 '14 at 11:44
1

Not sure you can, the difference between the SMS and the dialler is the fact the SMS can be done with fire and forget, the dialling has to be something that says running until it is done.

This way, by using the intent, you can startActivityForResult to get a result rather than getting an ANR while waiting for a method to return.

So you want to make the intent Intent.ACTION_CALL with the number as it's URI and then start the activity. You will need <uses-permission android:name="android.permission.CALL_PHONE" />

See Android dialer application for an example

Community
  • 1
  • 1
Woodi_333
  • 479
  • 2
  • 7