Related
I am using from bellow code for converting numbers to currency format when text changes but when I scrolled the recyclerView I lost true data. What can I do :
public class ManagePriceProductsAdapter extends RecyclerView.Adapter<ManagePriceProductsAdapter.ViewHolder> {
private List<ManagePriceProductsModel.DataValue> managePriceProductsModelList;
private Context context;
private getListDiscountInterface getListDiscountInterface;
private int vendorId = -1;
public ManagePriceProductsAdapter(Context context,
List<ManagePriceProductsModel.DataValue> managePriceProductsModelList,
getListDiscountInterface getListDiscountInterface,
int vendorId) {
this.context = context;
this.managePriceProductsModelList = managePriceProductsModelList;
this.getListDiscountInterface = getListDiscountInterface;
this.vendorId = vendorId;
}
#Override
public ManagePriceProductsAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(context)
.inflate(R.layout.list_item_manage_price_products, viewGroup, false);
return new ManagePriceProductsAdapter.ViewHolder(view,
new DiscountNumberTextWatcherWithSeperator(),
new OriginalNumberTextWatcherWithSeperator());
}
public void getListDiscount() {
getListDiscountInterface.sendGetListDiscountToActivity(managePriceProductsModelList);
}
public void backButton() {
getListDiscountInterface.backButtonForListDiscount(managePriceProductsModelList);
}
public void resetAdapter() {
this.managePriceProductsModelList.clear();
notifyDataSetChanged();
}
#Override
public void onBindViewHolder(final ManagePriceProductsAdapter.ViewHolder viewHolder, int position) {
viewHolder.discountNumberTextWatcherWithSeperator.updatePosition(viewHolder.getAdapterPosition(),
viewHolder.discountPriceEdittext,
viewHolder.originalPriceEdittext);
viewHolder.originalNumberTextWatcherWithSeperator.updatePosition(viewHolder.getAdapterPosition(),
viewHolder.originalPriceEdittext);
try {
if (managePriceProductsModelList.get(viewHolder.getAdapterPosition()).getTitle() != null) {
if (!TextUtils.isEmpty(managePriceProductsModelList.get(viewHolder.getAdapterPosition()).getTitle().trim())) {
String productName = managePriceProductsModelList.get(viewHolder.getAdapterPosition()).getTitle().trim();
viewHolder.titleTextview.setText(productName);
} else {
viewHolder.titleTextview.setText("----");
}
} else {
viewHolder.titleTextview.setText("----");
}
} catch (Exception ex) {
if (vendorId != -1) {
Throwable t = new Throwable(ex + ", vendorId: " + vendorId).fillInStackTrace();
FirebaseCrash.report(t);
} else {
Throwable t = new Throwable(ex + ", vendorId: empty").fillInStackTrace();
FirebaseCrash.report(t);
}
}
try {
if (managePriceProductsModelList.get(viewHolder.getAdapterPosition()).getPrice() != null) {
Long productPrice = managePriceProductsModelList.get(viewHolder.getAdapterPosition()).getPrice();
if (productPrice != null && productPrice != 0 && productPrice > 0) {
viewHolder.originalPriceEdittext.setText(String.valueOf(productPrice));
} else {
viewHolder.originalPriceEdittext.setText("");
}
}
} catch (Exception ex) {
if (vendorId != -1) {
Throwable t = new Throwable(ex + ", vendorId: " + vendorId).fillInStackTrace();
FirebaseCrash.report(t);
} else {
Throwable t = new Throwable(ex + ", vendorId: empty").fillInStackTrace();
FirebaseCrash.report(t);
}
}
try {
if (managePriceProductsModelList.get(viewHolder.getAdapterPosition()).getDiscountedPrice() != null) {
Long discountPrice = managePriceProductsModelList.get(viewHolder.getAdapterPosition()).getDiscountedPrice();
if (discountPrice != null && discountPrice != 0 && discountPrice > 0) {
viewHolder.discountPriceEdittext.setText(String.valueOf(discountPrice));
} else {
viewHolder.discountPriceEdittext.setText("");
}
}
} catch (Exception ex) {
if (vendorId != -1) {
Throwable t = new Throwable(ex + ", vendorId: " + vendorId).fillInStackTrace();
FirebaseCrash.report(t);
} else {
Throwable t = new Throwable(ex + ", vendorId: empty").fillInStackTrace();
FirebaseCrash.report(t);
}
}
}
#Override
public int getItemCount() {
return managePriceProductsModelList.size();
}
public interface getListDiscountInterface {
void sendGetListDiscountToActivity(List<ManagePriceProductsModel.DataValue> managePriceProductsModelList);
void backButtonForListDiscount(List<ManagePriceProductsModel.DataValue> managePriceProductsModelList);
}
class ViewHolder extends RecyclerView.ViewHolder {
//region ViewBinding
#BindView(R.id.title_textview)
TextView titleTextview;
#BindView(R.id.original_price_edittext)
EditText originalPriceEdittext;
#BindView(R.id.discount_price_edittext)
EditText discountPriceEdittext;
DiscountNumberTextWatcherWithSeperator discountNumberTextWatcherWithSeperator;
OriginalNumberTextWatcherWithSeperator originalNumberTextWatcherWithSeperator;
//endregion
ViewHolder(View view,
DiscountNumberTextWatcherWithSeperator discountNumberTextWatcherWithSeperator,
OriginalNumberTextWatcherWithSeperator originalNumberTextWatcherWithSeperator) {
super(view);
ButterKnife.bind(this, itemView);
this.discountNumberTextWatcherWithSeperator = discountNumberTextWatcherWithSeperator;
this.discountPriceEdittext.addTextChangedListener(discountNumberTextWatcherWithSeperator);
this.originalNumberTextWatcherWithSeperator = originalNumberTextWatcherWithSeperator;
this.originalPriceEdittext.addTextChangedListener(originalNumberTextWatcherWithSeperator);
}
}
private class DiscountNumberTextWatcherWithSeperator implements TextWatcher {
private EditText discountEditText;
private EditText originalEditText;
private int position;
private String getDecimalFormattedString(String value) {
StringTokenizer lst = new StringTokenizer(value, ".");
String str1 = value;
String str2 = "";
if (lst.countTokens() > 1) {
str1 = lst.nextToken();
str2 = lst.nextToken();
}
String str3 = "";
int i = 0;
int j = -1 + str1.length();
if (str1.charAt(-1 + str1.length()) == '.') {
j--;
str3 = ".";
}
for (int k = j; ; k--) {
if (k < 0) {
if (str2.length() > 0)
str3 = str3 + "." + str2;
return str3;
}
if (i == 3) {
str3 = "," + str3;
i = 0;
}
str3 = str1.charAt(k) + str3;
i++;
}
}
public void updatePosition(int position,
EditText discountEditText,
EditText originalEditText) {
this.position = position;
this.discountEditText = discountEditText;
this.originalEditText = originalEditText;
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
if (charSequence.length() > 0) {
originalEditText.setPaintFlags(originalEditText.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
ManagePriceProductsModel.DataValue dataValue = new ManagePriceProductsModel.DataValue();
dataValue.setTitle(managePriceProductsModelList.get(position).getTitle().trim());
dataValue.setId(managePriceProductsModelList.get(position).getId());
dataValue.setPrice(managePriceProductsModelList.get(position).getPrice());
dataValue.setDiscountedPrice(Long.parseLong(charSequence.toString().replace(",", "")));
managePriceProductsModelList.set(position, dataValue);
} else if (charSequence.length() == 0) {
originalEditText.setPaintFlags(originalEditText.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG));
ManagePriceProductsModel.DataValue dataValue = new ManagePriceProductsModel.DataValue();
dataValue.setTitle(managePriceProductsModelList.get(position).getTitle().trim());
dataValue.setId(managePriceProductsModelList.get(position).getId());
dataValue.setPrice(managePriceProductsModelList.get(position).getPrice());
dataValue.setDiscountedPrice(null);
managePriceProductsModelList.set(position, dataValue);
}
}
#Override
public void afterTextChanged(Editable editable) {
try {
discountEditText.removeTextChangedListener(this);
String value = discountEditText.getText().toString();
if (!value.equals("")) {
if (value.startsWith(".")) {
discountEditText.setText("0.");
}
if (value.startsWith("0") && !value.startsWith("0.")) {
discountEditText.setText("");
}
String str = discountEditText.getText().toString().replaceAll(",", "");
if (!value.equals(""))
discountEditText.setText(getDecimalFormattedString(str));
discountEditText.setSelection(discountEditText.getText().toString().length());
}
discountEditText.addTextChangedListener(this);
} catch (Exception ex) {
ex.printStackTrace();
discountEditText.addTextChangedListener(this);
}
}
}
private class OriginalNumberTextWatcherWithSeperator implements TextWatcher {
private EditText editText;
private int position;
private String getDecimalFormattedString(String value) {
StringTokenizer lst = new StringTokenizer(value, ".");
String str1 = value;
String str2 = "";
if (lst.countTokens() > 1) {
str1 = lst.nextToken();
str2 = lst.nextToken();
}
String str3 = "";
int i = 0;
int j = -1 + str1.length();
if (str1.charAt(-1 + str1.length()) == '.') {
j--;
str3 = ".";
}
for (int k = j; ; k--) {
if (k < 0) {
if (str2.length() > 0)
str3 = str3 + "." + str2;
return str3;
}
if (i == 3) {
str3 = "," + str3;
i = 0;
}
str3 = str1.charAt(k) + str3;
i++;
}
}
public void updatePosition(int position,
EditText editText) {
this.position = position;
this.editText = editText;
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
if (charSequence.length() > 0) {
ManagePriceProductsModel.DataValue dataValue = new ManagePriceProductsModel.DataValue();
dataValue.setTitle(managePriceProductsModelList.get(position).getTitle().trim());
dataValue.setId(managePriceProductsModelList.get(position).getId());
dataValue.setPrice(Long.parseLong(charSequence.toString().replace(",", "")));
dataValue.setDiscountedPrice(managePriceProductsModelList.get(position).getDiscountedPrice());
managePriceProductsModelList.set(position, dataValue);
} else if (charSequence.length() == 0) {
ManagePriceProductsModel.DataValue dataValue = new ManagePriceProductsModel.DataValue();
dataValue.setTitle(managePriceProductsModelList.get(position).getTitle().trim());
dataValue.setId(managePriceProductsModelList.get(position).getId());
dataValue.setPrice(null);
dataValue.setDiscountedPrice(managePriceProductsModelList.get(position).getDiscountedPrice());
managePriceProductsModelList.set(position, dataValue);
}
}
#Override
public void afterTextChanged(Editable editable) {
try {
editText.removeTextChangedListener(this);
String value = editText.getText().toString();
if (!value.equals("")) {
if (value.startsWith(".")) {
editText.setText("0.");
}
if (value.startsWith("0") && !value.startsWith("0.")) {
editText.setText("");
}
String str = editText.getText().toString().replaceAll(",", "");
if (!value.equals(""))
editText.setText(getDecimalFormattedString(str));
editText.setSelection(editText.getText().toString().length());
}
editText.addTextChangedListener(this);
} catch (Exception ex) {
ex.printStackTrace();
editText.addTextChangedListener(this);
}
}
}
}
As the comments above it is not recommended to use edittext in recyclerview.
If you have to do this can you try to use
viewHolder.setIsRecyclable(false);
in your onBindViewHolder method
You can use this library to support this
Create a ViewState
new ViewState<>() {
private String savedValue; /* here will be saved a value for each item by createViewStateID() */
#Override
public void clear(#NonNull final ViewHolder<ViewFinder> holder) {
holder.getViewFinder().setText(R.id.text, "");
}
#Override
public void save(#NonNull final ViewHolder<ViewFinder> holder) {
savedValue = holder.getViewFinder().<EditText>find(R.id.text).getText().toString();
}
#Override
public void restore(#NonNull final ViewHolder<ViewFinder> holder) {
holder.getViewFinder().setText(R.id.text, savedValue);
}
};
Set that ViewState to your ViewRenderer
adapter.registerRenderer(new ViewRenderer<>(
R.layout.your_item_layout, //your layout
YourItemModel.class, //your model
(model, finder, payloads) -> finder.setText(R.id.text, model.getValue()), //your binding
getYourViewStateProvider() // here is your ViewState
));
More info you can find here
You can use the code below to keep hold of your dynamic values.
Paste this code inside your adapter. This allows to assign a unique id to your items. Just make sure the id assigned to all the items in the recyclerview must be unique.
override fun getItemViewType(position: Int) = position
override fun getItemId(position: Int) = position.toLong()
I develop an Android app which interacts with Google Firebase Cloud Firestore. To get data from Firestore, I use addOnCompleteListener with DocumentSnapshot.toObject() method. However, method toObject() seems not to work properly because it doesn't transmit data from snapshot to object.
Goal.class
#Entity
public class Goal {
// private variables
#PrimaryKey (autoGenerate = true)
private int id;
private String remoteId;
private int goalPos;
private String goalName;
private int goalCategory;
private String goalDescription;
private int goalColor;
private int goalFrequency;
private long goalFrequencyCode;
private boolean goalRewardType;
private double goalReward;
private int activated;
private boolean isSynced;
// constructor
public Goal() {
remoteId = "";
goalPos = 0;
goalName = "";
goalCategory = 15;
goalDescription = "";
goalColor = R.color.cat_Black;
goalFrequency = 0; // 0=Daily, 1=Weekly, 2=Monthly
goalFrequencyCode = 1111111111; // 1111111.111 - Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday; first of month, middle of month, last of month
goalRewardType = false; // false = standard, true = individual
activated = 1; // 0=No, 1=Yes
isSynced = false;
}
// getter and setter
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRemoteId() {
return remoteId;
}
public void setRemoteId(String remoteId) {
this.remoteId = remoteId;
}
public int getGoalPos() {
return goalPos;
}
public void setGoalPos(int goalPos) {
this.goalPos = goalPos;
}
public String getGoalName() {
return goalName;
}
public void setGoalName(String goalName) {
this.goalName = goalName;
}
public int getGoalCategory() {
return goalCategory;
}
public void setGoalCategory(int goalCategory) {
this.goalCategory = goalCategory;
}
public String getGoalDescription() {
return goalDescription;
}
public void setGoalDescription(String goalDescription) {
this.goalDescription = goalDescription;
}
public int getGoalColor() {
return goalColor;
}
public void setGoalColor(int goalColor) {
this.goalColor = goalColor;
}
public int getGoalFrequency() {
return goalFrequency;
}
public void setGoalFrequency(int goalFrequency) {
this.goalFrequency = goalFrequency;
}
public long getGoalFrequencyCode() {
return goalFrequencyCode;
}
public void setGoalFrequencyCode(long goalFrequencyCode) {
this.goalFrequencyCode = goalFrequencyCode;
}
public LinkedList<Integer> getGoalFrequencyCodeAsList() {
LinkedList<Integer> stack = new LinkedList<>();
long number = goalFrequencyCode;
while (number > 0) {
long longTempMod = number % 10;
int intTempMod = (int) longTempMod;
stack.push(intTempMod);
number = number / 10;
}
return stack;
}
public void setGoalFrequencyCodeFromList(LinkedList<Integer> stack) {
double number = 0;
for (int j = 0; j < stack.size(); j++) {
Log.d(String.valueOf(j), String.valueOf(stack.get(j)));
}
if (stack.size() <= 1) {
goalFrequencyCode = 1111111111;
} else {
for (int i = 0; i < stack.size(); i++) {
Log.d(String.valueOf(stack.get(i)), String.valueOf(number));
number = number + (stack.get(i) * Math.pow(10, (stack.size() - 1 - i)));
}
Log.d("Sent from Goal - number", String.valueOf(number));
goalFrequencyCode = (long) number;
Log.d("Sent from Goal - long", String.valueOf(goalFrequencyCode));
}
}
public boolean getGoalRewardType() {
return goalRewardType;
}
public void setGoalRewardType(boolean goalRewardType) {
this.goalRewardType = goalRewardType;
}
public double getGoalReward() {
return goalReward;
}
public void setGoalReward(double goalReward) {
this.goalReward = goalReward;
}
public int getActivated() {
return activated;
}
public void setActivated(int activated) {
this.activated = activated;
}
public boolean getIsSynced() {
return isSynced;
}
public void setIsSynced(boolean isSynced) {
this.isSynced = isSynced;
}
#Override
public String toString() {
return "Goal{" +
"id=" + id +
", remoteId='" + remoteId + '\'' +
", goalPos=" + goalPos +
", goalName='" + goalName + '\'' +
", goalCategory=" + goalCategory +
", goalDescription='" + goalDescription + '\'' +
", goalColor=" + goalColor +
", goalFrequency=" + goalFrequency +
", goalFrequencyCode=" + goalFrequencyCode +
", goalRewardType=" + goalRewardType +
", goalReward=" + goalReward +
", activated=" + activated +
", isSynced=" + isSynced +
'}';
}
}
FirebaseService.class
public LiveData<ApiResponse<List<Goal>>> getGoals() {
final MutableLiveData<ApiResponse<List<Goal>>> list = new MutableLiveData<>();
if (mAuth.getCurrentUser() != null) {
userId = mAuth.getCurrentUser().getUid();
colRefGoals = firestore.collection(userId).document("data").collection("goals");
colRefGoals
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
List<Goal> goalsList = new ArrayList<Goal>();
for (DocumentSnapshot documentSnapshot : task.getResult()) {
Log.d("firebaseService", "DocumentSnapshop.getData: " + documentSnapshot.getData());
Goal goal = documentSnapshot.toObject(Goal.class);
Log.d("firebaseService", "DocumentSnapshot.toObject(Goal.class): " + goal.toString());
goalsList.add(goal);
}
ApiResponse<List<Goal>> apiResponse = new ApiResponse<List<Goal>>(goalsList);
list.setValue(apiResponse);
}
}
});
} else {
Throwable error = new Throwable("No user logged in");
ApiResponse<List<Goal>> apiResponse = new ApiResponse<List<Goal>>(error);
list.setValue(apiResponse);
return list;
}
return list;
}
Following my debug log comparison between .getData and .toObject:
12-05 19:53:42.663 11470-11470/com.benjaminsommer.dailygoals D/firebaseService: DocumentSnapshop.getData: {goals={goalRewardType=true, remoteId=10L44s0EcvTTzGajzhidgoals, id=2, goalFrequencyCode=1001111111, activated=1, goalColor=-4365347, goalCategory=8, goalDescription=Description Test, goalReward=1, goalPos=1, goalFrequency=2, goalName=Test}}
12-05 19:53:42.663 11470-11470/com.benjaminsommer.dailygoals D/firebaseService: DocumentSnapshot.toObject(Goal.class): Goal{id=0, remoteId='', goalPos=0, goalName='', goalCategory=15, goalDescription='', goalColor=2131558437, goalFrequency=0, goalFrequencyCode=1111111111, goalRewardType=false, goalReward=0.0, activated=1, isSynced=false}
.toObject doesn't transform the datasnapshot to my class. I already checked the documentation:
Important: Each custom class must have a public constructor that takes
no arguments. In addition, the class must include a public getter for
each property.
I have a constructor with no args and public getters for each property. I tried it with an empty constructor, but not working either. Is anything wrong with my getters? I use it in combination with Room, maybe there can be an issue?
Really appreciate your help and support.
Thanks, Ben
I am using RxTextView.textChanges for EditText that when the user is typing change value of EditText to convert numbers to currency format like below:
1,000
But I can't see any convert numbers to currency format.
I am using from: NumberFormat.getNumberInstance(Locale.US).format(productPrice);
My code is like bellow:
Observable<CharSequence> observableDiscountPrice = RxTextView.textChanges(discountPriceEdittext);
observableDiscountPrice.map(new Function<CharSequence, Boolean>() {
#Override
public Boolean apply(#io.reactivex.annotations.NonNull CharSequence charSequence) throws Exception {
try {
if (charSequence.length() > 0) {
String pPrice = NumberFormat.getNumberInstance(Locale.US).format(charSequence.toString());
originalPriceEdittext.setText(String.valueOf(pPrice));
return true;
} else {
return false;
}
} catch (Exception e) {
return true;
}
}
}).subscribe(new Subject<Boolean>() {
#Override
public boolean hasObservers() {
return false;
}
#Override
public boolean hasThrowable() {
return false;
}
#Override
public boolean hasComplete() {
return false;
}
#Override
public Throwable getThrowable() {
return null;
}
#Override
protected void subscribeActual(Observer<? super Boolean> observer) {
}
#Override
public void onSubscribe(#io.reactivex.annotations.NonNull Disposable d) {
}
#Override
public void onNext(#io.reactivex.annotations.NonNull Boolean aBoolean) {
}
#Override
public void onError(#io.reactivex.annotations.NonNull Throwable e) {
}
#Override
public void onComplete() {
}
});
Use this TextWatcher class:
public class NumberTextWatcherWithSeperator implements TextWatcher {
private EditText editText;
public NumberTextWatcherWithSeperator(EditText editText) {
this.editText = editText;
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
try {
editText.removeTextChangedListener(this);
String value = editText.getText().toString();
if (!value.equals("")) {
if (value.startsWith(".")) {
editText.setText("0.");
}
if (value.startsWith("0") && !value.startsWith("0.")) {
editText.setText("");
}
String str = editText.getText().toString().replaceAll(",", "");
if (!value.equals(""))
editText.setText(getDecimalFormattedString(str));
editText.setSelection(editText.getText().toString().length());
}
editText.addTextChangedListener(this);
} catch (Exception ex) {
ex.printStackTrace();
editText.addTextChangedListener(this);
}
}
private static String getDecimalFormattedString(String value) {
StringTokenizer lst = new StringTokenizer(value, ".");
String str1 = value;
String str2 = "";
if (lst.countTokens() > 1) {
str1 = lst.nextToken();
str2 = lst.nextToken();
}
String str3 = "";
int i = 0;
int j = -1 + str1.length();
if (str1.charAt(-1 + str1.length()) == '.') {
j--;
str3 = ".";
}
for (int k = j; ; k--) {
if (k < 0) {
if (str2.length() > 0)
str3 = str3 + "." + str2;
return str3;
}
if (i == 3) {
str3 = "," + str3;
i = 0;
}
str3 = str1.charAt(k) + str3;
i++;
}
}
}
and
yourEditText.addTextChangedListener(new NumberTextWatcherWithSeperator(yourEditText));
Take a look at https://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html
DecimalFormat myFormatter = new DecimalFormat("###,###.###");
String output = myFormatter.format(156456.673);
System.out.println(156456.673 + " " + "###,###.###" + " " + output);
// I/System.out: 156456.673 ###,###.### 156,456.673
I'm using this watcher to do the same thing:
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
public class CurrencyTextWatcher implements TextWatcher {
private EditText ed;
private String lastText;
private boolean bDel = false;
private boolean bInsert = false;
private int pos;
public CurrencyTextWatcher(EditText ed) {
this.ed = ed;
}
public static String getStringWithSeparator(long value) {
DecimalFormat formatter = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
String f = formatter.format(value);
return f;
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
bDel = false;
bInsert = false;
if (before == 1 && count == 0) {
bDel = true;
pos = start;
} else if (before == 0 && count == 1) {
bInsert = true;
pos = start;
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
lastText = s.toString();
}
#Override
public void afterTextChanged(Editable s) {
ed.removeTextChangedListener(this);
StringBuilder sb = new StringBuilder();
String text = s.toString();
for (int i = 0; i < text.length(); i++) {
if ((text.charAt(i) >= 0x30 && text.charAt(i) <= 0x39) || text.charAt(i) == '.' || text.charAt(i) == ',')
sb.append(text.charAt(i));
}
if (!sb.toString().equals(s.toString())) {
bDel = bInsert = false;
}
String newText = getFormattedString(sb.toString());
s.clear();
s.append(newText);
ed.addTextChangedListener(this);
if (bDel) {
int idx = pos;
if (lastText.length() - 1 > newText.length())
idx--;
if (idx < 0)
idx = 0;
ed.setSelection(idx);
} else if (bInsert) {
int idx = pos + 1;
if (lastText.length() + 1 < newText.length())
idx++;
if (idx > newText.length())
idx = newText.length();
ed.setSelection(idx);
}
}
private String getFormattedString(String text) {
String res = "";
try {
String temp = text.replace(",", "");
long part1;
String part2 = "";
int dotIndex = temp.indexOf(".");
if (dotIndex >= 0) {
part1 = Long.parseLong(temp.substring(0, dotIndex));
if (dotIndex + 1 <= temp.length()) {
part2 = temp.substring(dotIndex + 1).trim().replace(".", "").replace(",", "");
}
} else
part1 = Long.parseLong(temp);
res = getStringWithSeparator(part1);
if (part2.length() > 0)
res += "." + part2;
else if (dotIndex >= 0)
res += ".";
} catch (Exception ex) {
ex.printStackTrace();
}
return res;
}
}
In case you want to and a dollar sign
fun multiply_two_numbers() {
val x = etValOne.text.toString()
val y = etValTwo.text.toString()
val c = x.toDouble().times(y.toDouble())
//val c = (x.toDouble() * y.toDouble())
val df = DecimalFormat("$ "+"0.00")
df.roundingMode = RoundingMode.CEILING
df.format(c)
etANS.setText(df.format(c))
}
I have a Comparator to sort by 3 values:
ORDER_BY_Points
ORDER_BY_Gdif // goals difference
ORDER_BY_Goals
First I get a array from a json string. I send the array to StandingsSort.ORDER_BY_RULES
Arrays.sort(addressArray, StandingsSort.ORDER_BY_RULES);
Here is my code:
static final Comparator<Standings> ORDER_BY_Points = new Comparator<Standings>() {
public int compare(Standings a1, Standings a2) {
return a1.points.compareTo(a2.points);
}
};
static final Comparator<Standings> ORDER_BY_Gdif = new Comparator<Standings>() {
public int compare(Standings a1, Standings a2) {
return a1.Gdif.compareTo(a2.Gdif);
}
};
static final Comparator<Standings> ORDER_BY_Goals = new Comparator<Standings>() {
public int compare(Standings a1, Standings a2) {
return a1.goalsP.compareTo(a2.goalsP);
}
};
static final Comparator<Standings> ORDER_BY_RULES = new Comparator<Standings>() {
public int compare(Standings a1, Standings a2) {
int i = ORDER_BY_Points.compare(a1,a2);
if(i == 0){
i = ORDER_BY_Gdif.compare(a1,a2);
if(i == 0){
i = ORDER_BY_Goals.compare(a1,a2);
}
}
return i;
}
};
class Standings {
String teamName;
String goalsP;
String goalsM;
String Gdif;
String points;
#Override
public String toString() {
return "" + teamName + "," + goalsP + ":" + goalsM + "," + Gdif + "," + points + "";
}
public Standings(String teamName, String goalsP,
String goalsM, String Gdif, String points) {
super();
this.teamName = teamName;
this.goalsP = goalsP;
this.goalsM = goalsM;
this.Gdif = Gdif;
this.points = points;
}
}
But the result is not OK! Here is the result
Name, Goals, GDif, Points
Team,11:9,2,10
Team,5:3,2,10
Team,9:2,7,11
Team,0:6,-6,2
Team,3:9,-6,2
Team,6:9,-3,3
Team,8:13,-5,3
Team,8:9,-1,5
Team,8:11,-3,5
Team,8:7,1,5
Why does the Comparator sort wrong?
Since you store the points as Strings, "10" comes before "2", "3", and "5". If you want to compare these in order by the numerical value, you need to convert them into ints first.
Similarly, Gdif and Goals are compared as Strings which is probably not what you want.
is it possible to get the position of a touch when the user touches my widget on the homescreen? TIA
edit: my widget code:
public class MyWidgetProvider extends AppWidgetProvider {
public static String ACTION_WIDGET_MEMO = "comNgarsideMemoActionWidgetMemo";
public static String ACTION_WIDGET_PEN = "comNgarsideMemoActionWidgetPen";
public static String ACTION_WIDGET_ERASER = "comNgarsideMemoActionWidgetEraser";
public static String ACTION_WIDGET_UNDO = "comNgarsideMemoActionWidgetUndo";
public static String ACTION_WIDGET_REDO = "comNgarsideMemoActionWidgetRedo";
public static String ACTION_WIDGET_SAVE = "comNgarsideMemoActionWidgetSave";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
Intent memoIntent = new Intent(context, ListActivity.class);
memoIntent.setAction(ACTION_WIDGET_MEMO);
Intent penIntent = new Intent(context, MyWidgetProvider.class);
penIntent.setAction(ACTION_WIDGET_PEN);
Intent eraserIntent = new Intent(context, MyWidgetProvider.class);
eraserIntent.setAction(ACTION_WIDGET_ERASER);
Intent undoIntent = new Intent(context, MyWidgetProvider.class);
undoIntent.setAction(ACTION_WIDGET_UNDO);
Intent redoIntent = new Intent(context, MyWidgetProvider.class);
redoIntent.setAction(ACTION_WIDGET_REDO);
Intent saveIntent = new Intent(context, MyWidgetProvider.class);
saveIntent.setAction(ACTION_WIDGET_SAVE);
PendingIntent memoPendingIntent = PendingIntent.getActivity(context, 0, memoIntent, 0);
PendingIntent penPendingIntent = PendingIntent.getBroadcast(context, 0, penIntent, 0);
PendingIntent eraserPendingIntent = PendingIntent.getBroadcast(context, 0, eraserIntent, 0);
PendingIntent undoPendingIntent = PendingIntent.getBroadcast(context, 0, undoIntent, 0);
PendingIntent redoPendingIntent = PendingIntent.getBroadcast(context, 0, redoIntent, 0);
PendingIntent savePendingIntent = PendingIntent.getBroadcast(context, 0, saveIntent, 0);
remoteViews.setOnClickPendingIntent(R.id.iconBtn, memoPendingIntent);
remoteViews.setOnClickPendingIntent(R.id.penBtn, penPendingIntent);
remoteViews.setOnClickPendingIntent(R.id.eraserBtn, eraserPendingIntent);
remoteViews.setOnClickPendingIntent(R.id.undoBtn, undoPendingIntent);
remoteViews.setOnClickPendingIntent(R.id.redoBtn, redoPendingIntent);
remoteViews.setOnClickPendingIntent(R.id.saveBtn, savePendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
}
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
final int appWidgetId = intent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
this.onDeleted(context, new int[] { appWidgetId });
}
} else {
if (intent.getAction().equals(ACTION_WIDGET_PEN)) {
} else if (intent.getAction().equals(ACTION_WIDGET_ERASER)) {
} else if (intent.getAction().equals(ACTION_WIDGET_UNDO)) {
} else if (intent.getAction().equals(ACTION_WIDGET_REDO)) {
} else if (intent.getAction().equals(ACTION_WIDGET_SAVE)) {
}
super.onReceive(context, intent);
}
}
}
Maybe this will give you an idea...
PressureDynamics.java
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.content.Context;
import android.util.Log;
/**
* Keyboard sensor
*/
public class PressureDynamics extends Thread implements FeatureExtractor{
public static final String AVG_TOUCH_PRESSURE = "Avg_Touch_Pressure";
public static final String AVG_TOUCH_AREA = "Avg_Touch_Area";
private static final int EVENT_BYTE_SIZE = 16;
private InputStream _fis = null;
private boolean _shouldRun;
private Map<String, TouchScreenSensor> _sensors;
public PressureDynamics(Context context, Collection<FeatureInfo> featureInfos,
Long timeStamp){
super("Pressure Dynamics Feature Extractor Thread");
_shouldRun = true;
_sensors = new HashMap<String, TouchScreenSensor>();
int featureCount = 0;
for (FeatureInfo featureInfo : featureInfos){
String name = featureInfo.name;
try{
if (name.equalsIgnoreCase(AVG_TOUCH_PRESSURE)){
TouchScreenSensor s = new AvgTouchPressureSensor(featureInfo);
_sensors.put(AVG_TOUCH_PRESSURE, s);
}else if (name.equalsIgnoreCase(AVG_TOUCH_AREA)){
TouchScreenSensor s = new AvgTouchAreaSensor(featureInfo);
_sensors.put(AVG_TOUCH_AREA, s);
}else{
Log.e(FE_TAG, "Unhandled feature by " + getClass().getCanonicalName()
+ ": " + name);
continue;
}
++featureCount;
}catch(RuntimeException e){
Log.e(FE_TAG, "Unable to initialize feature: " + name, e);
}
}
if (featureCount == 0){
throw new FeatureExtractorInitException("No features of "
+ getClass().getCanonicalName() + " could be initialized");
}
_fis = openTouchScreenInputStream();
start();
}
private static InputStream openTouchScreenInputStream(){
final String HTC_TOUCH_SCREEN_INPUT_FILEPATH = "/dev/input/event1";
LocalServerConn localServerConn;
try{
localServerConn = LocalServerConn.getInstance();
localServerConn.runLocalServer();
}catch(Exception e){
throw new FeatureExtractorInitException(
"Unable to collect Touch Screen features", e);
}
try{
FileDescriptor[] fdArr = localServerConn
.sendFileDescriptorReq(HTC_TOUCH_SCREEN_INPUT_FILEPATH);
if (fdArr == null || fdArr.length == 0){
throw new FeatureExtractorInitException("Can't open keyboard device");
}
return new FileInputStream(fdArr[0]);
}catch(IOException e){
throw new FeatureExtractorInitException("Can't open keyboard input stream: "
+ e.getMessage(), e);
}
}
public void close(){
_shouldRun = false;
}
public void collectData(List<MonitoredData> monitoredData, ParcelableDate endTime){
for (Sensor s : _sensors.values()){
s.collectData(monitoredData, endTime);
}
}
public void run(){
int n;
int pos = 0;
byte[] buffer = new byte[256];
for (;;){
try{
n = _fis.read(buffer, pos, EVENT_BYTE_SIZE);
/*
* check if we are shutting down - this may have the thread hanging around
* until the next touch event comes in
*/
if (_shouldRun == false){
break;
}
pos += n;
// Log.v(FE_TAG, "read touch screen event: " + n + " bytes\n");
if (pos >= EVENT_BYTE_SIZE){
long currentTimeMillis = System.currentTimeMillis();
TouchEvent touchScreenEvent = new TouchEvent(buffer,
currentTimeMillis);
updateSensors(touchScreenEvent, currentTimeMillis);
pos -= EVENT_BYTE_SIZE;
}
}catch(IOException e){
Log.e(FE_TAG, e.getMessage(), e);
}
}
}
private void updateSensors(TouchEvent touchScreenEvent, long currentTimeMillis){
try{
// currently filter out all non preassure event types
//
switch ((int)touchScreenEvent.getCode()){
case TouchEvent.X_POS_EVENT:
case TouchEvent.Y_POS_EVENT:
case TouchEvent.TOUCH_DEVICE_TYPE_EVENT:
break;
case TouchEvent.ABS_PRESSURE_EVENT:
_sensors.get(AVG_TOUCH_PRESSURE).updateSensor(touchScreenEvent,
currentTimeMillis);
break;
case TouchEvent.ABS_TOOL_WIDTH_EVENT:
_sensors.get(AVG_TOUCH_AREA).updateSensor(touchScreenEvent,
currentTimeMillis);
break;
default:
Log.e(FE_TAG, "unrecognized touch event code :"
+ touchScreenEvent.getCode());
break;
}
}catch(Exception e){
Log.e(FE_TAG, e.getMessage(), e);
}
}
public String toString(){
return getClass().getSimpleName();
}
private static abstract class TouchScreenSensor extends Sensor{
private TouchScreenSensor(String name, FeatureInfo info){
//super(name, info.getValueTimeout());
super(name);
}
public abstract void updateSensor(TouchEvent event, long currentTimeMillis);
}
private static class AvgTouchPressureSensor extends TouchScreenSensor{
public AvgTouchPressureSensor(FeatureInfo info){
super(AVG_TOUCH_PRESSURE, info);
}
public void updateSensor(TouchEvent event, long currentTimeMillis){
addToAvg(event.getValue(), currentTimeMillis);
}
}
private static class AvgTouchAreaSensor extends TouchScreenSensor{
public AvgTouchAreaSensor(FeatureInfo info){
super(AVG_TOUCH_AREA, info);
}
public void updateSensor(TouchEvent event, long currentTimeMillis){
addToAvg(event.getValue(), currentTimeMillis);
}
}
}
Sensor.java
import java.util.List;
public class Sensor{
private final String _name;
private Double _avg;
private int _count;
private long _lastValueUpdateTime;
/**
* Constructor
*
* #param name The name of the feature that is collected by this sensor
* #param valueTimeout The time period of no value changes it takes for the current
* value to reset to the initial value (in millis)
*/
public Sensor(String name){
_lastValueUpdateTime = 0;
_name = name;
_avg = null;
_count = 0;
}
public void collectData(List<MonitoredData> monitoredData, ParcelableDate endTime){
Double value = getValue(endTime.getTime());
if (value != null){
value = Utils.truncateDouble(value);
}
monitoredData.add(new MonitoredData(_name, value, endTime));
}
public Double getValue(long time){
if (time - _lastValueUpdateTime > MainActivity.getAgentLoopTime()){
_avg = null;
_count = 0;
}
return _avg;
}
public String getName(){
return _name;
}
public void addToAvg(double value, long time){
Double avg = getValue(time);
if (avg == null){
avg = value; // Initial value
}else{
value = (avg * _count + value) / (_count + 1);
}
++_count;
_avg = value;
_lastValueUpdateTime = time;
}
#Override
public String toString(){
return _name;
}
}
TouchEvent.java
import android.util.Log;
import dt.util.Utils;
public class TouchEvent{
public static final int ABS_PRESSURE_EVENT = 0x18;
public static final int ABS_TOOL_WIDTH_EVENT = 0x1c;
public static final int X_POS_EVENT = 0x0;
public static final int Y_POS_EVENT = 0x1;
/* type of touching device ie. finger, stylus etc. */
public static final int TOUCH_DEVICE_TYPE_EVENT = 0x14a;
// private final long _timeStamp;
// private final int _sec;
// private final int _usec;
// 3, 1, 0 - ?
// private final long _type;
// different event types have different codes
private final long _code;
private final int _value;
//
public TouchEvent(byte[] _buffer, long currentTimeMillis){
int pos;
byte b[] = new byte[4];
byte s[] = new byte[2];
// _timeStamp = currentTimeMillis;
pos = 0;
// _sec = Utils.LittleEndianBytesToInt(_buffer);
pos += 4;
System.arraycopy(_buffer, pos, b, 0, 4);
// _usec = Utils.LittleEndianBytesToInt(b);
pos += 4;
// _type = Utils.LittleEndianBytesToUShort(s);
pos += 2;
System.arraycopy(_buffer, pos, s, 0, 2);
_code = Utils.littleEndianBytesToUShort(s);
pos += 2;
System.arraycopy(_buffer, pos, b, 0, 4);
_value = Utils.littleEndianBytesToInt(b);
if (_code != X_POS_EVENT && _code != Y_POS_EVENT
&& _code != TOUCH_DEVICE_TYPE_EVENT && _code != ABS_PRESSURE_EVENT
&& _code != ABS_TOOL_WIDTH_EVENT){
Log.d(FE_TAG, "unrecognized touch event code :" + _code);
}
}
public long getCode(){
return _code;
}
public double getValue(){
return _value;
}
}
FeatureInfo.java
import java.util.HashMap;
public class FeatureInfo{
/** The name of the feature */
public final String name;
/** The parameters relevant to the feature */
public final HashMap<String, String> params;
/**
* Constructs a FeatureInfo object from the given parameters
*
* #param name The name of the feature
* #param params The parameters relevant to the feature
*/
public FeatureInfo(String name, HashMap<String, String> params){
this.name = name;
this.params = (params == null) ? new HashMap<String, String>() : params;
}
#Override
public String toString(){
return name;
}
public int getTimeWindow() throws IllegalArgumentException{
final String paramName = "Time_Window";
try{
int timeWindow = Integer.parseInt(params.get(paramName)) * 1000;
if (timeWindow <= 0){
throw new IllegalArgumentException("Must be a positive integer");
}
return timeWindow;
}catch(Exception e){// NullPointer or Parsing
throw new IllegalArgumentException("Corrupt parameter: " + paramName
+ " in feature " + name, e);
}
}
// public int getTimeWindow() throws IllegalArgumentException{
// final String paramName = "Time_Window";
// try{
// int timeWindow = Integer.parseInt(params.get(paramName)) * 1000;
// if (timeWindow <= 0){
// throw new IllegalArgumentException("Must be a positive integer");
// }
// return timeWindow;
// }catch(Exception e){// NullPointer or Parsing
// throw new IllegalArgumentException("Corrupt parameter: " + paramName
// + " in feature " + name, e);
// }
// }
public int getValueTimeout() throws IllegalArgumentException{
final String paramName = "Value_Timeout";
try{
int valueTimeout = Integer.parseInt(params.get(paramName)) * 1000;
if (valueTimeout <= 0){
throw new IllegalArgumentException("Must be a positive integer");
}
return valueTimeout;
}catch(Exception e){// NullPointer or Parsing
throw new IllegalArgumentException("Corrupt parameter: " + paramName
+ " in feature " + name, e);
}
}
public double getMovieAverageWeight() throws IllegalArgumentException{
final String paramName = "Moving_Average_Weight";
try{
double movingAverageWeight = Double.parseDouble(params.get(paramName));
if (movingAverageWeight < 0 || movingAverageWeight > 1){
throw new IllegalArgumentException("Must be positive and 1.0 at most");
}
return movingAverageWeight;
}catch(Exception e){// NullPointer or Parsing
throw new IllegalArgumentException("Corrupt parameter: " + paramName
+ " in feature " + name, e);
}
}
public boolean getIncludeEventTimes(){
final String paramName = "Include_Event_Times";
return Boolean.parseBoolean(params
.get(paramName));
}
public boolean getIncludeMaximalEntity(){
final String paramName = "Include_Maximal_Entity";
return Boolean.parseBoolean(params
.get(paramName));
}
}
MonitoredData.java
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
#SuppressWarnings("unchecked")
public class MonitoredData implements Map, Parcelable{
public static final int DEFAULT = 0;
public static final int HAS_EXTRAS = 1;
protected String _name;
protected ParcelableDate _startTime, _endTime;
protected Object _value;
protected Bundle _extras;
public static final Parcelable.Creator<MonitoredData> CREATOR = new Parcelable.Creator<MonitoredData>(){
public MonitoredData createFromParcel(Parcel in){
ClassLoader cl = ParcelableDate.class.getClassLoader();
String name = in.readString();
Object value = in.readValue(null);
ParcelableDate startTime = (ParcelableDate)in.readParcelable(cl);
ParcelableDate endTime = (ParcelableDate)in.readParcelable(cl);
Bundle extras = in.readBundle();
MonitoredData monitoredData = new MonitoredData(name, value, startTime,
endTime);
if (extras != null){
monitoredData.setExtras(extras);
}
return monitoredData;
}
public MonitoredData[] newArray(int size){
return new MonitoredData[size];
}
};
private static DateFormat _sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
public MonitoredData(String name, Object value, Date endTime){
this(name, value, new ParcelableDate(endTime), new ParcelableDate(endTime));
}
public MonitoredData(String name, Object value, ParcelableDate endTime){
this(name, value, endTime, endTime);
}
public MonitoredData(String name, Object value, Date startTime, Date endTime){
this(name, value, new ParcelableDate(startTime), new ParcelableDate(endTime));
}
public MonitoredData(String name, Object value, Date startTime, ParcelableDate endTime){
this(name, value, new ParcelableDate(startTime), endTime);
}
public MonitoredData(String name, Object value, ParcelableDate startTime,
ParcelableDate endTime){
_name = name;
_startTime = startTime;
_endTime = endTime;
_value = value;
_extras = null;
}
public void setExtras(Bundle extras){
_extras = extras;
}
public Map<String, Object> toMap(){
TreeMap<String, Object> map = new TreeMap<String, Object>();
map.put("Name", _name);
map.put("StartTime", _startTime);
map.put("EndTime", _endTime);
map.put("Value", _value);
return map;
}
public String conciseToString(){
String extrasToString = (_extras != null && !_extras.isEmpty()) ? " - "
+ _extras.toString() : "";
return "{" + getName() + " = " + getValue() + "}" + extrasToString;
}
public int describeContents(){
return (_extras == null || _extras.isEmpty()) ? DEFAULT : HAS_EXTRAS;
}
public ParcelableDate getEndTime(){
return _endTime;
}
public String getName(){
return _name;
}
public ParcelableDate getStartTime(){
return _startTime;
}
public Object getValue(){
return _value;
}
public Bundle getExtras(){
return _extras;
}
public String toString(){
StringBuilder sb = new StringBuilder("{");
sb.append("Name = " + getName() + ", ");
sb.append("Value = " + getValue() + ", ");
sb.append("StartTime = " + _sdf.format(getStartTime()) + ", ");
sb.append("EndTime = " + _sdf.format(getEndTime()));
sb.append("}");
return sb.toString();
}
public void writeToParcel(Parcel dest, int flags){
dest.writeString(getName());
dest.writeValue(getValue());
dest.writeParcelable(getStartTime(), 0);
dest.writeParcelable(getEndTime(), 0);
dest.writeBundle(_extras);
}
public void clear(){
throw new UnsupportedOperationException();
}
public boolean containsKey(Object key){
throw new UnsupportedOperationException();
}
public boolean containsValue(Object value){
throw new UnsupportedOperationException();
}
public Set entrySet(){
return Collections.unmodifiableSet(toMap().entrySet());
}
public Object get(Object key){
throw new UnsupportedOperationException();
}
public boolean isEmpty(){
throw new UnsupportedOperationException();
}
public Set keySet(){
throw new UnsupportedOperationException();
}
public Object put(Object key, Object value){
throw new UnsupportedOperationException();
}
public void putAll(Map arg0){
throw new UnsupportedOperationException();
}
public Object remove(Object key){
throw new UnsupportedOperationException();
}
public int size(){
throw new UnsupportedOperationException();
}
public Collection values(){
throw new UnsupportedOperationException();
}
/**
* Returns the value of the monitored data as a Double.
* Null is returned if the value is null or is can not be converted to double.
*
* #return The value as double if possible, null otherwise
*/
public Double mdToDouble(){
Double sample;
Object val = getValue();
if (val instanceof Double){
sample = ((Double)val).doubleValue();
}else if (val instanceof Long){
sample = ((Long)val).doubleValue();
}else if (val instanceof Integer){
sample = ((Integer)val).doubleValue();
}else{
sample = null;
}
return sample;
}
}
Utils.java
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Formatter;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import android.content.Context;
import android.content.res.Resources;
import android.os.Environment;
import android.widget.Toast;
public class Utils{
public static byte[] append(byte[] first, byte[] second){
byte[] bytes;
bytes = new byte[first.length + second.length];
System.arraycopy(first, 0, bytes, 0, first.length);
System.arraycopy(second, 0, bytes, first.length, second.length);
return bytes;
}
public static int bytesToInt(byte[] bytes){
return (bytes[3] & 0xFF) | ((bytes[2] & 0xFF) << 8) | ((bytes[1] & 0xFF) << 16)
| ((bytes[0] & 0xFF) << 24);
}
public static int littleEndianBytesToInt(byte[] bytes){
return (bytes[0] & 0xFF) | ((bytes[1] & 0xFF) << 8) | ((bytes[2] & 0xFF) << 16)
| ((bytes[3] & 0xFF) << 24);
}
public static long littleEndianBytesToUShort(byte[] arr){
return (arr[1] << 8) | arr[0];
}
public static void displayShortAlert(Context context, String message){
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}
public static XmlPullParser getXPP(Context context, int resourceId, boolean isBinary){
XmlPullParser xpp;
Resources resources = context.getResources();
if (isBinary){
return resources.getXml(resourceId);
}else{
try{
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
xpp = factory.newPullParser();
xpp.setInput(resources.openRawResource(resourceId), null);
}catch(XmlPullParserException e){
xpp = null;
}
return xpp;
}
}
public static byte[] intToBytes(int i){
byte[] bytes = new byte[]{(byte)((i >> 24) & 0xff), (byte)((i >> 16) & 0xff),
(byte)((i >> 8) & 0xff), (byte)((i) & 0xff)};
return bytes;
}
/*
* debugging
*/
public static String printByteArray(byte[] bytes, int len){
StringBuilder sb = new StringBuilder();
sb.append("msg len: " + len + " :");
Formatter f = new Formatter(sb);
for (int i = 0; i < len; i++){
f.format("%2x", bytes[i]);
}
sb.append("\n");
return sb.toString();
}
public static List<Integer> getPids(String fileName){
String line;
int pidIndex = -1;
try{
Process p = Runtime.getRuntime().exec("ps " + fileName);
p.waitFor();
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()), 256);
if ((line = br.readLine()) == null){
throw new IllegalStateException("Unable to read ps output");
}
String[] tokens = line.split(" +");
for (int i = 0; i < tokens.length; ++i){
if (tokens[i].equalsIgnoreCase("pid")){
pidIndex = i;
}
}
if (pidIndex < 0){
throw new IllegalStateException("Unable to locate pid field in ps output");
}
List<Integer> pids = new ArrayList<Integer>();
while ((line = br.readLine()) != null){
tokens = line.split(" +");
assert tokens.length < 9;
try{
pids.add(Integer.parseInt(tokens[pidIndex]));
}catch(NumberFormatException e){
throw new IllegalStateException("Pid is not an integer");
}
}
br.close();
return pids;
}catch(Exception e){
throw new IllegalStateException("Unable to read running process through ps: "
+ e.getMessage(), e);
}
}
public static void killProcesses(List<Integer> pids){
for (Integer pid : pids){
android.os.Process.killProcess(pid);
}
}
public static void killProcesses(String processName){
killProcesses(getPids(processName));
}
public static void suKillProcesses(List<Integer> pids){
StringBuilder cmd = new StringBuilder("kill");
for (Integer pid : pids){
cmd.append(" ").append(pid);
}
try{
Runtime.getRuntime().exec(new String[]{"su", "-c", cmd.toString()});
}catch(IOException e){
e.printStackTrace();
}
}
public static void suKillProcess(int pid){
try{
Runtime.getRuntime().exec(new String[]{"su", "-c", "kill " + pid});
}catch(IOException e){
e.printStackTrace();
}
}
public static void suKillProcesses(String processName){
suKillProcesses(getPids(processName));
}
public static double truncateDouble(double d){
long l = Math.round(d * 100);
return l / 100.0;
}
public static double calcMovingAvg(double oldVal, double newVal, double newValWeight){
return (oldVal * (1.0 - newValWeight)) + (newValWeight * newVal);
}
public static double calcAvg(double oldAvg, int count, double newVal){
return (oldAvg * count + newVal) / (count + 1);
}
public static void writeLogToFile(Context context, boolean onSdcard, String prefix, int timeWindowInSeconds) throws Exception{
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH-mm-ss");
final DateFormat logDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
final long currentTime = System.currentTimeMillis();
final long startTime = currentTime - timeWindowInSeconds * 1000;
final String currentYear = Calendar.getInstance().get(Calendar.YEAR) + "-";
final String logFileName = prefix + sdf.format(new Date(currentTime)) + ".log";
BufferedReader logcatIn;
Process logcat;
OutputStream logFile;
try{
logcat = Runtime.getRuntime().exec("logcat -v time -d *:d");
logcatIn = new BufferedReader(new InputStreamReader(logcat
.getInputStream()), 1024);
}catch(IOException e){
throw new Exception("Unable to launch logcat: " + e.getMessage(), e);
}
try{
if (onSdcard){
logFile = new FileOutputStream(new File(Environment.getExternalStorageDirectory(), logFileName));
}else{
logFile = context.openFileOutput(logFileName, 0);
}
}catch(IOException e){
throw new Exception("Unable to create log file: " + e.getMessage(), e);
}
PrintWriter pw = new PrintWriter(logFile, false);
String line;
long logLineTime;
while ((line = logcatIn.readLine()) != null){
logLineTime = logDF.parse(currentYear + line.substring(0, line.indexOf(".") + 4)).getTime();
if (logLineTime >= startTime){
pw.println(line);
}
}
pw.flush();
pw.close();
logcatIn.close();
logcat.destroy();
}
}
FeatureExtractor.java
import java.util.List;
/**
* A class capable of extracting one or more features. It MUST have a public constructor
* with the following parameters in this order:
* <ul>
* <li>Context context</li>
* <li>Collection<FeatureInfo> featureInfos</li>
* <li>Long timeStamp</li>
* </ul>
*
*/
public interface FeatureExtractor{
/**
* Invoked during a data collection. It is up to the extractor to add the data
* relevant to it's monitored features to the monitoredData list.
*
* #param monitoredData The overall collected data (from all extractors) so far
* #param endTime The time of the current data collection
*/
public void collectData(List<MonitoredData> monitoredData, ParcelableDate endTime);
/**
* Invoked when the feature extractor is no longer needed. This is the place to
* release any resources, unregister any listeners, close any threads, etc.
*/
public void close();
}
FeatureExtractorInitException.java
public class FeatureExtractorInitException extends RuntimeException{
private static final long serialVersionUID = 1L;
public FeatureExtractorInitException(String message){
super(message);
}
public FeatureExtractorInitException(String message, Throwable t){
super(message, t);
}
public FeatureExtractorInitException(Throwable t){
super(t);
}
}
For example if you had an imageView one way of fetching coordinates is...
imageView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
int[] values = new int[2];
view.getLocationOnScreen(values);
Log.d("X & Y",values[0]+" "+values[1]);
}
});
Check out these ST threads:
How to get imageView inside onTouchEvent(MotionEvent event) in android
Android: How do I get the x y coordinates within an image / ImageView?
OnClickListener - x,y location of event?
Find layout with x,y coordinate
If you use reuf codes,you will need to use ParcelableData.java.I add ParcelableData class that found here and hope to save your time:
package dev.drsoran.moloko.service.parcel;
import java.util.Date;
import android.os.Parcel;
import android.os.Parcelable;
public class ParcelableDate implements Parcelable
{
public static final Parcelable.Creator< ParcelableDate > CREATOR = new Parcelable.Creator< ParcelableDate >()
{
public ParcelableDate createFromParcel( Parcel source )
{
return new ParcelableDate( source );
}
public ParcelableDate[] newArray( int size )
{
return new ParcelableDate[ size ];
}
};
private final Date date;
public ParcelableDate( final Date date )
{
this.date = date;
}
public ParcelableDate( long millis )
{
this.date = new Date( millis );
}
public ParcelableDate( Parcel source )
{
date = new Date( source.readLong() );
}
public Date getDate()
{
return date;
}
#Override
public String toString()
{
return date.toString();
}
public int describeContents()
{
return 0;
}
public void writeToParcel( Parcel dest, int flags )
{
dest.writeLong( date.getTime() );
}
}