Custom Incoming / Outgoing Call Screen in Android

I am trying to implement a custom screen for incoming calls / outgoing calls. Here is what I have tried. U gave two problems

  • Sometimes it brings up the default input screen on my phone, or sometimes it brings up a custom screen. I would always call on a customized screen.

  • I cannot initiate calls for outgoing calls. a custom screen just appears, but does not cause any calls.

How to solve this problem, I'm not sure what is wrong here. It would be great if someone can help me fix this.

Here is what I am trying:

manifest:

<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.CALL_PHONE" /> <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /> <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar" > <activity android:name="com.honey.ringer.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.honey.ringer.AcceptCall" android:screenOrientation="portrait" android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" > <intent-filter> <action android:name="android.intent.action.ANSWER" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> <receiver android:name="com.honey.ringer.PhoneListenerBroad"> <intent-filter> <action android:name="android.intent.action.PHONE_STATE" /> <action android:name="android.intent.action.NEW_OUTGOING_CALL" /> </intent-filter> </receiver> </application> 

BroadCastReciever: it has both inbound and outbound

 public class PhoneListenerBroad extends BroadcastReceiver { Context c; private String outgoing; @Override public void onReceive(Context context, Intent intent) { c = context; if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) { outgoing = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); int state = 2; Intent intentPhoneCall = new Intent(c, AcceptCall.class); intentPhoneCall.putExtra("incomingnumber", outgoing); intentPhoneCall.putExtra("state", state); intentPhoneCall.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); c.startActivity(intentPhoneCall); } try { TelephonyManager tmgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); MyPhoneStateListener PhoneListener = new MyPhoneStateListener(); tmgr.listen(PhoneListener, PhoneStateListener.LISTEN_CALL_STATE); } catch (Exception e) { Log.e("Phone Receive Error", " " + e); } } private class MyPhoneStateListener extends PhoneStateListener { public void onCallStateChanged(final int state, final String incomingNumber) { Handler callActionHandler = new Handler(); Runnable runRingingActivity = new Runnable() { @Override public void run() { if (state == 1) { Intent intentPhoneCall = new Intent(c, AcceptCall.class); intentPhoneCall.putExtra("incomingnumber", incomingNumber); intentPhoneCall.putExtra("state", state); intentPhoneCall.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); c.startActivity(intentPhoneCall); } } }; if (state == 1) { callActionHandler.postDelayed(runRingingActivity, 100); } if (state == 0) { callActionHandler.removeCallbacks(runRingingActivity); } } } 

}

