简单的 smack android 客户端不起作用?

Posted

技术标签:

【中文标题】简单的 smack android 客户端不起作用?【英文标题】:simple smack android client not working? 【发布时间】:2016-10-06 10:34:15 【问题描述】:

我正在使用this android source code,这是一个简单的 XMPP android 客户端。我已经在本地安装了 Openfire 并创建了一个用户,在 GenyMotion 我可以在单击登录按钮后连接到创建的用户,我在 openfire 面板中看到在线用户,我还在 Genymotion 的联系人列表中添加了两个联系人,但是当我继续调试,我得到这个错误:

    10/06 13:54:43: Launching app
    No apk changes detected since last installation, skipping installation of C:\Users\Davoud\Downloads\Compressed\Working_Chat_For_Niki\Chat\app\build\outputs\apk\app-debug.apk
    $ adb shell am force-stop com.mycompany.chat
    $ adb shell am start -n "com.mycompany.chat/com.mycompany.chat.ui.LoginActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
    Client not ready yet..Waiting for process to come online
    Waiting for process to come online
    Connected to process 13332 on device genymotion-preview___google_nexus_5x___7_0_0___api_24___1080x1920-192.168.30.101:5555
    D/Connect() Function: onCreate=>connecting....
    D/SMACK: SENT (0): <stream:stream xmlns='jabber:client' to='192.168.119.1' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' xml:lang='en'>
    D/SMACK: RECV (0): <?xml version='1.0' encoding='UTF-8'?><stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" from="desktop-8s6k7ec" id="1t9ccdyqpq" xml:lang="en" version="1.0"><stream:features><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"></starttls><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>PLAIN</mechanism><mechanism>ANONYMOUS</mechanism><mechanism>SCRAM-SHA-1</mechanism><mechanism>CRAM-MD5</mechanism><mechanism>DIGEST-MD5</mechanism></mechanisms><compression xmlns="http://jabber.org/features/compress"><method>zlib</method></compression><auth xmlns="http://jabber.org/features/iq-auth"/><register xmlns="http://jabber.org/features/iq-register"/></stream:features>
    D/ChatActivity: onServiceConnected
    D/xmpp: Connected!
    D/SMACK: SENT (0): <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='SCRAM-SHA-1'>biwsbj0zMjEscj07KiNwUSI3TiJ7ckVEfC15RDw3Sl80ZDxUWUxaYHFVTA==</auth>
    D/SMACK: RECV (0): <challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">cj07KiNwUSI3TiJ7ckVEfC15RDw3Sl80ZDxUWUxaYHFVTGRmMmJmMDVhLTIxNzEtNGMwNi05ZDY5LTBlYTYzMDAyMTY3OSxzPWNzWVR5aXNRbnBycDh5aVpYNHpVdFEwSWNtb0JmM1k2LGk9NDA5Ng==</challenge>
    W/EGL_emulation: eglSurfaceAttrib not implemented
    W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xdb25eec0, error=EGL_SUCCESS
    W/EGL_emulation: eglSurfaceAttrib not implemented
    W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xda550560, error=EGL_SUCCESS
    D/SMACK: SENT (0): <response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>Yz1iaXdzLHI9OyojcFEiN04ie3JFRHwteUQ8N0pfNGQ8VFlMWmBxVUxkZjJiZjA1YS0yMTcxLTRjMDYtOWQ2OS0wZWE2MzAwMjE2NzkscD1KZCtLT3RUSWt0VGlFdnJYbXcxRnNlYjZ0UFk9</response>
    D/SMACK: RECV (0): <success xmlns="urn:ietf:params:xml:ns:xmpp-sasl">dj1pUFBqZGlyU0pnK0djbm1TZ1lCaU9oWEJLYkE9</success>
    D/SMACK: SENT (0): <stream:stream xmlns='jabber:client' to='192.168.119.1' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' id='1t9ccdyqpq' xml:lang='en'>
    D/SMACK: RECV (0): <?xml version='1.0' encoding='UTF-8'?><stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" from="desktop-8s6k7ec" id="1t9ccdyqpq" xml:lang="en" version="1.0"><stream:features><compression xmlns="http://jabber.org/features/compress"><method>zlib</method></compression><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/><session xmlns="urn:ietf:params:xml:ns:xmpp-session"><optional/></session><sm xmlns='urn:xmpp:sm:2'/><sm xmlns='urn:xmpp:sm:3'/></stream:features>
    D/SMACK: SENT (0): <iq id='PhJm6-3' type='set'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><resource>Smack</resource></bind></iq>
    D/SMACK: RECV (0): <iq type="result" id="PhJm6-3" to="desktop-8s6k7ec/1t9ccdyqpq"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><jid>321@desktop-8s6k7ec/Smack</jid></bind></iq>
    D/SMACK: SENT (0): <enable xmlns='urn:xmpp:sm:3' resume='true'/>
    D/SMACK: RECV (0): <enabled xmlns='urn:xmpp:sm:3'/>
    D/SMACK: User logged (0): 321@desktop-8s6k7ec:5222/Smack
    D/xmpp: Authenticated!
    D/SMACK: XMPPConnection authenticated (0)
    D/SMACK: SENT (0): <iq id='PhJm6-5' type='get'><query xmlns='jabber:iq:roster'></query></iq>
    I/LOGIN: Yey! We're connected to the Xmpp server!
    D/SMACK: RECV (0): <iq type="result" id="PhJm6-5" to="321@desktop-8s6k7ec/Smack"><query xmlns="jabber:iq:roster"/></iq>
    D/SMACK: SENT (0): <presence id='PhJm6-6'><c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://www.igniterealtime.org/projects/smack' ver='E6FpoDPmjMQ3i53V+HWh0YBrS7U='/></presence>
    E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
                      Process: com.mycompany.chat, PID: 13332
                      java.lang.RuntimeException: An error occurred while executing doInBackground()
                          at android.os.AsyncTask$3.done(AsyncTask.java:318)
                          at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
                          at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
                          at java.util.concurrent.FutureTask.run(FutureTask.java:242)
                          at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
                          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
                          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
                          at java.lang.Thread.run(Thread.java:761)
                       Caused by: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.contacts.ContactsProvider2 from ProcessRecord68c245f 13332:com.mycompany.chat/u0a71 (pid=13332, uid=10071) requires android.permission.READ_CONTACTS or android.permission.WRITE_CONTACTS
                          at android.os.Parcel.readException(Parcel.java:1683)
                          at android.os.Parcel.readException(Parcel.java:1636)
                          at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:4169)
                          at android.app.ActivityThread.acquireProvider(ActivityThread.java:5434)
                          at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2267)
                          at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1515)
                          at android.content.ContentResolver.query(ContentResolver.java:514)
                          at android.content.ContentResolver.query(ContentResolver.java:472)
                          at com.mycompany.chat.ui.FriendsActivity$GetUser.doInBackground(FriendsActivity.java:67)
                          at com.mycompany.chat.ui.FriendsActivity$GetUser.doInBackground(FriendsActivity.java:54)
                          at android.os.AsyncTask$2.call(AsyncTask.java:304)
                          at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                          at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) 
                          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
                          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
                          at java.lang.Thread.run(Thread.java:761) 
    I/Process: Sending signal. PID: 13332 SIG: 9
    Application terminated.

