如何在我的应用程序中获取 phone 组织工作配置文件的调用日志历史记录(发布为私有应用程序)

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

在这里,我试图在调用结束并发布 apk (Published on play store as public app) 后获取我的应用程序中的最后一次调用日志历史记录。 现在我已经为一个组织发布了我的应用程序 private app 我无法在我的私人应用程序中获取通话记录历史记录,

为了获取通话记录历史,我开发了如下代码:

  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();
  }
 }

概览:

当尝试给工作联系人打电话或发送短信时,首先会收到一条消息:

您正在工作资料之外使用此应用。

然后可以给联系人打电话或发短信,但是短信或通话记录只会显示联系人 Phone 号码,不会显示姓名。

同样,来电时不显示联系方式。

原因: Phone 和 SMS 应用程序是在个人资料中设计和存放的,当在 Android 上为工作激活时,联系人应用程序存放在工作资料中。由于 Android 5.1.1 及更早版本的限制,这两个配置文件无法相互通信,因此只能看到 Phone 号码。这发生在任何 Android 设备上,并非特定于制造商。更多信息请见:

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

分辨率: 升级到 Android 6.0 Marshmallow。在 Android 6.0 Marshmallow Google 中宣布了对企业联系人的改进。 Android 工作激活设备在个人 Phone 和短信应用

上显示工作联系信息

请注意,访问工作联系信息的能力仅在 Google 的 Phone 和 Google 的 Messenger 应用程序中验证可用。