AcceptCall.java (for UI purposes - inbound and outbound):

  @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) public class AcceptCall extends Activity implements OnClickListener { LinearLayout answerButton; LinearLayout rejectButton; LinearLayout timerLayout; TextView contactName; TextView contactNumber; ImageView profile; private String incomingnumber; private int state; String name = null; String contactId = null; InputStream photo_stream; TextView callType; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.testactivity); answerButton = (LinearLayout) findViewById(R.id.callReceive); answerButton.setOnClickListener(this); rejectButton = (LinearLayout) findViewById(R.id.callReject); rejectButton.setOnClickListener(this); timerLayout = (LinearLayout) findViewById(R.id.timerLayout); contactName = (TextView) findViewById(R.id.contactName); contactNumber = (TextView) findViewById(R.id.contactNumber); callType = (TextView) findViewById(R.id.callType); timerValue = (TextView) findViewById(R.id.timerValue); profile = (ImageView)findViewById(R.id.contactPhoto); Bundle bundle = getIntent().getExtras(); if(bundle != null) { incomingnumber = bundle.getString("incomingnumber"); state = bundle.getInt("state"); } contactslookup(incomingnumber); contactName.setText(name); contactNumber.setText(incomingnumber); if (state == 2) { /*String uri = "tel:" + incomingnumber.trim(); Intent intent = new Intent(Intent.ACTION_CALL); intent.setData(Uri.parse(uri)); startActivity(intent);*/ } PhoneStateListener phoneStateListener = new PhoneStateListener() { @Override public void onCallStateChanged(int state, String incomingNumber) { //wen ringing if (state == TelephonyManager.CALL_STATE_RINGING) { Log.e("CALL_STATE_RINGING","CALL_STATE_RINGING"); } //after call cut else if(state == TelephonyManager.CALL_STATE_IDLE) { RejectCall(); } //wen speaking / outgoing call else if(state == TelephonyManager.CALL_STATE_OFFHOOK) { Log.e("CALL_STATE_OFFHOOK","CALL_STATE_OFFHOOK"); } super.onCallStateChanged(state, incomingNumber); } }; TelephonyManager mgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); if(mgr != null) { mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); } } private void contactslookup(String number) { Log.v("ffnet", "Started uploadcontactphoto..."); //InputStream input = null; // define the columns I want the query to return String[] projection = new String[] {ContactsContract.PhoneLookup.DISPLAY_NAME,ContactsContract.PhoneLookup._ID}; // encode the phone number and build the filter URI Uri contactUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number)); // query time Cursor cursor = getContentResolver().query(contactUri, projection, null, null, null); if (cursor.moveToFirst()) { // Get values from contacts database: contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup._ID)); name = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME)); } else { return; // contact not found } int currentapiVersion = android.os.Build.VERSION.SDK_INT; if (currentapiVersion >= 14) { Uri my_contact_Uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(contactId)); photo_stream = ContactsContract.Contacts.openContactPhotoInputStream(getContentResolver(), my_contact_Uri, true); } else { Uri my_contact_Uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(contactId)); photo_stream = ContactsContract.Contacts.openContactPhotoInputStream(getContentResolver(), my_contact_Uri); } if(photo_stream != null) { BufferedInputStream buf =new BufferedInputStream(photo_stream); Bitmap my_btmp = BitmapFactory.decodeStream(buf); profile.setImageBitmap(my_btmp); } else { profile.setImageResource(R.drawable.contactpic); } cursor.close(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public void onClick(View v) { // TODO Auto-generated method stub if(v.getId() == answerButton.getId()) { timerLayout.setVisibility(0); startTime = SystemClock.uptimeMillis(); customHandler.postDelayed(updateTimerThread, 0); callType.clearAnimation(); // Simulate a press of the headset button to pick up the call Intent buttonDown = new Intent(Intent.ACTION_MEDIA_BUTTON); buttonDown.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK)); this.sendOrderedBroadcast(buttonDown, "android.permission.CALL_PRIVILEGED"); // froyo and beyond trigger on buttonUp instead of buttonDown Intent buttonUp = new Intent(Intent.ACTION_MEDIA_BUTTON); buttonUp.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK)); this.sendOrderedBroadcast(buttonUp, "android.permission.CALL_PRIVILEGED"); } if(v.getId() == rejectButton.getId()) { RejectCall(); } } private void RejectCall() { TelephonyManager telephony = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE); try { // Java reflection to gain access to TelephonyManager's // ITelephony getter Class c = Class.forName(telephony.getClass().getName()); Method m = c.getDeclaredMethod("getITelephony"); m.setAccessible(true); com.android.internal.telephony.ITelephony telephonyService = (ITelephony) m.invoke(telephony); telephonyService.endCall(); finish(); timeSwapBuff += timeInMilliseconds; customHandler.removeCallbacks(updateTimerThread); } catch (Exception e) { e.printStackTrace(); Log.e("Error", "FATAL ERROR: could not connect to telephony subsystem"); Log.e("Error", "Exception object: " + e); } } private Runnable updateTimerThread = new Runnable() { public void run() { timeInMilliseconds = SystemClock.uptimeMillis() - startTime; updatedTime = timeSwapBuff + timeInMilliseconds; int secs = (int) (updatedTime / 1000); int mins = secs / 60; int hours = mins / 60; secs = secs % 60; int milliseconds = (int) (updatedTime % 1000); timerValue.setText(""+ hours + ":" + String.format("%02d", mins) + ":" + String.format("%02d", secs)); customHandler.postDelayed(this, 0); } }; } 
+10
android android-manifest
source share
2 answers

For outgoing calls: I did the following and it works fine. I created an outbound receiver with all the permissions needed in the manifest.

Invoking activity after a delay using a handler.

Like this:

 @Override public void onReceive(Context context, Intent intent) { c = context; setResultData(null); phonenumber = getResultData(); if (phonenumber == null) { phonenumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); } setResultData(phonenumber); callActionHandler.postDelayed(runRingingActivity, 1000); } Handler callActionHandler = new Handler(); Runnable runRingingActivity = new Runnable() { @Override public void run() { Intent intentPhoneCall = new Intent(c, OutgoingCallActivity.class); intentPhoneCall.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intentPhoneCall.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); c.startActivity(intentPhoneCall); } }; 

You can use the phone number to send it to a new action.

Let me know if you have any questions!

+5
source share

I can’t get the incoming call screen ... I can only see the default screen for making a call, not for receiving a call ......

0
source share

All Articles