/**
   * Target and initiator should successfully connect to a "remote" SOCKS5 proxy and the initiator
   * activates the bytestream.
   *
   * @throws Exception should not happen
   */
  @Test
  public void shouldSuccessfullyEstablishConnectionAndActivateSocks5Proxy() throws Exception {

    // build activation confirmation response
    IQ activationResponse =
        new IQ() {

          @Override
          public String getChildElementXML() {
            return null;
          }
        };
    activationResponse.setFrom(proxyJID);
    activationResponse.setTo(initiatorJID);
    activationResponse.setType(IQ.Type.RESULT);

    protocol.addResponse(
        activationResponse,
        Verification.correspondingSenderReceiver,
        Verification.requestTypeSET,
        new Verification<Bytestream, IQ>() {

          public void verify(Bytestream request, IQ response) {
            // verify that the correct stream should be activated
            assertNotNull(request.getToActivate());
            assertEquals(targetJID, request.getToActivate().getTarget());
          }
        });

    // start a local SOCKS5 proxy
    Socks5TestProxy socks5Proxy = Socks5TestProxy.getProxy(proxyPort);
    socks5Proxy.start();

    StreamHost streamHost = new StreamHost(proxyJID, socks5Proxy.getAddress());
    streamHost.setPort(socks5Proxy.getPort());

    // create digest to get the socket opened by target
    String digest = Socks5Utils.createDigest(sessionID, initiatorJID, targetJID);

    Socks5ClientForInitiator socks5Client =
        new Socks5ClientForInitiator(streamHost, digest, connection, sessionID, targetJID);

    Socket initiatorSocket = socks5Client.getSocket(10000);
    InputStream in = initiatorSocket.getInputStream();

    Socket targetSocket = socks5Proxy.getSocket(digest);
    OutputStream out = targetSocket.getOutputStream();

    // verify test data
    for (int i = 0; i < 10; i++) {
      out.write(i);
      assertEquals(i, in.read());
    }

    protocol.verifyAll();

    initiatorSocket.close();
    targetSocket.close();
    socks5Proxy.stop();
  }
  /** Loads streamhost address and ports from the proxies on the local server. */
  private void initStreamHosts() {
    List<Bytestream.StreamHost> streamHosts = new ArrayList<Bytestream.StreamHost>();
    Iterator it = proxies.iterator();
    IQ query;
    PacketCollector collector;
    Bytestream response;
    while (it.hasNext()) {
      String jid = it.next().toString();
      query =
          new IQ() {
            public String getChildElementXML() {
              return "<query xmlns=\"http://jabber.org/protocol/bytestreams\"/>";
            }
          };
      query.setType(IQ.Type.GET);
      query.setTo(jid);

      collector = connection.createPacketCollector(new PacketIDFilter(query.getPacketID()));
      connection.sendPacket(query);

      response = (Bytestream) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
      if (response != null) {
        streamHosts.addAll(response.getStreamHosts());
      }
      collector.cancel();
    }
    this.streamHosts = streamHosts;
  }
  public CommandWithReplyImpl(XmppConnection con, Packet packet) {

    connection = con;
    packetID = packet.getPacketID();

    // Setup a collector to receive the servers response
    collector = connection.createPacketCollector(new PacketIDFilter(packetID));

    // Get the subscription id if applicable
    subscriptionID = null;
    subidPattern = Pattern.compile("subid=[\"']([\\w-]+?)[\"']");

    // Set the results from the command to null
    result = null;

    if (connection.isConnected()) {
      try {
        connection.sendPacket(packet);
      } catch (IllegalStateException e) {
        // set result to an error
        result = new ArbitraryIQ();
        result.setType(IQ.Type.ERROR);
      }
    }
  }
 private static IQ error(IQ packet) {
   IQ error = new EmptyResultIQ(packet);
   error.setType(IQ.Type.error);
   error.setError(new XMPPError(Condition.forbidden));
   error.setStanzaId(packet.getStanzaId());
   error.setTo(packet.getFrom());
   return error;
 }
