Android studio room database - not returning values in onRestart() method - android-studio

My app is a list of element names. Clicking one goes to another activity with more details, and an editText and button to change its name. When I go back to the list, I want it to have the new name if updated. My onCreate method has this code which populates it from the database perfectly (ignore the hardcoded size, its just simpler for debugging)
final String DATABASE_NAME = "element_db";
final AppDatabase appDatabase;
appDatabase = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, DATABASE_NAME).build();
ListView list = (ListView)findViewById(R.id.listView);
final String[] element = new String[3];
new Thread(new Runnable() {
#Override
public void run() {
List<Element> elements;
elements = appDatabase.elementDao().fetchElements(); // a dao query "select*from"
int size = elements.size();
for (int i = 0; i < size; i++){
element[i] = elements.get(i).getName();
}
}
}) .start();
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, R.layout.activity_list_view, R.id.textView, element);
list.setAdapter(arrayAdapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent i = new Intent(MainActivity.this, itemdetail.class);
i.putExtra("pos", position);
startActivity(i);
}
});
To achieve an updated list when returning to this screen, I copied the above code into the onRestart method, but now the database does not return anything. If I just set the array that goes into the adapter to {"a", "a", "a"} the list populates fine. Any ideas why the database works onCreate but not onRestart?

I think you can use ViewModel and livedata to observe any database change

Related

duplicate view upon data change?

My CardView duplicate elements upon data change, the vardView is within a tab, and the way i declared that tab fragment as following;
in the onCreateView, i declared all the necessary firebase links and value events listeners to retrieve the required data related to the elements displayed on the cards.
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
if(snapshot !=null){
for (DataSnapshot child: snapshot.getChildren()) {
Log.i("MyTag", child.getValue().toString());
imagesfeedsList.add(child.child("address").getValue(String.class));
authorfeedsList.add(child.child("author").getValue(String.class));
ratingfeedsList.add(child.child("rating").getValue(String.class));
locationfeedsList.add(child.child("location").getValue(String.class));
publicIDfeedsList.add(child.child("public_id").getValue(String.class));
}
Log.i("MyTag_imagesDirFinal", imagesfeedsList.toString());
mImages = imagesfeedsList.toArray(new String[imagesfeedsList.size()]);
author = authorfeedsList.toArray(new String[authorfeedsList.size()]);
ratingV = ratingfeedsList.toArray(new String[ratingfeedsList.size()]);
locationV = locationfeedsList.toArray(new String[locationfeedsList.size()]);
publicID = publicIDfeedsList.toArray(new String[publicIDfeedsList.size()]);
numbOfAdrs = Long.valueOf(imagesfeedsList.size());
LENGTH = Integer.valueOf(String.valueOf(numbOfAdrs));
}
right after the snippet the adapter setup;
ContentAdapter adapter = new ContentAdapter(recyclerView.getContext());
recyclerView.setAdapter(adapter);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
return recyclerView;
}
Then comes the view holder with a RecycleView, declaring the cardView elements. One of the elements is a ratingBar, and here where the ratingbar Listener is to submit the user rating on a specific picture.
after that the content adapter;
public static class ContentAdapter extends RecyclerView.Adapter<ViewHolder> {
// Set numbers of List in RecyclerView.
private Context mContext;
public ContentAdapter(Context context) {
this.mContext = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()), parent);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.authorName.setText(author[position]);
holder.ratingValue.setText(ratingV[position]);
holder.locationValue.setText(locationV[position]);
Picasso.with(mContext).load(mImages[position]).into(holder.picture);
#Override
public int getItemCount() {
return LENGTH;
}
}
My problem is whenever the user submits a rating or even when the data related to any of the elements on anycard changes, the view gets duplicated ( i mean by the view, the cards ), a repetition of the cards, with the new data chnages displayed ?
i a not sure what is in my above code structure causing this and how to fix this repetitions, i mean i need the cards to be updated with the new data but not duplicated?
All right, so the problem was that every time the data changes, in the onCreate the imagesFeedList, ratingFeedList, etc does not get rid of the old information stored in it from the initial build, so when the refresh happens triggered by onDataChange, the new information gets added to the previous information, which cause the view to repeat the cards, thus just at the beginning of onDataChange and before storing any information in the several feedLists, it must be cleared;
imagesfeedsList.clear();
authorfeedsList.clear();
ratingfeedsList.clear();
locationfeedsList.clear();
publicIDfeedsList.clear();
and by that i made sure the view does not repeat build up based on old information.