【问题讨论】:

【参考方案1】:

将此添加到清单中:

<uses-permission android:name="android.permission.READ_CONTACTS" />

并在您的活动中请求许可(如果 sdk >= 23),

@Override
public void onCreate(Bundle b) 
    askPermission();    


public void askPermission()
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
        if (ContextCompat.checkSelfPermission(getActivity(),Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) 
            if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
                    Manifest.permission.READ_CONTACTS)) 
                AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
                builder.setTitle("Contacts access needed");
                builder.setPositiveButton(android.R.string.ok, null);
                builder.setMessage("please confirm Contacts access");//TODO put real question
                builder.setOnDismissListener(new DialogInterface.OnDismissListener() 
                    @TargetApi(Build.VERSION_CODES.M)
                    @Override
                    public void onDismiss(DialogInterface dialog) 
                        requestPermissions(
                                new String[]
                                        Manifest.permission.READ_CONTACTS
                                , PERMISSION_REQUEST_CONTACT);
                    
                );
                builder.show();
             else 
                // No explanation needed, we can request the permission.
                ActivityCompat.requestPermissions(getActivity(),
                        new String[]Manifest.permission.READ_CONTACTS,
                        PERMISSION_REQUEST_CONTACT);

                // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
                // app-defined int constant. The callback method gets the
                // result of the request.
            
        
    


@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) 
    switch (requestCode) 
        case PERMISSION_REQUEST_CONTACT: 
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) 

                // permission granted
             else 
                //permission denied
            
            return;
        
    

【讨论】:

以上是关于简单的 smack android 客户端不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

Smack - 何时调用 MultiUserChat.Join(...)

Android Smack MessageEventListener

使用 xmpp + smack + openfire 在 android 中阻止用户

如何为 xmpp 实现 smack

谷歌云消息传递 - 使用 smack 的 xmpp 服务器端不起作用

Smack Message.setType() 不起作用,类型设置为“聊天”