Android asmak数据包侦听器和自定义IQProvider未触发/调用

Android asmak数据包侦听器和自定义IQProvider未触发/调用,android,xmpp,smack,asmack,Android,Xmpp,Smack,Asmack,我正在一个android项目中使用最新版本(asmack-android-8-source-0.8.3),我试图通过发送多个IQ和接收响应来与服务器通信。 我收到响应并正确解析了它,但包侦听器没有触发它。 我有以下代码: vCard_IQProvider.java public class vCard_IQProvider implements IQProvider { public static final String NAMESPACE = "vcard-temp"; pu

我正在一个android项目中使用最新版本(asmack-android-8-source-0.8.3),我试图通过发送多个IQ和接收响应来与服务器通信。 我收到响应并正确解析了它,但包侦听器没有触发它。 我有以下代码:

vCard_IQProvider.java

public class vCard_IQProvider implements IQProvider
{
    public static final String NAMESPACE = "vcard-temp";
    public static final String ELEMENT_NAME = "vCard";
    public static final String LAST_STATUS = "LAST_STATUS";
    public static final String LAST_STATUS_DESCRIPTION = "LAST_STATUS_DESCRIPTION";
    public static final String WORK_TIME_RANGE = "WORK_TIME_RANGE";
    public static final String SOUND_SETTINGS = "SOUND_SETTINGS";
    public static final String AUTO_LOCATION_MACHINE_DATA = "AUTO_LOCATION_MACHINE_DATA";
    public static final String AUTO_LOCATION = "AUTO_LOCATION";
    public static final String AUTO_LOCATION_ENABLED = "AUTO_LOCATION_ENABLED";
    public static final String AUTO_ONLINE = "AUTO_ONLINE";
    public static final String HIDEACTIONNOTIFICATIONS = "HideActionNotifications";
    public static final String AUTO_CONNECT = "AUTO_CONNECT";
    public static final String AUTO_OFFLINE_WORK_TIME = "AUTO_OFFLINE_WORK_TIME";
    public static final String AUTO_RELOGIN = "AUTO_RELOGIN";
    public static final String CONNECTED_VIA_INTERNET = "CONNECTED_VIA_INTERNET";
    public static final String MINIMIZE_CHAT = "MINIMIZE_CHAT";
    public static final String PROMPT_PROJECT_SWITCH = "PROMPT_PROJECT_SWITCH";
    public static final String MACHINE_NAME = "MACHINE_NAME";
    public static final String MROFFICE_VER = "MROFFICE_VER";
    public static final String WORK = "WORK";
    public static final String LOCALITY = "LOCALITY";
    public static final String TIMESTAMP = "timestamp";
    public static final String REGION = "REGION";
    public static final String EXT = "EXT";
    public static final String LAST_ACTIVITY_TS = "LAST_ACTIVITY_TS";
    public static final String FUTURE_STATUS = "FUTURE_STATUS";
    public static final String FUTURE_STATUS_DESCRIPTION = "FUTURE_STATUS_DESCRIPTION";
    public static final String FUTURE_STATUS_TS = "FUTURE_STATUS_TS";
    public static final String CUSTOM = "CUSTOM";
    public static final String PREF = "PREF";
    private Map<String, String> list = new HashMap<String, String>();

    @Override
    public IQ parseIQ(XmlPullParser parser) throws Exception
    {
        String name;
        boolean isEmpty;
        boolean done = false;

        while(parser.next() != XmlPullParser.END_DOCUMENT && false == done)
        {
            name = parser.getName();

            switch (parser.getEventType())
            {
                case XmlPullParser.START_TAG:
                {
                    isEmpty = parser.isEmptyElementTag();

                    if(name.equalsIgnoreCase(LAST_STATUS) && false == isEmpty)
                    {
                        list.put(LAST_STATUS, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(LAST_STATUS_DESCRIPTION) && false == isEmpty)
                    {
                        list.put(LAST_STATUS_DESCRIPTION , parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(WORK_TIME_RANGE) && false == isEmpty)
                    {
                        list.put(WORK_TIME_RANGE, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(SOUND_SETTINGS) && false == isEmpty)
                    {
                        list.put(SOUND_SETTINGS, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(AUTO_LOCATION_MACHINE_DATA) && false == isEmpty)
                    {
                        list.put(AUTO_LOCATION_MACHINE_DATA, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(AUTO_LOCATION) && false == isEmpty)
                    {
                        list.put(AUTO_LOCATION, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(AUTO_LOCATION_ENABLED) && false == isEmpty)
                    {
                        list.put(AUTO_LOCATION_ENABLED, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(AUTO_ONLINE) && false == isEmpty)
                    {
                        list.put(AUTO_ONLINE, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(HIDEACTIONNOTIFICATIONS) && false == isEmpty)
                    {
                        list.put(HIDEACTIONNOTIFICATIONS, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(AUTO_CONNECT) && false == isEmpty)
                    {
                        list.put(AUTO_CONNECT, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(AUTO_OFFLINE_WORK_TIME) && false == isEmpty)
                    {
                        list.put(AUTO_OFFLINE_WORK_TIME, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(AUTO_RELOGIN) && false == isEmpty)
                    {
                        list.put(AUTO_RELOGIN, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(CONNECTED_VIA_INTERNET) && false == isEmpty)
                    {
                        list.put(CONNECTED_VIA_INTERNET, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(MINIMIZE_CHAT) && false == isEmpty)
                    {
                        list.put(MINIMIZE_CHAT, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(PROMPT_PROJECT_SWITCH) && false == isEmpty)
                    {
                        list.put(PROMPT_PROJECT_SWITCH, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(MACHINE_NAME) && false == isEmpty)
                    {
                        list.put(MACHINE_NAME, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(MROFFICE_VER) && false == isEmpty)
                    {
                        list.put(MROFFICE_VER, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(WORK) && false == isEmpty)
                    {
                        list.put(WORK, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(LOCALITY) && false == isEmpty)
                    {
                        list.put(LOCALITY, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(TIMESTAMP) && false == isEmpty)
                    {
                        list.put(TIMESTAMP, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(REGION) && false == isEmpty)
                    {
                        list.put(REGION, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(EXT) && false == isEmpty)
                    {
                        list.put(EXT, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(LAST_ACTIVITY_TS) && false == isEmpty)
                    {
                        list.put(LAST_ACTIVITY_TS, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(FUTURE_STATUS) && false == isEmpty)
                    {
                        list.put(FUTURE_STATUS, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(FUTURE_STATUS_DESCRIPTION) && false == isEmpty)
                    {
                        list.put(FUTURE_STATUS_DESCRIPTION, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(FUTURE_STATUS_TS) && false == isEmpty)
                    {
                        list.put(FUTURE_STATUS_TS, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(CUSTOM) && false == isEmpty)
                    {
                        list.put(CUSTOM, parser.nextText());
                    }
                    else if(name.equalsIgnoreCase(PREF) && false == isEmpty)
                    {
                        list.put(PREF, parser.nextText());
                    }

                    break;
                }
                case XmlPullParser.END_TAG:
                {
                    done = ELEMENT_NAME.equalsIgnoreCase(name);
                    break;
                }
            }
        }
        name = null;

        return new vCard_IQ(list);
    }
}
和包侦听器:

connection.addPacketListener(new PacketListener()
{
    @Override
    public void processPacket(Packet p)
    {   
        if(p.getPacketID().equals(vCard_IQ.ID))
        {
            vCard_IQ pp = (vCard_IQ)p;

            //access the parsed data
            //vCard_IQ.getData().get.......

            pp = null;
        }
    }
}, 
    new PacketFilter()
    {
        @Override
        public boolean accept(Packet arg0)
        {
            return true;
        }
    }); 
数据包过滤器设置为接受所有数据包,listner由于某种原因未触发。我可以在调试器中看到服务器正在发送响应

我甚至试图通过创建一个asynk任务绕过侦听器,在后台线程中等待,直到解析响应并访问它。现在它只适用于发送的第一个iq-我收到一个响应并正确地解析了它,但对于其余部分,我可以在调试器中看到服务器正在发送响应,但它从未到达解析器。从未调用过的解析器

   Asynk<Void, Void, Void> asynk = new Asynk<Void, Void, Void>()
    {
        Packet iq_vcard;

        @Override
        protected Void doInBackground(Void... params)
        {
            for(String s : names_list)
            {
                    final String name = s;
                    iq_vcard = new Packet()
                    {
                        @Override
                        public String toXML()
                        {
                            String str = String.format("<iq from='%s' to='%s' type='get' id='" + vCard_IQ.ID + "'><vCard xmlns='vcard-temp'/></iq>",
                                            sharedPrefs.getString(LogIn.USERNAME, "") + "@" + sharedPrefs.getString(Settings_LogIn.DOMAIN, Settings_LogIn.ERROR) + "/iOffice",
                                            name + "@" + sharedPrefs.getString(Settings_LogIn.DOMAIN, Settings_LogIn.ERROR));

                            Log.e("iq_vcard", str);
                            return str;
                        }
                    };
                    connection().sendPacket(iq_vcard);
                    iq_vcard = null;

                    while(false == vCard_IQ.finishedParsing())
                    {
                        try
                        {
                            Thread.sleep(1000);
                            Log.e("TAG", "waiting to finish parsing...");
                        }
                        catch (InterruptedException e)
                        {
                            e.printStackTrace();
                        }
                    }

                    //access the parsed data
                    //vCard_IQ.getData().get.......

                    vCard_IQ.setFinishedParsingToFalse();
            }

            return null;
        }

        @Override
        protected void onPostExecute(Void result)
        {

        }
    };
    asynk.execute();
Asynk Asynk=new Asynk()
{
分组iq_vcard;
@凌驾
受保护的Void doInBackground(Void…参数)
{
用于(字符串s:名称\u列表)
{
最终字符串名称=s;
iq_vcard=新数据包()
{
@凌驾
公共字符串toXML()
{
String str=String.format(“”,
sharedPrefs.getString(LogIn.USERNAME,“”+“@”+sharedPrefs.getString(Settings\u LogIn.DOMAIN,Settings\u LogIn.ERROR)+“/iooffice”,
name+“@”+sharedPrefs.getString(设置\u LogIn.DOMAIN,设置\u LogIn.ERROR));
Log.e(“iq_vcard”,str);
返回str;
}
};
连接().发送数据包(iq_vcard);
iq_vcard=null;
while(false==vCard_IQ.finishedParsing())
{
尝试
{
睡眠(1000);
Log.e(“标记”,“等待完成解析…”);
}
捕捉(中断异常e)
{
e、 printStackTrace();
}
}
//访问已解析的数据
//vCard_IQ.getData().get。。。。。。。
vCard_IQ.SetFinishedParsingOfalse();
}
返回null;
}
@凌驾
受保护的void onPostExecute(void结果)
{
}
};
asynk.execute();

有什么不对的建议吗?

这是aSmack中的一个bug,在无数次尝试修复这个问题后,我自己编译aSmack的尝试失败了,然后尝试了我能想到的任何东西,我做了以下事情:我在android项目中创建了一个新包,并在那里转储了aSmack的所有java类。通过这种方式,我让eclipse编译aSmack,并更好地控制它的代码

问题是,每次我从服务器收到自定义iq响应时,PacketParserUtils.java aSmack都会返回错误的元素名称和命名空间,从而选择错误的iq提供程序来解析响应。

来自文档:

在方法调用结束时,必须将解析器定位在 子元素的结束标记


如果有人也这么做,我发现了问题所在

vCard\u IQProvider
类上的条件错误时,应为:

while(!done && parser.next() != XmlPullParser.END_DOCUMENT)

否则当done设置为true时,while将再次检查条件并将解析器移动到下一个元素(使用调用
parser.next()
)。

我不确定我是否正确,但我在应用程序中观察到,当您启动IQ提供程序时,其他数据包侦听器将无法工作。所有类型的传出或传入数据包仅由IQ提供商处理。尝试将所有数据包记录在IQ提供者中,然后您就会知道。
   Asynk<Void, Void, Void> asynk = new Asynk<Void, Void, Void>()
    {
        Packet iq_vcard;

        @Override
        protected Void doInBackground(Void... params)
        {
            for(String s : names_list)
            {
                    final String name = s;
                    iq_vcard = new Packet()
                    {
                        @Override
                        public String toXML()
                        {
                            String str = String.format("<iq from='%s' to='%s' type='get' id='" + vCard_IQ.ID + "'><vCard xmlns='vcard-temp'/></iq>",
                                            sharedPrefs.getString(LogIn.USERNAME, "") + "@" + sharedPrefs.getString(Settings_LogIn.DOMAIN, Settings_LogIn.ERROR) + "/iOffice",
                                            name + "@" + sharedPrefs.getString(Settings_LogIn.DOMAIN, Settings_LogIn.ERROR));

                            Log.e("iq_vcard", str);
                            return str;
                        }
                    };
                    connection().sendPacket(iq_vcard);
                    iq_vcard = null;

                    while(false == vCard_IQ.finishedParsing())
                    {
                        try
                        {
                            Thread.sleep(1000);
                            Log.e("TAG", "waiting to finish parsing...");
                        }
                        catch (InterruptedException e)
                        {
                            e.printStackTrace();
                        }
                    }

                    //access the parsed data
                    //vCard_IQ.getData().get.......

                    vCard_IQ.setFinishedParsingToFalse();
            }

            return null;
        }

        @Override
        protected void onPostExecute(Void result)
        {

        }
    };
    asynk.execute();
while(!done && parser.next() != XmlPullParser.END_DOCUMENT)