use thread inside buttonclick in android

I am receiving temperature values from a sensor through BLE and storing it in my db and passing the values as an array through intent to graph activity and diplaying a line graph. I am also posting the values to google app engine. i am doing this all within runOnUiThread() and hence my app crashes when there are too many values.Is it possible to pass values into the graph activity on a new thread? or any other better suggestions?
#Override
public void propertyChange(final PropertyChangeEvent event) {
final String property = event.getPropertyName();
runOnUiThread(new Runnable() {
public void run() {
try {
if (property.equals(PROPERTY_IR_TEMPERATURE)) {
double newIRValue = (Double) event.getNewValue();
// float newIRValue_1 = (Float) event.getNewValue();
TextView textView = (TextView) findViewById(R.id.ir_temperature);
String value = decimal.format(newIRValue);
String formattedText = value + DEGREE_SYM;
float value_chk = (float)(newIRValue);
String formattedText_1 = String.valueOf(value_chk);
String sensorid = test_1;
String sensortype = "temperature";
// write_data(sensorid,sensortype,value);
// Toast.makeText(getBaseContext(), "ARV sensid:"+sensorid+" senstype:"+sensortype, Toast.LENGTH_SHORT).show();
long timemilli = System.currentTimeMillis();
//Log.d("TIMMEE", String.valueOf(timemilli));
String time=String.valueOf(timemilli);
db = new DBHandler(getApplicationContext());
//db.deleteTempReadings();
// inserting data to temp table
Log.i("insert", "Inserting Records...");
);
Temperature(sensorid,formattedText_1));
//Toast.makeText(getBaseContext(), "SENSOR_ID:"+t.getSensorId()+"TEMPERATURE: "+t.getTemperature()+"TIME: "+t.getTimestamp(), Toast.LENGTH_LONG).show();
// reading data from db
Log.i("Reading", "Reading Records...");
List<Temperature> temp = db.getAllTempReadings();
int arraySize=temp.size();
double tempArray[]=new double[arraySize];
int timeArray[]=new int [arraySize];
//Log.d("ans", String.valueOf(temp.size()));
for (Temperature t : temp) {
String log="SENSOR ID: "+t.getSensorId()+"TEMPERATURE: "+t.getTemperature()+"TIME: "+t.getTimestamp();
Log.d("Record"+t, log);
}
// Reading values into the array!
for(int i=0;i<arraySize;i++){
tempArray[i]=Double.parseDouble(temp.get(i).getTemperature());
}
Button btn=(Button)findViewBy Id(R.id.btnGraph);
btn.setOnCLickListener(new View.onClickListener(){
public void onClick(View v){
Intent iIntent =new Intent(getApplicationContext(),GraphActivity.class);
tIntent.putExtra("tempArray",tempArray);
startActivity(tIntent);
}
});
// rest....posting to server code......
textView.setText(formattedText);
}
}
}
}
}
The temperature value you get from the sensor upto this you have to do stuff in one thread and after that you have to start three thread one for the inserting into the DB, the other one for the displaying the line graph and the last and the third one for the posting the data into the google app engine.
I think you are a bit confused here. The idea is to keep slow processing OUT of your UI thread. I suggest you do the writes to the DB and the App engine first in the 'current' (presumably less critical) thread and then when all is done simply update the graph display in the UI thread.
The only reason you need RunOnUiThread is to make changes to the views on the screen.

Need to set additional information in list view