Esempio n. 5
0
 protected void sendUserWatching() {
   IQ toggle_google_queue =
       new IQ() {
         public String getChildElementXML() {
           return "<query xmlns='google:queue'><"
               + (isUserWatching ? "disable" : "enable")
               + "/></query>";
         }
       };
   toggle_google_queue.setType(IQ.Type.SET);
   extXMPPConnection.sendPacket(toggle_google_queue);
 }
Esempio n. 6
0
 private IQ carbonsEnabledIQ(final boolean new_state) {
   IQ setIQ =
       new IQ() {
         public String getChildElementXML() {
           return "<"
               + (new_state ? "enable" : "disable")
               + " xmlns='"
               + CarbonExtension.NAMESPACE
               + "'/>";
         }
       };
   setIQ.setType(IQ.Type.SET);
   return setIQ;
 }
  /**
   * A convenience method to create an IQ packet.
   *
   * @param ID The packet ID of the
   * @param to To whom the packet is addressed.
   * @param from From whom the packet is sent.
   * @param type The IQ type of the packet.
   * @return The created IQ packet.
   */
  public static IQ createIQ(
      final String ID, final String to, final String from, final IQ.Type type) {
    final IQ iqPacket =
        new IQ() {
          @Override
          public String getChildElementXML() {
            return null;
          }
        };
    iqPacket.setPacketID(ID);
    iqPacket.setTo(to);
    iqPacket.setFrom(from);
    iqPacket.setType(type);

    return iqPacket;
  }
Esempio n. 8
0
 /**
  * Convenience method to create a new empty {@link Type#RESULT IQ.Type.RESULT} IQ based on a
  * {@link Type#GET IQ.Type.GET} or {@link Type#SET IQ.Type.SET} IQ. The new packet will be
  * initialized with:
  *
  * <ul>
  *   <li>The sender set to the recipient of the originating IQ.
  *   <li>The recipient set to the sender of the originating IQ.
  *   <li>The type set to {@link Type#RESULT IQ.Type.RESULT}.
  *   <li>The id set to the id of the originating IQ.
  *   <li>No child element of the IQ element.
  * </ul>
  *
  * @param iq the {@link Type#GET IQ.Type.GET} or {@link Type#SET IQ.Type.SET} IQ packet.
  * @throws IllegalArgumentException if the IQ packet does not have a type of {@link Type#GET
  *     IQ.Type.GET} or {@link Type#SET IQ.Type.SET}.
  * @return a new {@link Type#RESULT IQ.Type.RESULT} IQ based on the originating IQ.
  */
 public static IQ createResultIQ(final IQ request) {
   if (!(request.getType() == Type.GET || request.getType() == Type.SET)) {
     throw new IllegalArgumentException(
         "IQ must be of type 'set' or 'get'. Original IQ: " + request.toXML());
   }
   final IQ result =
       new IQ() {
         public String getChildElementXML() {
           return null;
         }
       };
   result.setType(Type.RESULT);
   result.setPacketID(request.getPacketID());
   result.setFrom(request.getTo());
   result.setTo(request.getFrom());
   return result;
 }
  /**
   * If the initiator can connect to a SOCKS5 proxy but activating the stream fails an exception
   * should be thrown.
   *
   * @throws Exception should not happen
   */
  @Test
  public void shouldFailIfActivateSocks5ProxyFails() throws Exception {

    // build error response as reply to the stream activation
    XMPPError xmppError = new XMPPError(XMPPError.Condition.internal_server_error);
    IQ error =
        new IQ() {

          public String getChildElementXML() {
            return null;
          }
        };
    error.setType(Type.ERROR);
    error.setFrom(proxyJID);
    error.setTo(initiatorJID);
    error.setError(xmppError);

    protocol.addResponse(
        error, Verification.correspondingSenderReceiver, Verification.requestTypeSET);

    // start a local SOCKS5 proxy
    Socks5TestProxy socks5Proxy = Socks5TestProxy.getProxy(proxyPort);
    socks5Proxy.start();

    StreamHost streamHost = new StreamHost(proxyJID, socks5Proxy.getAddress());
    streamHost.setPort(socks5Proxy.getPort());

    // create digest to get the socket opened by target
    String digest = Socks5Utils.createDigest(sessionID, initiatorJID, targetJID);

    Socks5ClientForInitiator socks5Client =
        new Socks5ClientForInitiator(streamHost, digest, connection, sessionID, targetJID);

    try {

      socks5Client.getSocket(10000);

      fail("exception should be thrown");
    } catch (XMPPErrorException e) {
      assertTrue(XMPPError.Condition.internal_server_error.equals(e.getXMPPError().getCondition()));
      protocol.verifyAll();
    }

    socks5Proxy.stop();
  }
