Problem when creating an object and setting its variables - android

I'm making an app which for now, parses an url and takes some info from it. I want to use this values to create objects, put them into an arraylist, and show them on screen with a ListView layout.
Problem comes when i want to assign drawables values from the object. I want, depending on its values, assign a drawable or another. Here is the code:
Retransmision retransmision = new Retransmision();
retransmision.setIdioma(idioma);
retransmision.setTipo(tipo);
retransmision.setCalidad(calidad);
retransmision.setLink(link);
retransmision.setImagenLogo(tipo);
retransmision.setImagenCalidad(calidad);
retransmisionesDescargadas.add(retransmision);
I just create the object and assign some values with its methods. And heres the method wich is throwing nullPointerException:
public void setImagenCalidad(int calidad) {
if (calidad == 0) {
imagenCalidad = context.getResources().getDrawable(R.drawable.desconocida);
} else if(calidad <= 250) {
imagenCalidad = context.getResources().getDrawable(R.drawable.baja);
} else if(calidad <= 500) {
imagenCalidad = context.getResources().getDrawable(R.drawable.media);
} else if(calidad <= 750) {
imagenCalidad = context.getResources().getDrawable(R.drawable.alta);
} else if(calidad <= 1000) {
imagenCalidad = context.getResources().getDrawable(R.drawable.muy_alta);
} else {
imagenCalidad = context.getResources().getDrawable(R.drawable.excelente);
}
}
Weird since i use a similar code for method setImagenLogo that seems to work well. And only difference is one gets a String parameter. And the other an int.
Ps: If it might help, this is the constructor of the retransmision object and its variables:
Context context;
private String idioma;
private String tipo;
private int calidad;
private String link;
private Drawable imagenLogo;
private Drawable imagenIdioma;
private Drawable imagenCalidad;
public Retransmision() {
idioma = "";
tipo = "";
calidad = 0;
link = "";
imagenLogo = null;
imagenIdioma = null;
imagenCalidad = null;
}

The only thing that could be null there is the context... and I see you didn't initialize it in your constructor. Maybe this is what you want:
public Retransmision(Context ctx) {
idioma = "";
tipo = "";
calidad = 0;
link = "";
imagenLogo = null;
imagenIdioma = null;
imagenCalidad = null;
context = ctx;
}

Related

Open/Close SQL Database on the same thread

I'm developing a recipe book and I'm implementing this method to insert my Recipe in the Database. In the for cycle I get the ingredient's name and quantity from multiples EditText, saving each of them in an Ingredient.class instance (newIngredient). Then I insert the instance into the DB and add it to an ArrayList. The followings "if conditions" are for the title, time and other Recipe's attributes. Finally, I also insert Recipe and Tag instances in the relatives DB's tables and I close DB.
public void saveRecipe() {
dbHelper = new DatabaseHelper(context);
// creating new recipe from user input
Ingredient newIngredient;
String title, childIngredient, instruction, tag;
int target, time, childQuantity, calories;
int countIngredients = parentIngredientLayout.getChildCount();
int countTags = chipGroup.getChildCount();
ArrayList<Ingredient> ingredients = null;
ArrayList<Tag> tags = null;
View childViewIng = null;
EditText childTextViewI = null;
EditText childTextViewQ = null;
// ingredients fields settings
for (int d=0; d<countIngredients; d++) {
childViewIng = parentIngredientLayout.getChildAt(d);
childTextViewI = childViewIng.findViewById(R.id.ingredientsField);
childTextViewQ = childViewIng.findViewById(R.id.quantityField);
childIngredient = childTextViewI.getText().toString();
childQuantity = Integer.parseInt(childTextViewQ.getText().toString());
newIngredient = new Ingredient(childIngredient, childQuantity);
dbHelper.insertIngredient(newIngredient);
ingredients.add(newIngredient);
}
//recipe fields settings
if (photoPath1 == null)
photoPath1 = "";
if (photoPath2 == null)
photoPath2 = "";
if (photoPath3 == null)
photoPath3 = "";
if (titleText.getText().toString().isEmpty()) {
title = "";
} else {
title = titleText.getText().toString();
}
if (targetNumber.getText().toString().isEmpty()) {
target = 0;
} else {
target = Integer.parseInt(targetNumber.getText().toString());
}
if (timeNumber.getText().toString().isEmpty()) {
time = 0;
} else {
time = Integer.parseInt(timeNumber.getText().toString());
}
if (instructionText.getText().toString().isEmpty()) {
instruction = "";
} else {
instruction = instructionText.getText().toString();
}
if (caloriesNumber.getText().toString().isEmpty()) {
calories = 0;
} else {
calories = Integer.parseInt(caloriesNumber.getText().toString());
}
if (tagName.getText().toString().isEmpty()) {
tag = "";
} else {
tag = tagName.getText().toString();
}
Recipe newRecipe = new Recipe(title, photoPath1, photoPath2, photoPath3, instruction, target, time, calories, ingredients);
Tag newTag = new Tag(tag);
dbHelper.insertRecipe(newRecipe);
dbHelper.insertTag(newTag);
dbHelper.close(); }
I found out by debugging that in this case is inserted only the first ingredient. I tried to move the FOR until the end of code, but in that case, are inserted both recipe and tag and always only the first ingredient. I think the problem is relative to the opening/closing of the DB. Can somebody help me?
Ingredient constructor:
public Ingredient(String ingredient_name, int quantity) {
this.ingredient_name = ingredient_name;
this.quantity = quantity;
}
dbHelper.insertIngredient(newIngredient) method:
public boolean insertIngredient(Ingredient ingredient) {
db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(INGREDIENT_NAME, ingredient.getIngredient_name());
contentValues.put(QUANTITY, ingredient.getQuantity());
contentValues.put(KEY_CREATED_AT, time.getTime().toString());
long result = db.insert(TBL_INGREDIENTS, null, contentValues);
//db.close();
Log.e(TAG, "Ingredient inserted!");
if (result == -1) {
return false;
} else {
return true;
}
}
Ok, thanks to your comment we got the problem :)
You are calling .add(newIngredient) on a list that you initialized with ArrayList<Ingredient> ingredients = null;
Change it to
ArrayList<Ingredient> ingredients = new ArrayList<Ingredient>();
and it will work :)
Good luck!