I am trying to created a listview containing filenames. I want to set a additional information like file id with each list items, so when i click a filename, i have to get file id from it. please help me do this.
My sample code:
ListView listview = (ListView) findViewById(R.id.listview);
ArrayAdapter fileListAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, ['one','two','three']);
listview.setAdapter(fileListAdapter);
There are quite a few things involved here, so i'm providing you with an example of how you can achieve this (you can copy-paste and test):
public class MainActivity extends ListActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// First we simulate a pool of file names and IDs
String[] fileNames = {"fileName1", "fileName2", "fileName3"};
List<Integer> fileNameIds = new ArrayList<Integer>();
fileNameIds.add(1200);
fileNameIds.add(356);
fileNameIds.add(28);
// We call our custom Adapter
ArrayAdapter<String> adapter = new CustomAdapter(this, fileNames, fileNameIds);
// Finally we set the adapter to our list
setListAdapter(adapter);
}
// This is a custom adapter that uses ArrayAdapter for our purpose
// (as this is just an example you should consider using Base Adapter if you don't want
// to have a pool of filenames and a separate pool of ids)
class CustomAdapter extends ArrayAdapter<String>{
private final LayoutInflater INFLATER;
private final String[] FILE_NAMES;
private final List<Integer> FILE_NAME_IDS;
public CustomAdapter(Context context, String[] fileNames, List<Integer> fileNameIds) {
super(context, R.layout.custom_row, fileNames);
this.INFLATER = LayoutInflater.from(context);
this.FILE_NAMES = fileNames;
this.FILE_NAME_IDS = fileNameIds;
}
// HERE is where you can assign effectively an ID to your rows
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// this is an object that takes advantage of the holder pattern
// it retains the state of our rows in the list
FileNameHolder holder;
if(convertView == null){
convertView = INFLATER.inflate(R.layout.custom_row, null); // inflate your custom row
// now you need to assign specific identifier to the list row that the holder will retain
// for you, so you can always get this id by calling getTag from the View object on your
// item click listeners
holder = new FileNameHolder();
holder.fileName = (TextView) convertView; //since i only have a texView in layout i don't need to call findByView
convertView.setTag(holder); // relate the view to a custom FileNameHolder object that retains file name and its ID
} else{
holder = (FileNameHolder) convertView.getTag();
}
holder.fileName.setText(FILE_NAMES[position]); // PROVIDE the list with file name description
holder.idFileName = FILE_NAME_IDS.get(position); // ASSIGN file name ID
return convertView;
}
}
// This is an example of catching a row clicked and get the custom ID that you assigned,
// from here you can use that ID as you need
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// Here as you can see we obtain the object associated with the row that was clicked
FileNameHolder holder = (FileNameHolder) v.getTag();
// Here i provide a way you can test that you're always getting the correct file name and Id
Toast.makeText(this,
"File Name = " + holder.fileName.getText() +
", File ID = " + holder.idFileName,
Toast.LENGTH_SHORT).show();
}
// This is a class that takes advantage of the Holder Pattern and we use it to
// achieve what you need (remember this is just an example you should consider
// changing class and member access modifiers as you need)
class FileNameHolder{
Integer idFileName;
TextView fileName;
FileNameHolder() {
}
}
}
custom_row.xml is just a TextView (i took it from the simple_list_item_1 layout):
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:paddingStart="?android:attr/expandableListPreferredItemPaddingLeft"
android:textAppearance="?android:attr/textAppearanceMedium"
android:gravity="center_vertical"
/>
Hope it's useful... regards!!

LWUIT 1.5 How to capture tab click event, fetch content from server and show it in selected tab?

