private String asText(JSONObject obj) {
   StringBuilder status = new StringBuilder();
   String a = obj.optString(ACTION);
   String b = obj.optString(NUMBER);
   if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(a)) {
     status.append("Calling ");
   } else if (TelephonyManager.EXTRA_STATE_IDLE.equals(a)) {
     status.append("Ending phone call with ");
   } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(a)) {
     status.append("Inbound call from ");
   }
   status.append(b).append(".");
   return status.toString();
 }
        @Override
        public void onReceive(Context context, Intent intent) {
          final String action = intent.getAction();
          if (action.equals(DELAYED_KEYGUARD_ACTION)) {

            int sequence = intent.getIntExtra("seq", 0);

            if (DEBUG)
              Log.d(
                  TAG,
                  "received DELAYED_KEYGUARD_ACTION with seq = "
                      + sequence
                      + ", mDelayedShowingSequence = "
                      + mDelayedShowingSequence);

            synchronized (KeyguardViewMediator.this) {
              if (mDelayedShowingSequence == sequence) {
                // Don't play lockscreen SFX if the screen went off due to
                // timeout.
                mSuppressNextLockSound = true;

                doKeyguardLocked();
              }
            }
          } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
            mPhoneState = intent.getStringExtra(TelephonyManager.EXTRA_STATE);

            synchronized (KeyguardViewMediator.this) {
              if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState) // call ending
                  && !mScreenOn // screen off
                  && mExternallyEnabled) { // not disabled by any app

                // note: this is a way to gracefully reenable the keyguard when the call
                // ends and the screen is off without always reenabling the keyguard
                // each time the screen turns off while in call (and having an occasional ugly
                // flicker while turning back on the screen and disabling the keyguard again).
                if (DEBUG)
                  Log.d(
                      TAG,
                      "screen is off and call ended, let's make sure the " + "keyguard is showing");
                doKeyguardLocked();
              }
            }
          }
        }
  /**
   * Handle message sent by {@link #hideLocked()}
   *
   * @see #HIDE
   */
  private void handleHide() {
    synchronized (KeyguardViewMediator.this) {
      if (DEBUG) Log.d(TAG, "handleHide");
      if (mWakeAndHandOff.isHeld()) {
        Log.w(TAG, "attempt to hide the keyguard while waking, ignored");
        return;
      }

      // only play "unlock" noises if not on a call (since the incall UI
      // disables the keyguard)
      if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)) {
        playSounds(false);
      }

      mKeyguardViewManager.hide();
      mShowing = false;
      adjustUserActivityLocked();
      adjustStatusBarLocked();
    }
  }
  @Override
  public void onReceive(final Context context, Intent intent) {
    if (!Preferences.getBoolean(R.string.p_field_missed_calls, false)) {
      Preferences.clear(PREF_LAST_INCOMING_NUMBER);
      return;
    }

    String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);

    if (TelephonyManager.EXTRA_STATE_RINGING.equals(state)) {
      String number = digitsOnly(intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER));
      if (TextUtils.isEmpty(number)) return;

      Preferences.setString(PREF_LAST_INCOMING_NUMBER, number);
    } else if (TelephonyManager.EXTRA_STATE_IDLE.equals(state)) {
      final String lastNumber = Preferences.getStringValue(PREF_LAST_INCOMING_NUMBER);
      if (TextUtils.isEmpty(lastNumber)) {
        return;
      }

      Preferences.clear(PREF_LAST_INCOMING_NUMBER);

      new Thread() {
        @Override
        public void run() {
          AndroidUtilities.sleepDeep(WAIT_BEFORE_READ_LOG);
          Cursor calls =
              context
                  .getContentResolver()
                  .query(
                      Calls.CONTENT_URI,
                      new String[] {Calls.NUMBER, Calls.DATE, Calls.CACHED_NAME},
                      Calls.TYPE + " = ? AND " + Calls.NEW + " = ?",
                      new String[] {Integer.toString(Calls.MISSED_TYPE), "1"},
                      Calls.DATE + " DESC");
          try {
            if (calls == null) return;
            if (calls.moveToFirst()) {
              int numberIndex = calls.getColumnIndex(Calls.NUMBER);
              String number = calls.getString(numberIndex);

              // Sanity check for phone number match
              // in case the phone logs haven't updated for some reaosn
              if (!lastNumber.equals(digitsOnly(number))) {
                return;
              }

              // If a lot of time has passed since the most recent missed call, ignore
              // It could be the same person calling you back before you call them back,
              // but if you answer this time, the missed call will still be in the database
              // and will be processed again.
              int dateIndex = calls.getColumnIndex(Calls.DATE);
              long date = calls.getLong(dateIndex);
              if (DateUtilities.now() - date > 2 * DateUtilities.ONE_MINUTE) {
                return;
              }

              int nameIndex = calls.getColumnIndex(Calls.CACHED_NAME);
              String name = calls.getString(nameIndex);

              String timeString = DateUtilities.getTimeString(context, new Date(date));

              long contactId = getContactIdFromNumber(context, number);

              Intent missedCallIntent = new Intent(context, MissedCallActivity.class);
              missedCallIntent.putExtra(MissedCallActivity.EXTRA_NUMBER, number);
              missedCallIntent.putExtra(MissedCallActivity.EXTRA_NAME, name);
              missedCallIntent.putExtra(MissedCallActivity.EXTRA_TIME, timeString);
              missedCallIntent.putExtra(MissedCallActivity.EXTRA_CONTACT_ID, contactId);
              missedCallIntent.setFlags(
                  Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
              context.startActivity(missedCallIntent);
            }
          } finally {
            if (calls != null) calls.close();
          }
        }
      }.start();
    }
  }