使用 QuickBlox 聊天 SDK 发送图像 - Android

Posted

技术标签:

【中文标题】使用 QuickBlox 聊天 SDK 发送图像 - Android【英文标题】:Send Image Using QuickBlox Chat SDK - Android 【发布时间】:2016-01-04 13:27:40 【问题描述】:

我正在开发一个聊天应用程序。为此,我使用 Quickblox SDk 。到目前为止,我已经完成了文字聊天。现在我正在尝试在聊天中发送图像。为此,首先我从 SD 卡中选择图像,然后在图像选择时成功上传到 quickblox 服务器,然后使用 QBFile 引用我获取图像 ID 并尝试在聊天窗口中显示它。

这是参考代码。

 private void sendChatMessage(String messageText, InputStream imageStream) 

    final QBChatMessage chatMessage = new QBChatMessage();

    //Send Image
    if(imageStream != null)
        File file = FileHelper.getFileInputStream(imageStream, "sample_file.png", "myFile");
        Boolean fileIsPublic = true;
        QBContent.uploadFileTask(file, fileIsPublic, messageText, new QBEntityCallbackImpl<QBFile>() 
            @Override
            public void onSuccess(QBFile qbFile, Bundle params) 

                String publicUrl = qbFile.getPublicUrl();
                Toast.makeText(getApplicationContext(), "Image uploaded success", Toast.LENGTH_SHORT).show();
                id = qbFile.getId();
                Toast.makeText(getApplicationContext(),"Public URl: "+ publicUrl, Toast.LENGTH_SHORT).show();
                Toast.makeText(getApplicationContext(),"ID: "+ id + "", Toast.LENGTH_SHORT).show();

                //
                QBAttachment attach = new QBAttachment("image");
                attach.setId(id + "");
                ArrayList<QBAttachment> arryattach = new ArrayList<QBAttachment>();
                arryattach.add(attach);

                chatMessage.setProperty(PROPERTY_SAVE_TO_HISTORY, "1");
                chatMessage.setDateSent(new Date().getTime() / 1000);
                chatMessage.setBody("");
                chatMessage.setAttachments(arryattach);
                //chatMessage.setId(id+"");

                try 
                    chat.sendMessage(chatMessage);
                 catch (XMPPException e) 
                    Log.e(TAG, "failed to send a message", e);
                 catch (SmackException sme) 
                    Log.e(TAG, "failed to send a message", sme);
                

                if (dialog.getType() == QBDialogType.PRIVATE) 
                    showMessage(chatMessage);
                
            
            @Override
            public void onError(List<String> errors) 
                System.out.println("==========image uploaded Errors++++++++" + errors.toString());
            
        , new QBProgressCallback()
            @Override
            public void onProgressUpdate(int progress)
            
        );

    else
        //Send Text Body.
        chatMessage.setBody(messageText);
        chatMessage.setProperty(PROPERTY_SAVE_TO_HISTORY, "1");
        chatMessage.setDateSent(new Date().getTime() / 1000);

        try 
            chat.sendMessage(chatMessage);
         catch (XMPPException e) 
            Log.e(TAG, "failed to send a message", e);
         catch (SmackException sme) 
            Log.e(TAG, "failed to send a message", sme);
        

        messageEditText.setText("");

        if (dialog.getType() == QBDialogType.PRIVATE) 
            showMessage(chatMessage);
        
    


ChatAdapter.java

