In my android project, I am using RecyclerView. At run time I need to add files to it so that it will upload those files to my Server. And there will be a ProgressBar on each item to show upload progress. My problem is whenever I want to upload more files at a time, a progress of one item is showing on another Item. This is happening only on currently running uploads as I hide completed ProgressBar. And it is also happening whenever I scroll up and down. I have tried to store the upload progress in hashMap and retrieve it whenever an Item appears, but it did not work. I know this is the natural behavior of RecyclerView compare to a listview. I want to know how this can be achieved. I used as s3 to upload files. And Glide to show thumbnails of files if the file is an image.
CODE:
#Override
public void onBindChildViewHolder(final MyChildViewHolder holder, final int groupPosition, final int childPosition, int viewType) {
final MyChildItem child = Items.get(groupPosition).children.get(childPosition);
Context ctx = holder.imageView.getContext();
final String status = Smap.get(child.fileInfo.unique_id);
Log.d("STATUS", status);
switch (status) {
case Constants.UNKNOWN:
case Constants.RESUMED_WAITING:
case Constants.PAUSED:
case Constants.FAILED:
case Constants.CANCELED:
holder.upload_cancel.setVisibility(View.VISIBLE);
holder.resume_pause_select.setVisibility(View.VISIBLE);
holder.resume_pause_select.setImageResource(R.drawable.ic_action_ic_refresh_white_24dp);
holder.fileprogressbar.setVisibility(View.INVISIBLE);
holder.file_name.setVisibility(View.INVISIBLE);
break;
case Constants.PENDING_CANCEL:
case Constants.PENDING_NETWORK_DISCONNECT:
case Constants.PART_COMPLETED:
case Constants.PENDING_PAUSE:
case Constants.WAITING_FOR_NETWORK:
case Constants.IN_PROGRESS:
case Constants.WAITING:
holder.upload_cancel.setVisibility(View.VISIBLE);
holder.fileprogressbar.setIndeterminate(true);
holder.resume_pause_select.setVisibility(View.VISIBLE);
holder.resume_pause_select.setImageResource(R.drawable.ic_action_ic_pause_white_24dp);
holder.fileprogressbar.setVisibility(View.VISIBLE);
holder.file_name.setVisibility(View.INVISIBLE);
try {
file file = new file(null, child.fileInfo.unique_id, child.fileInfo.localpath, child.fileInfo.remotepath, status, child.fileInfo.privacy, child.fileInfo.file_size, "UPLOAD", Umap.get(child.fileInfo.unique_id), child.fileInfo.pond_id, Constants.getLastTimeOpened());
fileDao.insert(file);
Log.d("new file", "Inserted");
} catch (SQLException e) {
Log.d("ERROR", "Not Inserted");
}
Integer prevprogress = Pmap.get(child.fileInfo.unique_id);
if(prevprogress!=null){
holder.fileprogressbar.setIndeterminate(false);
holder.fileprogressbar.setProgress(prevprogress);
}
transferObserver = Util.getTransferUtility(getContext()).getTransferById(Integer.parseInt(Umap.get(child.fileInfo.unique_id)));
if (transferObserver != null) {
transferObserver.setTransferListener(new TransferListener() {
#Override
public void onStateChanged(int i, TransferState transferState) {
if (child.fileInfo.unique_id != null && !child.fileInfo.unique_id.isEmpty()) {
Umap.put(child.fileInfo.unique_id, String.valueOf(i));
Smap.put(child.fileInfo.unique_id, transferState.toString());
}
holder.fileprogressbar.setIndeterminate(true);
if (transferState.toString().equals(Constants.COMPLETED)) {
com.ficean.android.ficean.File.File.fileStore(getContext(), phonenumber, "UPLOAD", child.fileInfo, new com.ficean.android.ficean.File.File.Call() {
#Override
public void onSuccess(boolean result) {
if (result) {
}
}
});
}
List<file> files = fileDao.queryBuilder().where(com.ficean.android.ficean.db.fileDao.Properties.File_unique_id.eq(child.fileInfo.unique_id)).limit(1).build().list();
for (file file : files) {
file.setFile_status(transferState.toString());
file.setU_id(String.valueOf(i));
fileDao.update(file);
}
expMgr.notifyChildItemChanged(groupPosition,childPosition);
}
#Override
public void onProgressChanged(int i, long l, long l1) {
int value = Constants.percentage(l, l1);
holder.fileprogressbar.setIndeterminate(false);
holder.fileprogressbar.setProgress(value);
Pmap.put(child.fileInfo.unique_id,value);
}
#Override
public void onError(int i, Exception e) {
}
});
}
break;
default:
String link = SaveUtil.getEncryptedPreferences(getContext()).getString(child.fileInfo.unique_id, Constants.NOTHING);
Glide.with(getContext()).load(link).skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.SOURCE).crossFade().placeholder(R.drawable.image_icon).listener(new CustomRequestListener(new CustomRequestListener.requestCallBack() {
#Override
public void onSuccess(boolean isSuccess) {
if (!isSuccess) {
String remotePath;
if (Opener.isFileVideo(child.fileInfo.localpath)) {
remotePath = phonenumber.concat("/").concat("thumbnails").concat("/").concat(FilenameUtils.removeExtension(new File(child.fileInfo.localpath).getName())).concat(".png");
} else {
remotePath = child.fileInfo.remotepath;
}
LoginCredentials.getSignedUrl(getContext(), remotePath, new LoginCredentials.UrlCallback() {
#Override
public void onSuccess(final URL url) {
if (url != null) {
Glide.with(getContext()).load(url.toString()).skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.SOURCE).crossFade().placeholder(R.drawable.image_icon).listener(new CustomRequestListener(new CustomRequestListener.requestCallBack() {
#Override
public void onSuccess(boolean isSuccess) {
if (isSuccess) {
SaveUtil.getEncryptedEditor(getContext()).putString(child.fileInfo.unique_id, url.toString()).apply();
}
}
})).error(R.drawable.image_icon).into(holder.imageView);
}
}
});
}
}
})).error(R.drawable.image_icon).into(holder.imageView);
holder.resume_pause_select.setVisibility(View.INVISIBLE);
holder.fileprogressbar.setVisibility(View.INVISIBLE);
holder.upload_cancel.setVisibility(View.INVISIBLE);
break;
}
}
Related
so im tring to check data before i press toggle button but i cannot get the right logic to do the process
so i think i should do if checked look at the database set the background resource then i do the if pressed but i doesnt work
like it doesnt even change the backgroundResource
i tried to change buttonView to myViewholder.btn.setBackgroundResource but it doesnt work neither
toggle button
myViewHolder.btn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, final boolean isChecked) {
if (myViewHolder.btn.isChecked()) {
sessionManager = new SessionManager(zContext);
final HashMap<String, String> user = sessionManager.getUserDetail();
final String user_id2 = user.get(USER_ID);
String user_id = data.getUser_id();
final String post_id = data.getPost_id();
String URL = HOST + "/likes_table.php";
sessionManager = new SessionManager(zContext);
AndroidNetworking.get("http://10.0.2.2/Final/gettinglike.php")
.setPriority(Priority.LOW)
.build()
.getAsJSONArray(new JSONArrayRequestListener() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, "onResponse: " + response);
{
try {
for (int i = 0; i < response.length(); i++) {
final JSONObject data = response.getJSONObject(i);
if (data.getString("post_id").equals(post_id)) {
String like_id = data.getString("like_id");
String user_id = data.getString("user_id").trim();
String post_id = data.getString("post_id");
if (user_id.equals(user_id2)){
myViewHolder.btn.isChecked();
buttonView.setBackgroundResource(ic_star_black_24dp_checked);
}
else{
buttonView.setBackgroundResource(ic_star_border_black_24dp);
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
#Override
public void onError(ANError error) {
Log.d(TAG, "onError: " + error);
}
});
if (myViewHolder.btn.isPressed()){
}
}
else {
}
}
});
Finally i solved it correctly
first i needed to create php file where it checks in which state
$user_id = $_POST['user_id'];
$post_id = $_POST['post_id'];
$sql_verify = "SELECT * FROM likes_table WHERE post_id = :POST_ID AND user_id =
:USER_ID
";
$stmt = $PDO->prepare($sql_verify);
$stmt->bindParam(':POST_ID', $post_id);
$stmt->bindParam(':USER_ID',$user_id);
$stmt->execute();
if ($stmt->rowCount() > 0) {
$returnApp = array( 'SIGNUP' => 'LIKE_ALREADY_EXIST');
echo json_encode($returnApp);
}
else {
$returnApp = array( 'SIGNUP' => 'LIKE_DOESNT_EXIST');
echo json_encode($returnApp);
}
then i create mothod for calling it with two cases one when toggle button is on and the onther when the toggle button is off
private void getdata3(final MyViewHolder myViewHolder , final int i){
final String URL2 = HOST + "/likes_table2.php";
sessionManager = new SessionManager(zContext);
final HashMap<String, String> user = sessionManager.getUserDetail();
final String user_id3 = user.get(USER_ID);
PostsModelClass data = modelClassList.get(i);
final String post_id = data.getPost_id();
Ion.with(zContext)
.load(URL2)
.setBodyParameter("user_id",user_id3)
.setBodyParameter("post_id",post_id)
.asJsonObject()
.setCallback(new FutureCallback<JsonObject>() {
#Override
public void onCompleted(Exception e, JsonObject result) {
try {
String RETURN = result.get("SIGNUP").getAsString();
switch (RETURN) {
case "LIKE_ALREADY_EXIST":
final String URL = HOST + "/dislike.php";
myViewHolder.btn.setBackgroundResource(ic_star_black_24dp_checked);
myViewHolder.btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Ion.with(zContext)
.load(URL)
.setBodyParameter("post_id", post_id)
.setBodyParameter("user_id",user_id3)
.asJsonObject()
.setCallback(new FutureCallback<JsonObject>() {
#Override
public void onCompleted(Exception e, JsonObject result) {
try {
String RETURN = result.get("SIGNUP").getAsString();
switch (RETURN) {
case "Posted":
myViewHolder.btn.setBackgroundResource(ic_star_border_black_24dp);
getdata3(myViewHolder,i);
modelClassList.clear();
newsFeedFragmentUser.getData();
break;
default:
break;
}
} catch (Exception error) {
}
}
});
}
});
break;
case "LIKE_DOESNT_EXIST":
myViewHolder.btn.setBackgroundResource(ic_star_border_black_24dp);
final String URL3 = HOST + "/likes_table.php";
myViewHolder.btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Ion.with(zContext)
.load(URL3)
.setBodyParameter("post_id", post_id)
.setBodyParameter("user_id",user_id3)
.asJsonObject()
.setCallback(new FutureCallback<JsonObject>() {
#Override
public void onCompleted(Exception e, JsonObject result) {
try {
String RETURN = result.get("SIGNUP").getAsString();
switch (RETURN) {
case "Posted":
myViewHolder.btn.setBackgroundResource(ic_star_black_24dp_checked);
getdata3(myViewHolder,i);
modelClassList.clear();
newsFeedFragmentUser.getData();
break;
default:
break;
}
} catch (Exception error) {
}
}
});
}
});
break;
default:
Toast.makeText(zContext, "Ops! Error Occurred m", Toast.LENGTH_LONG).show();
break;
}
} catch (Exception error) {
Toast.makeText(zContext, "Ops! Error Occured" + error, Toast.LENGTH_LONG).show();
}
}
});
}
then i call it inside onBindViewHolder
getdata3(myViewHolder,i);
hope this finds anyone in need of this .. it took my 3 days to figure out the logic
this getItemViewType()
public int getItemViewType(int position) {
boolean type = _arr_GameList.get(position).isFirstComment();
if (type) {
return 0;
} else {
return 1;
}
}
After that set the view holder type wise but not display data . i used one arraylist but i want to two arraylist position first parent and second chhailed position
public void onBindViewHolder(#NonNull final MyViewHolder holder, int position) {
object = _arr_GameList.get(position);
if (object != null) {
if (object.isFirstComment()) {
setData(holder, position);
} else {
setData(holder, position);
}
}
}
After that set the view holder type wise but not display data . i used one arraylist but i want to two arraylist position first parent and second chhailed position
private void ReplyCommentServiceCall(final MyViewHolder holder, int position, String comment_id, String comment_body) {
Call<ResponseBody> call;
call = LaravelRetrofite.addgetClient().AddreplyComment("Bearer " + preferencesUtility.getAccessToken(), "Application/json", article_id, comment_id, comment_body);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
try {
if (response.isSuccessful()) {
Log.v("Articalereplycomment", response.toString());
Log.v("replygetposition", "" + position);
boolean type = _arr_GameList.get(position).isFirstComment();
Log.v("layouttype", "" + type);
object = _arr_GameList.get(position);
ArticleCommentsModel articleCommentsModel = _arr_GameList.get(position + 1);
articleCommentsModel.setComment_body(comment_body);
articleCommentsModel.setDeleteCommentOption("1");
articleCommentsModel.setFirstComment(false);
_arr_GameList.add(articleCommentsModel);
setData(holder, position + 1);
notifyDataSetChanged();
} else {
// error case
switch (response.code()) {
case 404:
NetworkUtility.ToastFunction(mActivity, "not found");
break;
case 500:
NetworkUtility.ToastFunction(mActivity, "server broken");
break;
default:
NetworkUtility.ToastFunction(mActivity, "unknown error");
break;
}
}
} catch (Exception e) {
String message = e.getMessage().replace("java.lang.Throwable: ", "");
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.v("Upload", t.getMessage());
String message = t.getMessage().replace("java.lang.Throwable: ", "");
}
});
}
are you sure you got the method right?
right now it seems that this if is useless.
both cases are the same.
if (object.isFirstComment()) {
setData(holder, position);
} else {
setData(holder, position);
}
I am currently writing an Android app in Android Studio for the Microsoft band that will record data from the GSR, HR, and Skin Temp.
I have the data for GSR and Skin Temp. currently reading on the application but the rate that it is updated is very slow, especially for the Skin Temp. I was wondering if there was a way to make these sensors send data more frequently because the data I have now has too long of intervals for the purpose I am using it for. Here is my MainPage.java file.
public class MainPage extends Activity {
private BandClient client = null;
TextView tvGSR;
TextView tvHeartRate;
TextView tvTemperature;
Button updateTest;
private BandGsrEventListener mGsrEventListener = new BandGsrEventListener() {
#Override
public void onBandGsrChanged(final BandGsrEvent event) {
if (event != null) {
appendGSRToUI(String.format("%d kΩ\n", event.getResistance()));
}
}
};
private BandSkinTemperatureEventListener tempEventListener = new BandSkinTemperatureEventListener() {
#Override
public void onBandSkinTemperatureChanged(final BandSkinTemperatureEvent event) {
if (event != null) {
appendTempToUI(String.format("%.2f ºF\n", event.getTemperature()*1.800 + 32.00));
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_page);
tvGSR = (TextView) findViewById(R.id.tvGSR);
tvTemperature = (TextView) findViewById(R.id.tvTemperature);
updateTest = (Button) findViewById(R.id.updateTest);
updateTest.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
tvGSR.setText("");
tvTemperature.setText("");
new GsrSubscriptionTask().execute(); // Put first (runs connection)
new TempSubscriptionTask().execute();
}
});
}
#Override
protected void onResume() {
super.onResume();
tvGSR.setText("");
tvTemperature.setText("");
}
#Override
protected void onPause() {
super.onPause();
if (client != null) {
try {
client.getSensorManager().unregisterGsrEventListener(mGsrEventListener);
client.getSensorManager().unregisterSkinTemperatureEventListener(tempEventListener);
} catch (BandIOException e) {
appendGSRToUI(e.getMessage());
appendTempToUI(e.getMessage());
}
}
}
#Override
protected void onDestroy() {
if (client != null) {
try {
client.disconnect().await();
} catch (InterruptedException e) {
// Do nothing as this is happening during destroy
} catch (BandException e) {
// Do nothing as this is happening during destroy
}
}
super.onDestroy();
}
private class GsrSubscriptionTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
try {
if (getConnectedBandClient()) {
int hardwareVersion = Integer.parseInt(client.getHardwareVersion().await());
if (hardwareVersion >= 20) {
appendGSRToUI("Band is connected.\n");
client.getSensorManager().registerGsrEventListener(mGsrEventListener);
} else {
appendGSRToUI("The Gsr sensor is not supported with your Band version. Microsoft Band 2 is required.\n");
}
} else {
appendGSRToUI("Band isn't connected. Check Bluetooth.\n");
}
} catch (BandException e) {
String exceptionMessage="";
switch (e.getErrorType()) {
case UNSUPPORTED_SDK_VERSION_ERROR:
exceptionMessage = "SDK Version Outdated.\n";
break;
case SERVICE_ERROR:
exceptionMessage = "GSR Not Supported\n";
break;
default:
exceptionMessage = "Unknown error occured: " + e.getMessage() + "\n";
break;
}
appendGSRToUI(exceptionMessage);
} catch (Exception e) {
appendGSRToUI(e.getMessage());
}
return null;
}
}
private class TempSubscriptionTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
try {
if (true) {
int hardwareVersion = Integer.parseInt(client.getHardwareVersion().await());
if (hardwareVersion >= 20) {
appendTempToUI("Band is connected.\n");
client.getSensorManager().registerSkinTemperatureEventListener(tempEventListener);
} else {
appendTempToUI("Temperature Not Supported.\n");
}
} else {
appendTempToUI("Band isn't connected. Check Bluetooth\n");
}
} catch (BandException e) {
String exceptionMessage="";
switch (e.getErrorType()) {
case UNSUPPORTED_SDK_VERSION_ERROR:
exceptionMessage = "SDK Version Outdated\n";
break;
case SERVICE_ERROR:
exceptionMessage = "Microsoft Health App Error\n";
break;
default:
exceptionMessage = "Unknown error occured: " + e.getMessage() + "\n";
break;
}
appendTempToUI(exceptionMessage);
} catch (Exception e) {
appendTempToUI(e.getMessage());
}
return null;
}
}
private void appendGSRToUI(final String string) {
this.runOnUiThread(new Runnable() {
#Override
public void run() {
tvGSR.setText(string);
}
});
}
private void appendTempToUI(final String string) {
this.runOnUiThread(new Runnable() {
#Override
public void run() {
tvTemperature.setText(string);
}
});
}
private boolean getConnectedBandClient() throws InterruptedException, BandException {
if (client == null) {
BandInfo[] devices = BandClientManager.getInstance().getPairedBands();
if (devices.length == 0) {
appendGSRToUI("Band isn't paired with your phone.\n");
return false;
}
client = BandClientManager.getInstance().create(getBaseContext(), devices[0]);
} else if (ConnectionState.CONNECTED == client.getConnectionState()) {
return true;
}
appendGSRToUI("Band is connecting...\n");
return ConnectionState.CONNECTED == client.connect().await();
}
}
There is currently no way to get data at a faster rate than provided by the Microsoft Band SDK.
Also, depending on what you want the data for, the skin temperature data might not be useful for you. Looking at the sensors you want to subscribe to, it looks like your application might be health related. But the skin temperature data contains the raw values from one of several thermometers inside of the band. And the band itself will generate some heat internally, so the data is unlikely to represent the skin temperature of the wearer exactly.
I want send composing event in Group (Multiuser) chat in xmpp, I am using asmack library, I have done same functionality with One to One chat.
I am using below code:
mMessageEventManager = new MessageEventManager(XMPPConnectApplication.getInstance().getXmppConnection());
mMessageEventManager.addMessageEventNotificationListener(new MessageEventNotificationListener() {
#Override
public void offlineNotification(String arg0, String arg1) {
}
#Override
public void displayedNotification(String arg0, String arg1) {
}
#Override
public void deliveredNotification(String arg0, String arg1) {
}
#Override
public void composingNotification(String from, String to) {
Log.e("Receiver-composingNotification",from + " is started typing......"+to);
}
#Override
public void cancelledNotification(String from, String to) {
Log.e("Receiver-cancelledNotification",from + " is stopped typing......"+to);
}
});
Please let me know if you have any idea for the same.
Any help will be appreciated.
Yes, I have idea about it and I have done just before 1 week.
I have used MessageEventManager to manage Chat States.
private MessageEventManager mMessageEventManager;
Add this method for Chat State Receiving Listener:
private void chatStateRecognizer(){
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
mMessageEventManager = new MessageEventManager(mXmppConnection);
mMessageEventManager.addMessageEventNotificationListener(new MessageEventNotificationListener() {
#Override
public void offlineNotification(String arg0, String arg1) {
}
#Override
public void displayedNotification(String arg0, String arg1) {
}
#Override
public void deliveredNotification(String from, String arg1) {
}
#Override
public void composingNotification(String from, String to) {
Log.i("Receiver:Compose state",from + " is started typing......"+to);
}
#Override
public void cancelledNotification(String from, String to) {
Log.i("Receiver:Stop state",from + " is stopped typing......"+to);
}
});
}
});
thread.start();
}
Create one Model class name with GroupInfoModel.java:
public class GroupInfoModel implements Comparable<GroupInfoModel>, Serializable{
private static final long serialVersionUID = 1L;
private String memberId = "", memberName = "";
private boolean isAdmin;
public String getMemberId() {
return memberId;
}
public void setMemberId(String memberId) {
this.memberId = memberId;
}
public String getMemberName() {
return memberName;
}
public void setMemberName(String memberName) {
this.memberName = memberName;
}
public boolean isAdmin() {
return isAdmin;
}
public void setAdmin(boolean isAdmin) {
this.isAdmin = isAdmin;
}
#Override
public int compareTo(GroupInfoModel another) {
return getMemberName().compareTo(another.getMemberName());
}
}
Now take ArrayList of GroupInfoModel.java class:
private ArrayList<GroupInfoModel> groupDetailsList = new ArrayList<GroupInfoModel>();
private boolean isComposingStarted;
on onCreate() of Activity / Fragment:
groupDetailsList.clear();
ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(mXmppConnection);
DiscoverItems items = discoManager.discoverItems(mRoomId);
for (Iterator<Item> it = items.getItems(); it.hasNext();) {
DiscoverItems.Item item = (DiscoverItems.Item) it.next();
String occupant = item.getEntityID();
occupant = occupant.split("/")[1];
GroupInfoModel groupInfoModel = new GroupInfoModel();
groupInfoModel.setAdmin(false);
groupInfoModel.setMemberId(occupant+"#"+mServiceNameHere);
groupInfoModel.setMemberName(occupant);
groupDetailsList.add(groupInfoModel);
}
Now add TextWatcher on your EditText of Compose Message (Chat view) screen:
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(s.toString().length()==1&&!isComposingStarted){
isComposingStarted = true;
if(chatType.equals("OneToOneChat")){
mMessageEventManager.sendComposingNotification(myJabberId, friendJabberId);
}else if(chatType.equals("GroupChat")){
for (int i = 0; i < groupDetailsList.size(); i++) {
if(!groupDetailsList.get(i).getMemberId().contains(myJabberId)){
mMessageEventManager.sendComposingNotification(groupDetailsList.get(i).getMemberId(), roomId);
}
}
}
}else if(s.toString().length()==0){
isComposingStarted = false;
if(chatType.equals("OneToOneChat")){
mMessageEventManager.sendCancelledNotification(myJabberId, friendJabberId);
}else if(chatType.equals("GroupChat")){
for (int i = 0; i < groupDetailsList.size(); i++) {
if(!groupDetailsList.get(i).getMemberId().contains(myJabberId)){
mMessageEventManager.sendCancelledNotification(groupDetailsList.get(i).getMemberId(), roomId);
}
}
}
}
}
I strongly recommended that use above code in Application class, you can modify methods as your requirements.
Done.
// send multi user chat typing status
public static void sendMUCTypingStatus(ChatState state)
{
// check if you are connected to group
if(multiUserChat != null)
{
try{
// create packet
Message statusPacket = new Message();
// set body to null
statusPacket.setBody(null);
// set packet type to group chat
statusPacket.setType(Message.Type.groupchat);
// set subject to null
statusPacket.setSubject(null);
// set to the group name
statusPacket.setTo(multiUserChat.getRoom());
// set from my current jis example : me#domain.com
statusPacket.setFrom(new MyPrefrence(XmppBase.context).getUsername());
// get the chat state extension and pass our state
ChatStateExtension extension = new ChatStateExtension(state);
// add the extention to our packet
statusPacket.addExtension(extension);
// get the connection and send the packet
Utils.getConnection().sendStanza(statusPacket);
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
}
}
Usage :
sendMucTypingStatus(ChatState.composing);
watch this : Quick overview of using
With RxJava and Jake Wharton's RxBinding, it's quite simple to do:
RxTextView.afterTextChangeEvents(editText)
.observeOn(Schedulers.io())
.skip(1)
.map({ input ->
// FIRE ChatState.composing EVENT HERE
input // just returning the argument here
})
.debounce(2, TimeUnit.SECONDS)
.observeOn(Schedulers.io())
.subscribe {
// FIRE ChatState.active EVENT HERE
}
Remember that we will have to write code to catch these events via smack stanzaListener and display it on the UI accordingly!
Code is written in Kotlin, but it is fairly straight forward.
The problem just like the title, I tried to count the user (I defined) who have the same name, I used countinbackground or findinbackground, no matter what I did, the count is always 0. Does anyone can help me, I don't know why. Thanks a lot. Below is my code:
public boolean checknameunique(String n) {
boolean notexist = true;
ParseQuery<Userdata> query = ParseQuery.getQuery(Userdata.class);
query.whereEqualTo("name", n);
/*query.countInBackground(new CountCallback() {
public void done(int count, ParseException e) {
if (e == null) {
name_count = count;
}
}
});*/
query.findInBackground(new FindCallback<Userdata>() {
#Override
public void done(List<Userdata> objects, ParseException e) {
if(e==null) {
int size = objects.size();
name_count = size;
}
}
});
if(name_count>0) {
notexist = false;
Toast.makeText(this,
"Username already exist",
Toast.LENGTH_LONG).show();
}
return notexist;
}
I guess you are not aware that findInBackground method is asynchronous, that is why you have that callback inside. You probably want to learn a bit more about threads and async tasks in Android and Parse.
Here is the correct code you would want to have:
public void checknameunique(String n) {
ParseQuery<Userdata> query = ParseQuery.getQuery(Userdata.class);
query.whereEqualTo("name", n);
query.findInBackground(new FindCallback<Userdata>() {
#Override
public void done(List<Userdata> res, ParseException e) {
if(e == null) {
int size = res.size();
if(res.size() > 0) {
showMessage("Username already exist");
} else {
proceed();
}
} else {
showMessage(e.getMessage());
}
}
});
}
private void showMessage(String message) {
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
private void proceed() {
//TODO:
}