I am using LWUIT 1.5 tabs to show notifications. I have three Tabs and I fetch notifications from a php web service. I successfully fetched list of notifications for first Tab. But for next two Tabs I am failing to understand what code I should write to
Detect that second/third Tab is clicked. I know how to add commandListener to a Button. What commandListener is there for Tab selection?
How to refresh content of a Tab when new data is received from the server?
private void showNotificationList() {
try {
Form f = new Form("Notifications");
f.setScrollable(false);
f.setLayout(new BorderLayout());
final List list = new List(getNotifications()); //gets hashtables - notices
list.setRenderer(new GenericListCellRenderer(createGenericRendererContainer(), createGenericRendererContainer()));
list.setSmoothScrolling(true);
//System.out.println("adding list component to listview");
list.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
int i = list.getSelectedIndex();
noticeDetailsForm(notices[i]);
//Dialog. show( "title", notices[i].toString(), "ok", "exitt");
}
});
//Container c2 = new Container(new BoxLayout(BoxLayout.Y_AXIS));
//c2.addComponent(list);
Tabs tabs = new Tabs(Tabs.TOP);
tabs.addTab("Recent", list);
tabs.addTab("Urgent", new Label("urgent goes here"));
tabs.addTab("Favourites", new Label("favs goes here"));
//f.addComponent(tabs);
f.addComponent(BorderLayout.CENTER, tabs);
Command backComm = new Command("Back") {
public void actionPerformed(ActionEvent ev) {
Dashboard.dbInstance.setUpDashboard();
}
};
f.addCommand(backComm);
//System.out.println("showing lsit form");
f.show();
} catch (Exception ex) {
ex.printStackTrace();
}
}
private Container createGenericRendererContainer() throws IOException { //System.out.println("container called");
//System.out.println("container called");
Container c = new Container(new BorderLayout());
c.setUIID("ListRenderer");
Label xname = new Label("");
Label description = new Label();
Label focus = new Label("");
Container cnt = new Container(new BoxLayout(BoxLayout.Y_AXIS));
xname.setName("Name");
xname.getStyle().setBgTransparency(0);
xname.getStyle().setFont(Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_MEDIUM));
//description.setFocusable(true);
description.setName("Description");
cnt.addComponent(xname);
cnt.addComponent(description);
c.addComponent(BorderLayout.CENTER, cnt);
Button thumb = new Button(Image.createImage("/res/home-work.png"));
//Image img = Image.createImage("/res/home-work.png");
c.addComponent(BorderLayout.WEST, thumb);
return c;
}
private Hashtable[] getNotifications() {
int total = notices.length;
//System.out.println(total);
Hashtable[] data = new Hashtable[total];
//Hashtable[] data = new Hashtable[5];
/data[0] = new Hashtable();
data[0].put("Name", "Shai");
data[0].put("Surname", "Almog");
data[0].put("Selected", Boolean.TRUE);/
for (int i = 0; i < total; i++) {
data[i] = new Hashtable();
//System.out.println(notices[i].getName());
data[i].put("Name", notices[i].getName());
data[i].put("Description", notices[i].getDescription());
data[i].put("Id", Integer.toString(notices[i].getId()));
}
return data;
}
1)I had the same problem and I solved it by overriding Keyreleased of the Form not the Tab
and inside it I check for the component that is focused and if it is the Tab get "tab.selectedIndex" to detect in which Tab I am and load appropriate data .
Here is Sample code(this inside the my derived form that extends Form )
**
public void keyReleased(int keyCode) {
Component p=this.getFocused();
String str= p.getClass().getName();
if(str.toLowerCase().indexOf("radiobutton")!=-1){ // Radiobutton because when u
Here do tab specific work focus on the
tab it returns radiobutton.
lwuit understands tabs as list
of radiobuttons
}**
2)and about refreshing the data I did a solution and I don't Know if its right
I get the new data , create new List and remove the old one and attach the new one then
call Form.repaint();

How to make A Spinner access the other Spinner?

I have Three Spinners= spinState,spinCounty,& spinCity, i would like to select the State spinner then choose a State,then the second spinner would give me the list of Counties within that particular state,then select the County,then the third spinner would give me a list of the cities with in that particular county,such as: (State)Florida,(County)Dade,(City)Miami then after all 3 have been selected pass that information to the next Activity/Class. Can anyone help? here is my code
Spinner spinState,spinCounty,spinCity;
Button bNext;
protected void onCreate(Bundle)
{
//TODO Auto generated method stub
super.oncreate(Bundle)
setContentView(R.layout.info);
Spinner States = (Spinner) findViewById(R.id.spinState);
ArrayAdapter USstates = ArrayAdapter.createFromResource(this,
R.array.States, android.R.layout.simple_spinner_item);
USstates.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
States.setAdapter(USstates);
Spinner Counties = (Spinner) findViewById(R.id.spinCounty);
ArrayAdapter UScounties = ArrayAdapter.createFromResource(this,
R.array.Counties, android.R.layout.simple_spinner_item);
UScounties.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Counties.setAdapter(UScounties);
Spinner Cities = (Spinner) findViewById(R.id.spinCity);
ArrayAdapter UScities = ArrayAdapter.createFromResource(this,
R.array.Cities,android.R.layout.simple_spinner_item);
UScities.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Cities.setAdapter(UScities);
initialize();
bNext.setOnClickListener(this);
}
What code should i use and where?PS. whoever may answer could u use my exact variables so i won't be confused,Thanks in Advance.
countries.setOnItemSelectedListener(new OnItemSelectedListener() {
ArrayAdapter<String> stateadapter=null;
#Override
public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
switch (pos) {
case 0:
stateadapter = new ArrayAdapter<String>(
activityclass.this,
android.R.layout.simple_spinner_item, Arrays
.asList(getResources().getStringArray(
R.array.USAstate)));
states.setAdapter(stateadapter);
case 1:
stateadapter = new ArrayAdapter<String>(
activityclass.this,
android.R.layout.simple_spinner_item, Arrays
.asList(getResources().getStringArray(
R.array.Indiastate)));
states.setAdapter(stateadapter);
}
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
}
Select State
<string-array name="USAstate">
<item>california</item>
<item>texas</item>
<item>virgina</item>
<item>alaska</item>
</string-array>

Resources