Why does WorkManager doesn't work correctly with OneTimeWorkRequest?

I have problem with WorkManager from Android Architecture Components.
version of workmanager is alpha-06
Maybe I didn't understand this process, but I expect that OneTimeWorkRequest will work only once, and it work correctly if time for this work not very long (not more than 7+- minutes), but if more, workmanager start the same work again (with same UUID) and not stop first work, and workmanager execute two works in parallel
Here I start work
Data workDownloadBookData = new Data.Builder().putInt(BookDownloadWork.BOOK_ID_KEY, id).putString(BookDownloadWork.COUNTRY_CODE_KEY, countryCode).build();
OneTimeWorkRequest request = new OneTimeWorkRequest.Builder(BookDownloadWork.class)
.setInputData(workDownloadBookData)
.setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 2L, TimeUnit.SECONDS)
.build();
WorkManager workManager = WorkManager.getInstance();
if (workManager != null) {
workManager.beginUniqueWork(countryCode + id,ExistingWorkPolicy.KEEP, request).enqueue();
}
It is my work
public class BookDownloadWork extends Worker {
private static final String TAG = BookDownloadWork.class.getSimpleName();
public static final String COUNTRY_CODE_KEY = "COUNTRY_CODE_KEY";
public static final String LAST_UPDATE_KEY = "LAST_UPDATE_KEY";
public static final String BOOK_ID_KEY = "BOOK_ID_KEY";
public static final String PHOTO_URI_KEY = "PHOTO_URI_KEY";
private BookRepository bookRepository;
private BookLoadProgressDao bookLoadProgressDao;
private BookLoadWorkerDao bookLoadWorkerDao;
private NotificationController notificationController;
#NonNull
#Override
public Result doWork() {
bookRepository = App.appComponent.getBookRepository();
bookLoadProgressDao = App.appComponent.getBookLoadProgressDao();
bookLoadWorkerDao = App.appComponent.getBookLoadWorkerDao();
notificationController = App.appComponent.getNotificationController();
String countryCode = getInputData().getString(COUNTRY_CODE_KEY);
// String countryCode = getInputData().getString(COUNTRY_CODE_KEY, "");
int serverBookId = getInputData().getInt(BOOK_ID_KEY, 0);
if (!TextUtils.isEmpty(countryCode) && serverBookId != 0) {
String localBookId = serverBookId + countryCode;
BookLoadProgress bookLoadProgress = new BookLoadProgress();
bookLoadProgress.setId(localBookId);
try {
LocalBookDetail localBookDetail = bookRepository.selectLocalBookDetailSynch(serverBookId, countryCode);
bookRepository.saveBookToLocalStorageSynch(serverBookId, localBookDetail.getLastUpdate(), countryCode, null);
BookLoadWorker bookLoadWorker = new BookLoadWorker();
bookLoadWorker.setBookId(localBookId);
bookLoadWorker.setWorkId(getId());
bookLoadWorkerDao.insertBookLoadWorker(bookLoadWorker);
RemoteBookChapter[] remoteBookChapters = bookRepository.loadBookFromServerSynch(countryCode, serverBookId);
if (remoteBookChapters == null) return Result.FAILURE;
//count max progress
for (int i = 0; i < remoteBookChapters.length; i++) {
RemoteBookChapter remoteBookChapter = remoteBookChapters[i];
if (remoteBookChapter.getType().equals("image")) { bookLoadProgress.setMaxProgress(bookLoadProgress.getMaxProgress() + 1);
for (int j = 0; j < remoteBookChapter.getContent().length; j++) {
RemoteBookContent remoteBookContent = remoteBookChapter.getContent()[j];
if (remoteBookContent.getType().equals("image")) {
bookLoadProgress.setMaxProgress(bookLoadProgress.getMaxProgress() + 1);
}
}
}
}
bookLoadProgressDao.insertBookLoadProgress(bookLoadProgress);
for (int i = 0; i < remoteBookChapters.length; i++) {
RemoteBookChapter remoteBookChapter = remoteBookChapters[i];
if (remoteBookChapter.getType().equals("image")) { remoteBookChapter.setUrl(bookRepository.loadAndSaveImageSynch(remoteBookChapter.getUrl())); bookLoadProgress.setCurrentProgress(bookLoadProgress.getCurrentProgress() + 1);
bookLoadProgressDao.insertBookLoadProgress(bookLoadProgress);
for (int j = 0; j < remoteBookChapter.getContent().length; j++) {
RemoteBookContent remoteBookContent = remoteBookChapter.getContent()[j];
if (remoteBookContent.getType().equals("image")) {
remoteBookContent.setUrl(bookRepository.loadAndSaveImageSynch(remoteBookContent.getUrl())); bookLoadProgress.setCurrentProgress(bookLoadProgress.getCurrentProgress() + 1); bookLoadProgressDao.insertBookLoadProgress(bookLoadProgress);
}
}
}
}
bookRepository.saveBookToLocalStorageSynch(serverBookId, localBookDetail.getLastUpdate(), countryCode, remoteBookChapters);
bookLoadProgressDao.deleteBookLoadProgress(bookLoadProgress.getId());
notificationController.sendNotificationAboutBookDownloadFinished(serverBookId, countryCode);
return Result.SUCCESS;
} catch (Exception e) {
Log.e(TAG, "doWork: ",e );
// bookLoadProgressDao.deleteBookLoadProgress(bookLoadProgress.getId());
bookRepository.deleteBookSycnh(localBookId);
return Result.FAILURE;
}
} else {
return Result.FAILURE;
}
}
}
but I need only one work for download these files and save it to database
I think you are mixing a few concepts. OneTimeWorkRequest's are not unique by themselves. If you only want one instance of the continuation run, then you should be using unique work. Look athe documentation for beginUniqueWork.