getView()

    @Override
    public View getView(int position, View convertView, ViewGroup parent) 
       final ViewHolder holder;
        QBChatMessage chatMessage = getItem(position);
        LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        int type = getItemViewType(position) ;
        if (convertView == null) 

            if (type == ChatItemType.Sticker.ordinal()) 
                convertView = vi.inflate(R.layout.list_item_sticker, parent, false);
             else if (type == ChatItemType.Message.ordinal()) 
                convertView = vi.inflate(R.layout.list_item_message, parent, false);
             else 
                convertView = vi.inflate(R.layout.list_item_image, parent, false);
            

            holder = createViewHolder(convertView);
            convertView.setTag(holder);
         else 
            holder = (ViewHolder) convertView.getTag();
        

        QBUser currentUser = ChatService.getInstance().getCurrentUser();
        boolean isOutgoing = chatMessage.getSenderId() == null || chatMessage.getSenderId().equals(currentUser.getId());
        setAlignment(holder, isOutgoing);

        Collection<QBAttachment> attachments =  chatMessage.getAttachments();

        //attachments.
        if ( attachments != null && attachments.size() > 0) 

            String imageid="" ;
            for(QBAttachment attachment :attachments)
                imageid = attachment.getId();
            
            new BackgroundOperation(holder ,imageid).execute();

         else if (StickersManager.isSticker(chatMessage.getBody())) 
            StickersManager.with(convertView.getContext())
                    .loadSticker(chatMessage.getBody())
                    .setPlaceholderColorFilterRes(android.R.color.darker_gray)
                    .into(holder.stickerView);
         else if (holder.txtMessage != null) 
            holder.txtMessage.setText(chatMessage.getBody());
        

        if (chatMessage.getSenderId() != null) 
            holder.txtInfo.setText(chatMessage.getSenderId() + ": " + getTimeText(chatMessage));
         else 
            holder.txtInfo.setText(getTimeText(chatMessage));
        
        return convertView;
    

    class BackgroundOperation extends AsyncTask<InputStream , Void , InputStream>

       ViewHolder holder ;
       int imageid ;
       InputStream inputStream;

       BackgroundOperation(ViewHolder holder , String imageid)
           this.holder = holder ;
           this.imageid = Integer.parseInt(imageid);
       

       @Override
       protected void onPreExecute() 
           super.onPreExecute();
       

       @Override
       protected InputStream doInBackground(InputStream... params) 

           Handler mHandler = new Handler(Looper.getMainLooper());
               mHandler.post(new Runnable() 
                   public void run() 
                       QBContent.downloadFileTask(imageid, new QBEntityCallbackImpl<InputStream>() 
                           @Override
                           public void onSuccess(InputStream inputS, Bundle params) 

                               inputStream = inputS ;

                               //ImageView img =   holder.image_attachment ; //.setImageDrawable(d);
                               //Toast.makeText(context, "Image download Sucess", Toast.LENGTH_SHORT).show();

                           

                           @Override
                           public void onError(List<String> errors) 
                               Log.d("Image Download Error : ", errors.toString());
                               //Toast.makeText(context, "Image Download Error ", Toast.LENGTH_SHORT).show();
                           
                       , new QBProgressCallback() 
                           @Override
                           public void onProgressUpdate(int progress) 
                               //Toast.makeText(context, "Image Download Progress ", Toast.LENGTH_SHORT).show();
                           
                       );
                   
               );

           return inputStream;
       

       @Override
       protected void onPostExecute(InputStream s) 
           super.onPostExecute(s);

           if(s != null)
               Log.d("InputStream Value :", "******"+s.toString()+"******************");
               Bitmap bmp = BitmapFactory.decodeStream(s);
               Drawable d = new BitmapDrawable(context.getResources(), bmp);
               if(holder.image_attachment != null)
                   holder.image_attachment.setImageDrawable(d);
           
       
   

这里我在 getView() 中调用 new BackgroundOperation(holder ,imageid).execute();,这里我传递当前持有者和 imageid 以从 quickblox 服务器下载图像。这里发生了什么,当 new BackgroundOperation(holder ,imageid).execute() 运行(图像上传后),然后 doInBackground() 的返回语句不执行,即使图像正在下载,我在 QBContent.downloadFileTask() 的 onSuccess() 中得到相应的 InputStream 。这里我很困惑为什么 doInBackground() 没有返回。

【问题讨论】:

@andriod 开发者。我正在尝试为我的学校项目实现与您相同的聊天 api,我也想知道如何发送附件。我尝试在他们的网站上关注 quickblox 的 tut,但这并不是很有帮助。你能帮帮我吗? 【参考方案1】:

试试这个代码:

在 sendChatMessage 内

替换

id = qbFile.getId();

id = qbFile.getUid();

ChatAdapter.java 的 getView() 内部

替换

new BackgroundOperation(holder ,imageid).execute();

String url =prefixofimagePublicurl +imageid ;
Picasso.with(context).load(url).into(imageView);

从 ChatAdapter.java 中移除 BackgroundOperation。

注意:改变imageid int ot String的数据类型

【讨论】:

以上是关于使用 QuickBlox 聊天 SDK 发送图像 - Android的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin C# SDK 中的 Quickblox 聊天设置 save_to_history 为 true

使用 Quickblox SDK 未收到从 iOS 到 android 的推送通知

在 Quickblox Chat sdk 中聊天/1:1 聊天

quickblox javascript sdk 一对一视频聊天

使用 quickblox 的 Quickblox 聊天

使用 QuickBlox JavaScript SDK 的问题