Esempio n. 10
0
 /**
  * Convenience method to create a new {@link Type#ERROR IQ.Type.ERROR} IQ based on a {@link
  * Type#GET IQ.Type.GET} or {@link Type#SET IQ.Type.SET} IQ. The new packet will be initialized
  * with:
  *
  * <ul>
  *   <li>The sender set to the recipient of the originating IQ.
  *   <li>The recipient set to the sender of the originating IQ.
  *   <li>The type set to {@link Type#ERROR IQ.Type.ERROR}.
  *   <li>The id set to the id of the originating IQ.
  *   <li>The child element contained in the associated originating IQ.
  *   <li>The provided {@link XMPPError XMPPError}.
  * </ul>
  *
  * @param iq the {@link Type#GET IQ.Type.GET} or {@link Type#SET IQ.Type.SET} IQ packet.
  * @param error the error to associate with the created IQ packet.
  * @throws IllegalArgumentException if the IQ packet does not have a type of {@link Type#GET
  *     IQ.Type.GET} or {@link Type#SET IQ.Type.SET}.
  * @return a new {@link Type#ERROR IQ.Type.ERROR} IQ based on the originating IQ.
  */
 public static IQ createErrorResponse(final IQ request, final XMPPError error) {
   if (!(request.getType() == Type.GET || request.getType() == Type.SET)) {
     throw new IllegalArgumentException(
         "IQ must be of type 'set' or 'get'. Original IQ: " + request.toXML());
   }
   final IQ result =
       new IQ() {
         public String getChildElementXML() {
           return request.getChildElementXML();
         }
       };
   result.setType(Type.ERROR);
   result.setPacketID(request.getPacketID());
   result.setFrom(request.getTo());
   result.setTo(request.getFrom());
   result.setError(error);
   return result;
 }
Esempio n. 11
0
  /**
   * FIXME: replace with IQ.createErrorResponse Prosody does not allow to include request body in
   * error response. Replace this method with IQ.createErrorResponse once fixed.
   */
  private IQ createErrorResponse(IQ request, XMPPError error) {
    IQ.Type requestType = request.getType();
    if (!(requestType == IQ.Type.GET || requestType == IQ.Type.SET)) {
      throw new IllegalArgumentException(
          "IQ must be of type 'set' or 'get'. Original IQ: " + request.toXML());
    }

    final IQ result =
        new IQ() {
          @Override
          public String getChildElementXML() {
            return "";
          }
        };
    result.setType(IQ.Type.ERROR);
    result.setPacketID(request.getPacketID());
    result.setFrom(request.getTo());
    result.setTo(request.getFrom());
    result.setError(error);
    return result;
  }
  /**
   * Sends enable or disable carbon packet to the server.
   *
   * @param enable if <tt>true</tt> sends enable packet otherwise sends disable packet.
   */
  private void enableDisableCarbon(final boolean enable) {
    IQ iq =
        new IQ() {

          @Override
          public String getChildElementXML() {
            return "<" + (enable ? "enable" : "disable") + " xmlns='urn:xmpp:carbons:2' />";
          }
        };

    Packet response = null;
    try {
      PacketCollector packetCollector =
          jabberProvider
              .getConnection()
              .createPacketCollector(new PacketIDFilter(iq.getPacketID()));
      iq.setFrom(jabberProvider.getOurJID());
      iq.setType(IQ.Type.SET);
      jabberProvider.getConnection().sendPacket(iq);
      response = packetCollector.nextResult(SmackConfiguration.getPacketReplyTimeout());

      packetCollector.cancel();
    } catch (Exception e) {
      logger.error("Failed to enable carbon.", e);
    }

    isCarbonEnabled = false;

    if (response == null) {
      logger.error("Failed to enable carbon. No response is received.");
    } else if (response.getError() != null) {
      logger.error("Failed to enable carbon: " + response.getError());
    } else if (!(response instanceof IQ) || !((IQ) response).getType().equals(IQ.Type.RESULT)) {
      logger.error("Failed to enable carbon. The response is not correct.");
    } else {
      isCarbonEnabled = true;
    }
  }
