Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get phone call log history of organisation work profile in my application (Published as Private app)

Here I am trying to get last call log history in my application after call ended with released apk (Published on play store as public app). Now I have released my app as private app for one organization I am not able to get call log history in my private application,

To get call log history I have developed code as below:

  public class CallLogListener extends BroadcastReceiver {

  private String tag = "CallLogListener";
  History h;
  Call call;

  /**
   * This method is called when BroadcastReceiver receive some action from another app
   *
   * @param mContext Context which is received by BroadcastReceiver
   * @param i        Intent which is received by BroadcastReceiver
   */
  @Override
  public void onReceive(Context mContext, Intent i) {
      // TODO Auto-generated method stub
      try {
          h = new History(new Handler(), mContext, "0");
          mContext.getContentResolver().registerContentObserver(CallLog.Calls.CONTENT_URI, true, h);
          Bundle bundle = i.getExtras();
          if (bundle == null)
              return;
          SharedPreferences sp = mContext.getSharedPreferences(Constants.CallLogConstants.PREF_CALL_LOG, Activity.MODE_PRIVATE);
          savePrefBoolean(mContext, mContext.getString(R.string.IS_PHONE_CALL_STATE_BUSY), true);
          String s = bundle.getString(TelephonyManager.EXTRA_STATE);

          if (i.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) { // call when call is in outgoing state
              Calendar calendar = Calendar.getInstance();
              calendar.setTimeInMillis(System.currentTimeMillis());
              String number = i.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
              sp.edit().putString(Constants.DatabaseConstants.EXTRA_NUMBER, number).commit();
              sp.edit().putString(Constants.DatabaseConstants.EXTRA_STATE, "OutGoing Call").commit();
              sp.edit().putLong(Constants.DatabaseConstants.EXTRA_START_TIME, System.currentTimeMillis()).commit();
          } else if (s.equals(TelephonyManager.EXTRA_STATE_RINGING)) { // call when call is in incoming ringing state
              String number = bundle.getString("incoming_number");
              sp.edit().putString(Constants.DatabaseConstants.EXTRA_NUMBER, number).commit();
              sp.edit().putString(Constants.DatabaseConstants.EXTRA_STATE, s).commit();
          } else if (s.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) { // call when call is in offhook state
              sp.edit().putString(Constants.DatabaseConstants.EXTRA_STATE, s).commit();
          } else if (s.equals(TelephonyManager.EXTRA_STATE_IDLE)) { // call when call is in idle state
              savePrefBoolean(mContext, mContext.getString(R.string.IS_PHONE_CALL_STATE_BUSY), false);
              String state = sp.getString(Constants.DatabaseConstants.EXTRA_STATE, null);
              if (!state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
                  Calendar calendar = Calendar.getInstance();
                  calendar.setTimeInMillis(System.currentTimeMillis());
                  long temp = sp.getLong(Constants.DatabaseConstants.EXTRA_START_TIME, 0);
                  String duration = String.valueOf((temp - System.currentTimeMillis()) / 1000);
                  showLog(tag, "duration =  " + duration, Constants.LogConstants.LOG_I, null);
                  duration = StringUtils.trim(duration.replaceAll("\\D+", ""));
                  sp.edit().putString(Constants.DatabaseConstants.EXTRA_STATE, null).commit();
                  sp.edit().putLong(Constants.DatabaseConstants.EXTRA_START_TIME, 0).commit();
                  sp.edit().putString("call_duration", duration).commit();
                  h = new History(new Handler(), mContext, StringUtils.trim(duration.replaceAll("\\D+", "")));
                  mContext.getContentResolver().registerContentObserver(CallLog.Calls.CONTENT_URI, true, h);
              }
              sp.edit().putString(Constants.DatabaseConstants.EXTRA_STATE, s).commit();
          }
      } catch (Exception e) {
          Crashlytics.logException(e);
      }
  }
}


public class History extends ContentObserver {

  private String tag; // Tag

  private Context mContext;
  private Cursor managedCursor;
  private boolean isCallEnd = false;
  private String TotalCallDuration;
  private CallInfo mCallInfo;

  /**
   * History is ContentObserver for call log
   *
   * @param handler  activity handler
   * @param cc       Context of an activity
   * @param duration total call duration ringing time and actual talk time.
   */
  public History(Handler handler, Context cc, String duration) {
      // TODO Auto-generated constructor stub
      super(handler);
      tag = History.class.getSimpleName(); // Tag
      mContext = cc;
      this.TotalCallDuration = duration;
  }

  /**
   * This is Overrided method of ContentObserver
   *
   * @return boolean where true or false
   */
  @Override
  public boolean deliverSelfNotifications() {
      return true;
  }

  /**
   * This is Overrided method of ContentObserver to check when call log is change
   *
   * @param selfChange to check if any thing change in call log
   */
  @Override
  public void onChange(boolean selfChange) {
      // TODO Auto-generated method stub
      super.onChange(selfChange);
      try {
          SharedPreferences sp = mContext.getSharedPreferences(Constants.CallLogConstants.PREF_CALL_LOG, Activity.MODE_PRIVATE);
          String number = sp.getString(Constants.DatabaseConstants.EXTRA_NUMBER, null);
          String timeDuration = sp.getString("call_duration", "0");
          if (number != null) {
              getCalldetailsNow(timeDuration);
              sp.edit().putString(Constants.DatabaseConstants.EXTRA_NUMBER, null).commit();
              sp.edit().putString("call_duration", "0").commit();
          }
      } catch (Exception e) {
          Crashlytics.logException(e);
      }
  }

