getting realtime data from ubidots to android app - java

i am doing project on ecg monitoring android app so i need to get real time data from ubidots, i manage to get latest variable value when i run app but not the all new values which will be updated continuously.So, i need help to get real time data in my app as a result my app should get data when it is updated in ubidots variable .
here is my code for getting variable:
public class MainActivity extends Activity {
private TextView ecgLevel;
String variableValue;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ecgLevel = (TextView) findViewById(R.id.ecg);
ApiUbidots getApi = new ApiUbidots();
getApi.execute();
}
class ApiUbidots extends AsyncTask<Integer, Void, Value[]> {
private final String API_KEY = “";
private final String VARIABLE_ID = "”;
#Override
protected Value[] doInBackground(Integer... params) {
ApiClient apiClient = new ApiClient(API_KEY);
Variable ecgLevel = apiClient.getVariable(VARIABLE_ID);
Value[] variableValues = ecgLevel.getValues();
return variableValues;
}
#Override
protected void onPostExecute(Value[] variableValues) {
double varValue = variableValues[0].getValue();
variableValue = (String.valueOf(varValue));
ecgLevel.setText(variableValue);
}
}
}```

Use Retrofit for hit the API after you get latest variable

Related

Losing data when sending between two classes

My app doesn't display anything when passing data from one class to another. I located through with the debugger that my ArrayList doesn't get the right value from the class.
I'm sending data with the following function:
public class Adaugare extends AppCompatActivity {
private ListView myListView;
private NumeAdapter numeAdapter;
String inume;
int ivarsta;
Intent intent = new Intent();
private ArrayList persoanaArrayList = new ArrayList<>();
public ArrayList getPersoanaArrayList() {
return persoanaArrayList;
}
public int getPersoanaArrayListsize() {
return persoanaArrayList.size();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_adaugare);
myListView = (ListView) findViewById(R.id.persoana_list);
Button btn_fin = (Button) findViewById(R.id.btn_fin);
btn_fin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
EditText nume_edit_text = (EditText) findViewById(R.id.ins_nume);
EditText varsta_edit_text = (EditText) findViewById(R.id.ins_var);
ivarsta = Integer.parseInt(varsta_edit_text.getText().toString());
inume = nume_edit_text.getText().toString();
persoanaArrayList.add(new Persoana(inume, ivarsta));
}
});
}
}
And recieving it with:
public class Afisare extends AppCompatActivity {
ListView myListView;
NumeAdapter numeAdapter;
Adaugare ad = new Adaugare();
int cate;
int i;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_afisare);
myListView = (ListView) findViewById(R.id.persoana_list);
ArrayList<Persoana> persoanaArrayList = new ArrayList<Persoana>(ad.getPersoanaArrayList());
numeAdapter = new NumeAdapter(this, persoanaArrayList);
myListView.setAdapter(numeAdapter);
}
The class Persoana is:
public class Persoana {
private String nume;
private int varsta;
Persoana(String inume, int ivar) {
this.nume = inume;
this.varsta = ivar;
}
public String getNume() {
return nume;
}
public int getVarsta() {
return varsta;
}
public void setNume(String nume) {
this.nume = nume;
}
public void setVarsta(int varsta) {
this.varsta = varsta;
}
}
Persoana is the main class, everything is saved in it. ad is an object of Adaugare, Adaugare being the class from which I've taken the code for getPersoanaArrayList. At debugging some values appeared at ad, namely Adaugare #4556, and persoanaArrayList remains null.
I need the persoanaArrayList so that i can initialize my Adapter and listView. Everything else in the code seems fine from step by step testing with debugger.
Your problem is with the following line in the Afisare class:
Adaugare ad = new Adaugare();
You can't simply new one activity from another activity and expect to access a shared list between them. To share instance data between java objects you need a reference to the other object. Creating a new instance will create a new empty list. That's why you are "losing" data. A quick fix would be to make the list static so it can be accessed from any instance.
But since you're dealing with Android, the right way to share data between activities is by using intent extras. The first activity starts the second activity via an intent. The first activity places the desired data in the intent as extras. The second activity uses getIntent() and the various methods on Intent to access the extras.
One last tip, in Android, you never use the new operator with Activities. Activities are created by the system to service an intent. If you find yourself using the new operator, that's a sign that you're doing something wrong.

Fill an ArrayList with object from response.body

I'm using retrofit to get list of data from api. I want to save the data which I get in body.response to arrayList. I can do that and I get the items from new arrayList, but it seems that the new list are not saved. When I try to use it outside of method onResponse, I get an error
Unable to start activity... IndexOutOfBoundsException: Index 0, Size 0
The interface
public interface ServerApi {
#Headers("Accept: application/json")
#GET("cities")
Call<ArrayList<City>> getCities();
}
The activity
public class SomeActivity extends AppCompatActivity {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://url")
.addConverterFactory(GsonConverterFactory.create())
.build();
ServerApi serverApi = retrofit.create(ServerApi.class);
ArrayList<City> cityList = new ArrayList<City>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_parkings);
final TextView tv1 = findViewById(R.id.tv1);
final Call<ArrayList<City>> cities = serverApi.getCities();
cities.enqueue(new Callback<ArrayList<City>>() {
#Override
public void onResponse(Call<ArrayList<City>> call, Response<ArrayList<City>> response) {
for(int i=0; i<response.body().size(); i++){
City ct = new City(response.body().get(i).getId(), response.body().get(i).getName());
cityList.add(ct);
tv1.setText(cityList.get(i).getName());
}
}
#Override
public void onFailure(Call<ArrayList<City>> call, Throwable t) {
tv1.setText("failure " + t);
}
});
TextView c1 = findViewById(R.id.c1);
c1.setText(cityList.get(0).getName());
}
}
The string tv1.setText(cityList.get(i).getName()); inside the method onResponse works well. But when I write it out of the method, the aplication fall
As it can be seen you run your code in a background thread and a few lines below you try to update your textview on the UI thread.
The background operation will take some time, therefore, by the time you try to update the TextView the cityList is empty.
Consider reading a bit more here: Consuming apis with retrofit

Accessing methods from other class to Activity

I need to set the String value generated by from AsynTask's OnPostExecute() method to Another Activity's Textview for that I have used following two methods, but both methods fails.
Method 1: By using GetterSetter Class
I am fairly new to android. I am making an app in which i stuck to this particular problem. I am running asyncTask from BackgroundTask class and BackgroundTask is running from StringGenerator class. In this AsyncTask I am setting value of a string to the getterSetter class.
My String Generator class -->
public class StringGenerator {
...
new BackgroundTask(context).execute(sb.toString());
Intent intent = new Intent(context.getApplicationContext(),Answer.class);
context.startActivity(intent);
sb.setLength(0);
}
My BackgroundTask Class -->
class BackgroundTask extends AsyncTask<String, Void, String> {
Context context;
GetterSetter getterSetter;
...
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.d("Answer",s);
getterSetter = new GetterSetter();
getterSetter.setString(s);
}
}
My GetterSetter Class, here log prints correct string.So, the string is set here, I have verified it. -->
class GetterSetter{
private String string;
public String getString() {
return string;
}
public void setString(String string) {
this.string = string;
Log.d("S1",string);
Log.d("S2",this.string);
}
}
From this getterSetter class i want to access string and set it onto textview onto another Activity called Answer Activity.
My Answer Activity -->
public class Answer extends AppCompatActivity {
GetterSetter getterSetter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_answer);
getterSetter = new GetterSetter();
((TextView)findViewById(R.id.SetSteps)).setText(getterSetter.getString());
}
}
Problem with this method is -->
But the String value set on the textview is empty, so it prints
nothing. Also, i tried to log the string.
Method 2 : By using SharedPreferences,but it always gives me default value which is ""(Empty).
My StringGenerator Class -->
public class StringGenerator {
...
new BackgroundTask(context).execute(sb.toString());
Intent intent = new Intent(context.getApplicationContext(),Answer.class);
context.startActivity(intent);
sb.setLength(0);
}
My BackgroundTask Class -->
class BackgroundTask extends AsyncTask<String, Void, String> {
Context context;
SharedPreferences.Editor editor;
BackgroundTask(Context context) {
this.context = context;
editor = context.getSharedPreferences("SolutionString",context.MODE_PRIVATE).edit();
}
...
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.d("Answer", s);
editor.putString("Solution",s);
editor.apply();
}
}
My Answer Class -->
public class Answer extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_answer);
SharedPreferences sharedPreferences = getSharedPreferences("SolutionString", MODE_PRIVATE);
((TextView)findViewById(R.id.SetSteps)).setText(sharedPreferences.getString("Solution",""));
}
}
Problem with this method is -->
This method will set the correct output string only for first time, after that second time and onwards this method will print default value which is ""(Empty).I tries to debug this method via printing logs and in logs the string values are not empty, i got correct values in logs. So, I think in this method the problem is updation of sharedpreferences value. I have also researched about this on stackoverflow and tried following solution, but nothing works.
SharedPreferences return only default value
getPreferences always returns default value
and many more.
Can anyone tell me how can i access the string inside OnCreate Activity for first method?? or for second method I need to get the updated values for SharedPreferences.
I don't want to create another intent because, i am already running intent from String Generator class.
first of all new GetterSetter() will creates a new object... now lets see how the memory works...
class BackgroundTask extends AsyncTask<String, Void, String> {
Context context;
GetterSetter getterSetter;
...
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.d("Answer",s);
getterSetter = new GetterSetter(); // assume is stored at address 2000 in the memory
getterSetter.setString(s);
}
}
public class Answer extends AppCompatActivity {
GetterSetter getterSetter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_answer);
getterSetter = new GetterSetter();// assume stored at 2008 in the memory , hence the string private String string does not have any value...
((TextView)findViewById(R.id.SetSteps)).setText(getterSetter.getString());
}
}
Now here are the points :-
private String string; if you declare this as private String string = ""; the null pointer exception will not occur.
you should have single GetterSetter getterSetter; intialized getterSetter = new GetterSetter(); only once then the value will persist... if you have both the BackgroundTask and Answer in separate files Answer class wont be able to see BackgroundTask class GetterSetter...
Rather include BackgroundTask with the Activity class and call the textview.setText in onPostExecute...
public class Answer extends AppCompatActivity {
GetterSetter getterSetter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_answer);
getterSetter = new GetterSetter();
}
class BackgroundTask extends AsyncTask<String, Void, String> {
Context context;
...
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.d("Answer",s);
getterSetter.setString(s);
((TextView)findViewById(R.id.SetSteps)).setText(getterSetter.getString());
}
}
}
If you insist on using different files then BackgroundTask should be called first and
class BackgroundTask extends AsyncTask {
Context context;
public static GetterSetter getterSetter; // this will store the object in memory and the value will persist between classes...
...
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.d("Answer",s);
getterSetter = new GetterSetter();
getterSetter.setString(s);
// the activity Answer should start anywhere after this to get the correct value...
}
}
public class Answer extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_answer);
((TextView)findViewById(R.id.SetSteps)).setText(BackgroundTask.getterSetter.getString());
}
}
Hope it helps...
As you are creating a new object so the data in the existing object will be destroyed. So, the simplest way to do the above task is send the object with the intent. You can do this onPostExecute or on click of a button in your first Activity.
Intent intent = new Intent(MainActivity.this, Answer.class);
intent.putExtra("Object", getterSetter);
startActivity(intent);
and your object i.e. GetterSetter must implements Serializable as:
class GetterSetter implements Serializable
and in your another activity i.e. Answer.java you have to receive intent as:
Intent rcv = getIntent();
GetterSetter getterSetter = (GetterSetter) rcv.getSerializableExtra("Object");,
((TextView)findViewById(R.id.SetSteps)).setText(getterSetter.getString());

How to use Android's AsyncTask to get all of my data through JSoup, then send that information to another class?

I'm pretty new to developing in Android, but I understand that I cannot run Jsoup.connect(url).get() without some kind of thread as it is a synchronous call. I tried creating a class called Product that extends AsyncTask, and then having my original class called List call Product and then have the int displayed. However, regardless of the actual result, it always prints out 0.
I have tested my code before, so I know it works and that the issue must be something related to Android.
List Class:
public class List extends AppCompatActivity{
String itemURL;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item_list_view);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Bundle itemData = getIntent().getExtras();
if(itemData==null){
return;
}
//Gets URL
itemURL = itemData.getString("itemURL");
int listSize=new Product(itemURL).getListSize();
System.out.println(listSize);
}
}
Product class:
public class Product extends AsyncTask<Void,Void,Void>{
String url;
String title;
int listSize;
public Product(String url){
this.url = url;
}
protected Void doInBackground (Void... voids) {
//Create JSoup connection
try{
Document doc = Jsoup.connect("url").get();
//Gets title
String link = doc.select("h2#s-result-count").first().text();
System.out.println(link);
listSize=Integer.parseInt(link.substring(0,1));
System.out.println(listSize);
try{
int listSize= Integer.parseInt(link.substring(0,2));
System.out.println(listSize);
}catch(Exception e){}
}catch (Exception e){}
}
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
getListSize();
}
public int getListSize(){
return listSize;
}
}
All advice would be appreciated, thanks for your time and help!
You have to override
onPostExecute()
to make sure you are getting the variable after it is updated from the thread. Call your
getListSize()
from inside the overridden function.
Consider that calling
execute()
and then immediately calling
getListSize()
will happen line by line while the actual thread you have spun off will continue working. You're asking for a value that hasn't been updated.
Edit::
For clarification:
public class List extends AppCompatActivity{
String itemURL;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item_list_view);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Bundle itemData = getIntent().getExtras();
if(itemData==null){
return;
}
//Gets URL
itemURL = itemData.getString("itemURL");
int listSize=new Product(itemURL).getListSize(); // this doesn't do anything meaningful for you
System.out.println(listSize);
}
}
Note the comment I have added to
int listSize = new Product(itemURL).getListSize();
First,
doInBackground()
will never run until you call
execute()
You need to call
new Product(itemURL).execute();
Afterword, you have to provide some kind of callback to the Activity since you haven't nested the product class or initialized an anonymous instance of AsyncTask.
In your Product class you can set a variable
Context
public class Product extends AsyncTask<...> {
public Context context;
}
Then, in place of
int listSize = new Product(itemURL).getListSize();
put:
Product product = new Product();
product.context = this;
product.execute();
Then, in Product's
onPostExecute()
put:
if (context.getClass().equals(List.class)) {
((List) context).some_method_that_does_something_with_list_size()
}
Alternatively, you can add it to Product's constructor:
public Product(String url, Context context) {...}
Edit 2::
For further clarification
((List) context).some_method_that_does_something_with_list_size()
was meant to serve as a placemarker for any method available in your activity. It could easily be substituted with:
System.out.println(listSize);
Edit 3::
For further, further clarification:
In your Activity, ItemListView, define a method called
printListSize(int listSize) {
System.out.println("list size: " + listSize);
}
Then, in onPostExecute() call:
((ItemListView) context).printListSize(listSize);

Using onSaveInstanceState during orientation change?

First thing; I'm pretty much brand new to all this.
I've built a basic calculator but I lose the data when switching orientation (such as typing the number 9 then it going blank when switched to landscape).
I've already looked and found this:
How to use onSavedInstanceState example please
, but I'm unsure how to implement it into my code.
public class MainActivity extends AppCompatActivity {
private TextView _screen;
private String display = "";
private String currentOperator = "";
private String result = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
_screen = (TextView)findViewById(R.id.textView);
_screen.setText(display);
}
private void updateScreen(){
_screen.setText(display);
}
Can anyone help? An example using my piece would be perfect. Thanks

Categories