txtt.setText(getString(R.string.("i" + j++)));

What's wrong with this code? I want to use id automatically. I think after R.string there is a mistake. What can ı do
Do it like this
public static int getStringIDFromName(String stringName)
{
int stringID= 0;
if(stringName == null
|| stringName.equalsIgnoreCase(""))
{
return 0;
}
try
{
#SuppressWarnings("rawtypes")
Class res = R.string.class;
Field field = res.getField(stringName);
stringID = field.getInt(null);
}
catch(Exception e)
{
// Error
}
return stringID;
}
Set your value like this
int stringVal = getStringIDFromName("i" + j++);
if( stringVal != 0)
txtt.setText(getResource().getString(stringVal));
This would work only if you are doing everything else right.
// initialization for TextView
TextView txtt = (TextView) findViewById(R.id.myTextViewId);
// set the text
txtt.setText(getResources().getString(R.string.mystring));

Android read contacts(and details) seems very slow

I use the following code to read each contacts along with their details.
private static final String[] PROJECTION =
{
Data._ID,
Data.MIMETYPE,
Data.DATA1,
Data.DATA2,
Data.DATA3,
Data.DATA4,
Data.DATA5,
Data.DATA6,
Data.DATA7,
Data.DATA8,
Data.DATA9,
Data.DATA10,
Data.DATA11,
Data.DATA12,
Data.DATA13,
Data.DATA14,
Data.DATA15
};
private static final String SELECTION = Data.LOOKUP_KEY + " = ?";
private String[] mSelectionArgs = { "" };
private static final String SORT_ORDER = Data.MIMETYPE;
private static final int MIME_TYPE_INDEX = 1;
private static final int DISPLAY_NAME_INDEX = 3;//data2
private static final int GIVEN_NAME_INDEX = 3;//data2
private static final int FAMILY_NAME_INDEX = 4;//data3
private static final int MIDDLE_NAME_INDEX = 6;//data5
private static final int ORGANIZATION_INDEX = 2;//data2
private static final int PHONE_TYPE_INDEX = 3;//data2
private static final int PHONE_LABEL_INDEX = 4;//data3
private static final int PHONE_NUMBER_INDEX = 2;//data1
private static final int EMAIL_TYPE_INDEX = 3;//data2
private static final int EMAIL_LABEL_INDEX = 4;//data1
private static final int EMAIL_INDEX = 2;//data1
private byte[] createJsonData(ArrayList<String> selected) throws JSONException, IOException{
Log.d("SynchContactActivity", "Time 1: " + java.text.DateFormat.getDateTimeInstance().format(Calendar.getInstance().getTime()));
int current = 0;
final String messagePrep = getResources().getString(R.string.progress_message_prep);
final String messageCompress = getResources().getString(R.string.progress_message_compress);
final String messageUpload = getResources().getString(R.string.progress_message_upload);
if(selected == null ){
selected = getContacts();
}
final int count = selected.size();
mHandler.post(new Runnable() {
#Override
public void run() {
if(mProgressDialog != null){
mProgressDialog.setMax(count);
mProgressDialog.setMessage(messagePrep);
}
}
});
updateProgress(current);
JSONObject root = new JSONObject();
JSONArray contactsArray = new JSONArray();
JSONObject contactJSON, phoneJSON, emailJSON;
JSONArray phonesArray,emailsArray;
String name, lastName, middleName,organization;
for (String key : selected) {
contactJSON = new JSONObject();
phonesArray = new JSONArray();
emailsArray = new JSONArray();
mSelectionArgs[0] = key;
//Cursor details = managedQuery(Data.CONTENT_URI, PROJECTION, SELECTION, mSelectionArgs, SORT_ORDER);
Cursor details = getApplicationContext().getContentResolver().query(Data.CONTENT_URI, PROJECTION, SELECTION, mSelectionArgs, SORT_ORDER);
//initialize null variables
name = null;
lastName = null;
middleName = null;
organization = null;
while(details.moveToNext()){
String mimeType = details.getString(MIME_TYPE_INDEX);
if(mimeType.equals(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)){
name = details.getString(GIVEN_NAME_INDEX);
lastName = details.getString(FAMILY_NAME_INDEX);
middleName = details.getString(MIDDLE_NAME_INDEX);
}
else if(mimeType.equals(ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE)){
organization = details.getString(ORGANIZATION_INDEX);
}
else if(mimeType.equals(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)){
phoneJSON = new JSONObject();
String phoneNumber = details.getString(PHONE_NUMBER_INDEX);
int type = details.getInt(PHONE_TYPE_INDEX);
String typeLabel = phoneTypeMap.get(String.valueOf(type));
if (typeLabel == null) {
typeLabel = details.getString(PHONE_LABEL_INDEX);
}
phoneJSON.put("ptype", typeLabel);
phoneJSON.put("number", phoneNumber);
phonesArray.put(phoneJSON);
}
else if(mimeType.equals(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)){
emailJSON = new JSONObject();
String email = details.getString(EMAIL_INDEX);
int type = details.getInt(EMAIL_TYPE_INDEX);
String typeLabel = emailTypeMap.get(String.valueOf(type));
if (typeLabel == null) {
typeLabel = details.getString(EMAIL_LABEL_INDEX);
}
emailJSON.put("etype", typeLabel);
emailJSON.put("address",email);
emailsArray.put(emailJSON);
}
}
contactJSON.put("firstname", name==null?"null":name);
contactJSON.put("middlename", middleName==null?"null":middleName);
contactJSON.put("lastname", lastName==null?"null":lastName);
contactJSON.put("organization", organization==null?"null":organization);
contactJSON.put("phones", phonesArray);
contactJSON.put("emails", emailsArray);
contactsArray.put(contactJSON);
details.close();
++current;
updateProgress(current);
}
root.put("contacts", contactsArray);
Log.d("SynchContactActivity", "Time 1: " + java.text.DateFormat.getDateTimeInstance().format(Calendar.getInstance().getTime()));
mHandler.post(new Runnable() {
#Override
public void run() {
if(mProgressDialog != null){
mProgressDialog.setMessage(messageCompress);
}
}
});
// to compress
String json_doc = root.toString();
byte[] compressed = compress(json_doc);
mHandler.post(new Runnable() {
#Override
public void run() {
if(mProgressDialog != null){
mProgressDialog.setMessage(messageUpload);
}
}
});
return compressed;
}
This code is too slow - that reads 3-4 contacts per second on average. Is this normal or can be optimized?
I think projection might be a good candidate to be optimized but I'm not sure.
Thanks in advance.
It's hard for me to tell exactly what you're trying to do, but it looks like you're trying to read data from the Contacts Provider and send it to a server using JSON. I suggest you look at the ContactsContract.RawContacts.Entity table, which contains all the data you're probably looking for without the mess of trying to figure out the MIME type of the DATA row you've just retrieved. You're certainly slowing down your app by getting the entire contents of the DATA row.
In addition, you should use a SyncAdapter to do this work. See Transferring Data Using Sync Adapters
Reading contacts can be made in 2-5 seconds. See the example app here
Source code attached