  /**
   * Function to get call details using getContentResolver
   * and store call information in database
   *
   * @throws Exception this will throws exception and handles in root method
   */
  private void getCalldetailsNow(String timeDuration) throws Exception {
      // TODO Auto-generated method stub
      if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
          // TODO: Consider calling
          //    ActivityCompat#requestPermissions
          // here to request the missing permissions, and then overriding
          //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
          //                                          int[] grantResults)
          // to handle the case where the user grants the permission. See the documentation
          // for ActivityCompat#requestPermissions for more details.
          return;
      }
      managedCursor = mContext.getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null, null, CallLog.Calls.DATE + " DESC");

      int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
      int formatedNumber = managedCursor.getColumnIndex(CallLog.Calls.CACHED_FORMATTED_NUMBER);
      int duration1 = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
      int type1 = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
      int date1 = managedCursor.getColumnIndex(CallLog.Calls.DATE);

      boolean isMoveTofirst = managedCursor.moveToFirst();
      showToast(mContext, "12 :: managedCursor.moveToFirst() " + isMoveTofirst);
      if (isMoveTofirst == true) {
          String phNumber = managedCursor.getString(number);
          String phFormatedNumber = managedCursor.getString(formatedNumber);
          String strCallDuration;
          strCallDuration = managedCursor.getString(duration1);
          String callAnswered = strCallDuration.equalsIgnoreCase("0") ? Constants.CallHistoryListConstants.CALL_STATE_NOT_ANSWERED : Constants.CallHistoryListConstants.CALL_STATE_ANSWERED;

          String type = managedCursor.getString(type1);
          showToast(mContext, "13 :: type " + type);
          String date = managedCursor.getString(date1);
          CommonUtils.showLog(tag, "date = " + date, Constants.LogConstants.LOG_E, null);

          String dir = null;
          int dircode = Integer.parseInt(type);
          switch (dircode) {
              case CallLog.Calls.OUTGOING_TYPE:
                  dir = "OUTGOING";
                  isCallEnd = true;
                  break;
              case CallLog.Calls.INCOMING_TYPE:
                  dir = "INCOMING";
                  timeDuration = strCallDuration;
                  isCallEnd = true;
                  break;
              default:
                  dir = "INCOMING";
                  callAnswered = "MISSED";
                  timeDuration = "0";
                  isCallEnd = true;
                  break;
          }

          SimpleDateFormat sdf_date = new SimpleDateFormat("dd-M-yyyy", Locale.ENGLISH);
          SimpleDateFormat sdf_time = new SimpleDateFormat("HH:mm:ss", Locale.ENGLISH);
          // SimpleDateFormat sdf_dur = new SimpleDateFormat("KK:mm:ss");

          String dateString = sdf_date.format(new Date(Long.parseLong(date)));
          String timeString = sdf_time.format(new Date(Long.parseLong(date)));

          showLog(tag, "History.java :: phoneCallTalkTme = " + timeDuration, Constants.LogConstants.LOG_E, null);
          if (isCallEnd) {
              // create object of sugar orm module class and store data in local databse
              mCallInfo = new CallInfo(); // create object of call info table
              mCallInfo.setNumber(phNumber); // set number
              mCallInfo.setDate(dateString); // set date
              mCallInfo.setTime(timeString.replace(".", "")); // set time
              mCallInfo.setDuration(timeDuration); // set duration
              mCallInfo.setCallState(callAnswered); // set call state
              mCallInfo.setType(dir); // set call type
              mCallInfo.save();

              savePrefString(mContext, mContext.getString(R.string.BUNDLE_LAST_CALL_DURATION), timeDuration);
              savePrefString(mContext, mContext.getString(R.string.BUNDLE_LAST_CALL_TYPE), dir);
              savePrefString(mContext, mContext.getString(R.string.BUNDLE_LAST_CALL_STATUS), callAnswered);
              savePrefString(mContext, mContext.getString(R.string.BUNDLE_LAST_CALL_DATE), dateString + " " + timeString.replace(".", ""));
          }
      }
      managedCursor.close();
  }
 }
like image 282
Dhaval Travadi Avatar asked Nov 08 '22 13:11

Dhaval Travadi


1 Answers

Overview :

When trying to call or send SMS to Work Contacts, one is first presented with a message:

You're using this app outside of your work profile.

One is then able to call or text the contact, however the SMS message or Call Log will only show the contact Phone Number and no name is displayed.

Similarly, no contact details are displayed when receiving a call.

Cause : The Phone and SMS apps are designed and housed in the Personal Profile and when activated on Android for Work the Contacts app is housed in the Work Profile. Due to limitations in Android 5.1.1 and earlier these two profiles cannot communicate with each other, thus only the Phone Number is seen. This happens on any Android Device not specific to manufacturer. For more information, please see:

https://support.google.com/work/android/answer/6275589?hl=en

Resolution : Upgrade to Android 6.0 Marshmallow. In Android 6.0 Marshmallow Google had announced improvements for Enterprise Contacts. Android for Work activated devices display Work Contact information on Personal Phone and SMS apps

Note that the ability to access work contact information is only verified as available in Google's Phone and Google's Messenger applications.

like image 84
chandrakant sharma Avatar answered Nov 15 '22 12:11

chandrakant sharma