Esempio n. 13
0
  public void notify(
      String notificationId,
      String notificationApiKey,
      String notificationTitle,
      String notificationMessage,
      String notificationUri,
      String from,
      String packetId) {
    final MediaPlayer mp = MediaPlayer.create(context, R.raw.dd);
    // TODO FIXME 发送查看回执
    IQ result =
        new IQ() {
          @Override
          public String getChildElementXML() {
            return null;
          }
        };
    result.setType(Type.RESULT);
    try {
      Constants.xmppManager.getConnection().sendPacket(result);
    } catch (Exception e) {
    }
    if (notificationTitle.equals("聊天")) {
      ActivityManager activityManager =
          (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
      String runningActivity = activityManager.getRunningTasks(1).get(0).topActivity.getClassName();
      if (runningActivity.equals("com.huake.wit_tour.LangMan_LTActivity")) {
        // 如果当前运行的activity是聊天界面,那么做处理
        String s[] = notificationMessage.split(",");
        String tstId = s[0];
        if (LangMan_LTActivity.instance.getuid(tstId)) {
          LangMan_LTActivity.instance.receiveMessage(s[4], s[5]);
        } else {
          // 如果是另一个pad上面发送来的信息则重新声音提示
          mp.start();
          String testid = KeepTSData.readNotificationId(context);
          if (testid.equals("")) {
            KeepTSData.keepUser(
                context,
                notificationId,
                notificationApiKey,
                notificationTitle,
                notificationMessage,
                notificationUri);
          } else {
            String id = KeepTSData.readNotificationId(context) + "@" + notificationId;
            String apikey = KeepTSData.readNotificationApiKey(context) + "@" + notificationApiKey;
            String title = KeepTSData.readNotificationTitle(context) + "@" + notificationTitle;
            String message =
                KeepTSData.readNotificationMessage(context) + "@" + notificationMessage;
            String uri = KeepTSData.readNotificationUri(context) + "@" + notificationUri;

            KeepTSData.keepUser(context, id, apikey, title, message, uri);
          }
          MainActivity.instance.set_TS();
          new Thread() {
            public void run() {
              try {
                sleep(4000);
              } catch (Exception e) {
              }
              mp.release();
            };
          }.start();
        }
      } else {
        // 如果不是聊天界面
        mp.start();
        String testid = KeepTSData.readNotificationId(context);
        if (testid.equals("")) {
          KeepTSData.keepUser(
              context,
              notificationId,
              notificationApiKey,
              notificationTitle,
              notificationMessage,
              notificationUri);
        } else {
          String id = KeepTSData.readNotificationId(context) + "@" + notificationId;
          String apikey = KeepTSData.readNotificationApiKey(context) + "@" + notificationApiKey;
          String title = KeepTSData.readNotificationTitle(context) + "@" + notificationTitle;
          String message = KeepTSData.readNotificationMessage(context) + "@" + notificationMessage;
          String uri = KeepTSData.readNotificationUri(context) + "@" + notificationUri;

          KeepTSData.keepUser(context, id, apikey, title, message, uri);
        }
        MainActivity.instance.set_TS();
        new Thread() {
          public void run() {
            try {
              sleep(4000);
            } catch (Exception e) {
            }
            mp.release();
          };
        }.start();
      }

    } else {
      mp.start();
      String testid = KeepTSData.readNotificationId(context);
      if (testid.equals("")) {
        KeepTSData.keepUser(
            context,
            notificationId,
            notificationApiKey,
            notificationTitle,
            notificationMessage,
            notificationUri);
      } else {
        String id = KeepTSData.readNotificationId(context) + "@" + notificationId;
        String apikey = KeepTSData.readNotificationApiKey(context) + "@" + notificationApiKey;
        String title = KeepTSData.readNotificationTitle(context) + "@" + notificationTitle;
        String message = KeepTSData.readNotificationMessage(context) + "@" + notificationMessage;
        String uri = KeepTSData.readNotificationUri(context) + "@" + notificationUri;
        KeepTSData.keepUser(context, id, apikey, title, message, uri);
      }
      MainActivity.instance.set_TS();
      new Thread() {
        public void run() {
          try {
            sleep(4000);
          } catch (Exception e) {

          }
          mp.release();
        };
      }.start();
    }
  }
Esempio n. 14
0
  /**
   * Parses an IQ packet.
   *
   * @param parser the XML parser, positioned at the start of an IQ packet.
   * @return an IQ object.
   * @throws Exception if an exception occurs while parsing the packet.
   */
  public static IQ parseIQ(XmlPullParser parser, Connection connection) throws Exception {
    IQ iqPacket = null;

    String id = parser.getAttributeValue("", "id");
    String to = parser.getAttributeValue("", "to");
    String from = parser.getAttributeValue("", "from");
    IQ.Type type = IQ.Type.fromString(parser.getAttributeValue("", "type"));
    XMPPError error = null;

    boolean done = false;
    while (!done) {
      int eventType = parser.next();

      if (eventType == XmlPullParser.START_TAG) {
        String elementName = parser.getName();
        String namespace = parser.getNamespace();
        if (elementName.equals("error")) {
          error = PacketParserUtils.parseError(parser);
        } else if (elementName.equals("query") && namespace.equals("jabber:iq:auth")) {
          iqPacket = parseAuthentication(parser);
        } else if (elementName.equals("query") && namespace.equals("jabber:iq:roster")) {
          iqPacket = parseRoster(parser);
        } else if (elementName.equals("query") && namespace.equals("jabber:iq:register")) {
          iqPacket = parseRegistration(parser);
        } else if (elementName.equals("bind")
            && namespace.equals("urn:ietf:params:xml:ns:xmpp-bind")) {
          iqPacket = parseResourceBinding(parser);
        }
        // Otherwise, see if there is a registered provider for
        // this element name and namespace.
        else {
          Object provider = ProviderManager.getInstance().getIQProvider(elementName, namespace);
          if (provider != null) {
            if (provider instanceof IQProvider) {
              iqPacket = ((IQProvider) provider).parseIQ(parser);
            } else if (provider instanceof Class) {
              iqPacket =
                  (IQ)
                      PacketParserUtils.parseWithIntrospection(
                          elementName, (Class<?>) provider, parser);
            }
          }
          // Only handle unknown IQs of type result. Types of 'get' and 'set' which are not
          // understood
          // have to be answered with an IQ error response. See the code a few lines below
          else if (IQ.Type.RESULT == type) {
            // No Provider found for the IQ stanza, parse it to an UnparsedIQ instance
            // so that the content of the IQ can be examined later on
            iqPacket = new UnparsedResultIQ(parseContent(parser));
          }
        }
      } else if (eventType == XmlPullParser.END_TAG) {
        if (parser.getName().equals("iq")) {
          done = true;
        }
      }
    }
    // Decide what to do when an IQ packet was not understood
    if (iqPacket == null) {
      if (IQ.Type.GET == type || IQ.Type.SET == type) {
        // If the IQ stanza is of type "get" or "set" containing a child element
        // qualified by a namespace it does not understand, then answer an IQ of
        // type "error" with code 501 ("feature-not-implemented")
        iqPacket =
            new IQ() {
              @Override
              public String getChildElementXML() {
                return null;
              }
            };
        iqPacket.setPacketID(id);
        iqPacket.setTo(from);
        iqPacket.setFrom(to);
        iqPacket.setType(IQ.Type.ERROR);
        iqPacket.setError(new XMPPError(XMPPError.Condition.feature_not_implemented));
        connection.sendPacket(iqPacket);
        return null;
      } else {
        // If an IQ packet wasn't created above, create an empty IQ packet.
        iqPacket =
            new IQ() {
              @Override
              public String getChildElementXML() {
                return null;
              }
            };
      }
    }

    // Set basic values on the iq packet.
    iqPacket.setPacketID(id);
    iqPacket.setTo(to);
    iqPacket.setFrom(from);
    iqPacket.setType(type);
    iqPacket.setError(error);

    return iqPacket;
  }
Esempio n. 15
0
 public static IQ parseIQ(XmlPullParser xmlPullParser)
     throws XmlPullParserException, IOException, SmackException {
   XMPPError xMPPError = null;
   ParserUtils.assertAtStartTag(xmlPullParser);
   int depth = xmlPullParser.getDepth();
   String attributeValue = xmlPullParser.getAttributeValue("", "id");
   String attributeValue2 = xmlPullParser.getAttributeValue("", PrivacyItem.SUBSCRIPTION_TO);
   String attributeValue3 = xmlPullParser.getAttributeValue("", PrivacyItem.SUBSCRIPTION_FROM);
   Type fromString = Type.fromString(xmlPullParser.getAttributeValue("", "type"));
   IQ iq = null;
   while (true) {
     switch (xmlPullParser.next()) {
       case VideoSize.HVGA /*2*/:
         XMPPError parseError;
         IQ iq2;
         String name = xmlPullParser.getName();
         String namespace = xmlPullParser.getNamespace();
         Object obj = -1;
         switch (name.hashCode()) {
           case 96784904:
             if (name.equals(XMPPError.ERROR)) {
               obj = null;
               break;
             }
             break;
         }
         switch (obj) {
           case VideoSize.QCIF /*0*/:
             parseError = parseError(xmlPullParser);
             iq2 = iq;
             break;
           default:
             IQProvider iQProvider = ProviderManager.getIQProvider(name, namespace);
             XMPPError xMPPError2;
             if (iQProvider == null) {
               xMPPError2 = xMPPError;
               iq2 = new UnparsedIQ(name, namespace, parseElement(xmlPullParser));
               parseError = xMPPError2;
               break;
             }
             xMPPError2 = xMPPError;
             iq2 = (IQ) iQProvider.parse(xmlPullParser);
             parseError = xMPPError2;
             break;
         }
         iq = iq2;
         xMPPError = parseError;
         break;
       case Version.API03_CUPCAKE_15 /*3*/:
         if (xmlPullParser.getDepth() != depth) {
           break;
         }
         if (iq == null) {
           switch (C01861.$SwitchMap$org$jivesoftware$smack$packet$IQ$Type[fromString.ordinal()]) {
             case VideoSize.CIF /*1*/:
               iq = new ErrorIQ(xMPPError);
               break;
             case VideoSize.HVGA /*2*/:
               iq = new EmptyResultIQ();
               break;
           }
         }
         iq.setStanzaId(attributeValue);
         iq.setTo(attributeValue2);
         iq.setFrom(attributeValue3);
         iq.setType(fromString);
         iq.setError(xMPPError);
         return iq;
       default:
         break;
     }
   }
 }
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    originSharedPrefs =
        this.getSharedPreferences(Constants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE);

    DisplayMetrics dm = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(dm);
    // 屏幕宽
    mobileWidthPix = dm.widthPixels;
    // 屏幕高
    mobileHeightPix = dm.heightPixels;

    density = dm.density; // 屏幕密度(0.75/1.0/1.5)
    Log.i("xiaobingo", "density是:" + density);
    // densityDPI = dm.densityDpi; //屏幕密度DPI (120/160/240)
    mobileWidth = (int) (mobileWidthPix / density + 0.5f);
    mobileHeight = (int) (mobileHeightPix / density + 0.5f);
    Log.i("xiaobingo", "屏幕宽:" + mobileWidth);
    Log.i("xiaobingo", "屏幕高:" + mobileHeight);

    SharedPreferences sharedPrefs =
        this.getSharedPreferences(Constants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE);
    callbackActivityPackageName =
        sharedPrefs.getString(Constants.CALLBACK_ACTIVITY_PACKAGE_NAME, "");
    callbackActivityClassName = sharedPrefs.getString(Constants.CALLBACK_ACTIVITY_CLASS_NAME, "");
    Log.i(LOGTAG, "callbackActivity是:" + callbackActivityClassName);
    context = Constants.xmppManager.getContext();

    Intent intent = getIntent();
    if (intent.getStringExtra("ItemTitle") != null) {
      // 来自主页面DemoAppActivity点击单项的intent,不是通知页面Notifier转过来的intent
      Bundle bundle = this.getIntent().getExtras();
      notificationTitle = bundle.getString("ItemTitle");
      notificationMessage = bundle.getString("ItemMessage");
      notificationUri = bundle.getString("ItemUri");
    } else {
      // 来自通知页面Notifier传来的intent,需要增加userInfo内容
      notificationId = intent.getStringExtra(Constants.NOTIFICATION_ID);
      notificationApiKey = intent.getStringExtra(Constants.NOTIFICATION_API_KEY);
      notificationTitle = intent.getStringExtra(Constants.NOTIFICATION_TITLE);
      notificationMessage = intent.getStringExtra(Constants.NOTIFICATION_MESSAGE);
      notificationUri = intent.getStringExtra(Constants.NOTIFICATION_URI);
      notificationFrom = intent.getStringExtra(Constants.NOTIFICATION_FROM);
      packetId = intent.getStringExtra(Constants.PACKET_ID);

      Log.d(LOGTAG, "notificationId=" + notificationId);
      Log.d(LOGTAG, "notificationApiKey=" + notificationApiKey);
      Log.d(LOGTAG, "notificationTitle=" + notificationTitle);
      Log.d(LOGTAG, "notificationMessage=" + notificationMessage);
      Log.d(LOGTAG, "notificationUri=" + notificationUri);
      Log.d(LOGTAG, "notificationFrom=" + notificationFrom);

      // TODO FIXME 发送查看回执
      IQ result =
          new IQ() {
            @Override
            public String getChildElementXML() {
              return null;
            }
          };
      result.setType(Type.RESULT);
      result.setPacketID(packetId);
      result.setTo(notificationFrom);
      try {
        Constants.xmppManager.getConnection().sendPacket(result);
      } catch (Exception e) {
      }

      // 保存通知标题和信息到userInfo中,以便保存在DemoAppActivity的浏览历史记录里
      UserInfo userInfo = (UserInfo) context.getApplicationContext();
      // userInfo.setMyNotifierTitle(title);
      // userInfo.setMyNotifierMessage(message);
      // userInfo.setMyNotifierUri(uri);
      HashMap<String, String> addMap = new HashMap<String, String>();
      addMap.put("ItemTitle", notificationTitle);
      addMap.put("ItemMessage", notificationMessage);
      addMap.put("ItemUri", notificationUri);
      userInfo.addMyNotifier(addMap);
    }

    View rootView = createView(notificationTitle, notificationMessage, notificationUri);
    setContentView(rootView);
  }