Updating values to Hash-table?

I have some problem in updating the values to hash-table,here is my problem i will explain it clearly.
1.I have getting the response from server,i am adding the values to layout,by using layout Layout-Inflater.
2.in our application we have streaming request.when the streaming request is turned on the values need to be updated regularly.
storing values in hash-tables
Hashtable<String, View> indicesHashtable = new Hashtable<String, View>();
For(Step 1)code i have written belowthe code.
private void addIndices(LinearLayout parent, final String key,final String value) {
LayoutInflater factory = LayoutInflater.from(mContext);
final View row = factory.inflate(R.layout.indices_values, null);
final TextView keyTextView = (TextView) row.findViewById(R.id.txtCompany);
final TextView valueTextView = (TextView) row.findViewById(R.id.txtIndex);
final Button iconImageView = (Button) row.findViewById(R.id.btnIcon);
row.setBackgroundResource(android.R.drawable.list_selector_background);
if (value.length() > 0) {
keyTextView.setText(Html.fromHtml("<b>"+indices.get(key)+"</b>"));
valueTextView.setText(Html.fromHtml(value));
if(quoteArrowIconId != -1)
iconImageView.setBackgroundResource(quoteArrowIconId);
else
iconImageView.setBackgroundDrawable(null);
}else{
keyTextView.setText(Html.fromHtml(key));
}
indicesHashtable.put(key, row);
parent.addView(row);
}
For(Step 2)i need help from you guys.
i have written code..that i have shown below.
private void handleResponseOfResponses(ResponseParser response) {
Hashtable responses = (Hashtable) response.getValue(Response_890.RESPONSES);
String[] symbols = new String[responses.size()];
int index = 0;
indicesHashtable.clear();
for(int i =indicesSymbols.length-1; i >= 0; i--){
Enumeration e = responses.keys();
while (e.hasMoreElements()) {
ResponseParser subResponse = (ResponseParser) responses.get(e.nextElement());
if (subResponse.getResponseCode() == ResponseCodes.QUOTES_RESPONSE) {
String[] quoteProperties = (String[]) subResponse.getValue(Response_312.QUOTES_KEY);
if(quoteProperties[0].equalsIgnoreCase(indicesSymbols[i])){
// symbolTable.put(quoteProperties[0].toUpperCase(), index);
symbols[index++] = quoteProperties[0];
String value = quoteValue(quoteProperties);
For displaying the values coming for response i have added (AddIndices)method
addIndices(linear_Indices, quoteProperties[0], value);
}
}
}
}
autoscroll();
indicesStreamerClient = new StreamerClient(indicesSymbols){
#Override
public void onStreamDataReceived(QuoteData quoteData) {
System.out.println("onStreamDataReceived () -> "+quoteData.getSymbol());
HERE I NEED TO ADDED ANOTHER METHOD FOR UPDATING THE VALUES..HOW I CAN WRITE THE CODE.
};
};
Streamer.getInstance(mContext).registerStramerClient(indicesStreamerClient);
}
Guys i am fresher as well as new to andriod.
Thanks in advance!!!!!!

Categories

Resources