Retrieving data and passing to textview - java

I'm trying to think of the logic behind how I should do this. The way I am doing it right now is sort of a hack, but it works. It's just too many API requests and unnecessary, so hopefully someone here can help me envision on how I should do this.
I'm using the parse.com SDK for android to retrieve data to display videos.
Here is my code for the video function
int count = 9;
private void getVideos()
{
ParseQuery<ParseObject> query = ParseQuery.getQuery("Videos");
query.whereEqualTo("videoid", count);
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> videoData, ParseException e) {
if (e == null) {
/** check to see if there are any more videos **/
if(videoData.size() == 0){
Toast.makeText(getApplicationContext(), "No more videos found.", Toast.LENGTH_LONG).show();
}else{
for(int i=0; i<videoData.size(); i++){
String videoUrl = videoData.get(i).getString("url");
String videoTitle = videoData.get(i).getString("title");
String videoUser = videoData.get(i).getString("user");
TextView title = (TextView)findViewById(R.id.videoTitle);
title.setTextColor(Color.parseColor("#FFFFFF"));
title.setText(videoTitle);
TextView user = (TextView)findViewById(R.id.videoUser);
user.setTextColor(Color.parseColor("#FFFFFF"));
user.setText("By: " + videoUser);
myVideoView = (VideoView) findViewById(R.id.myvideoview);
myVideoView.setVideoPath(vineVideoUrl);
myVideoView.setMediaController(null);
myVideoView.start();
/** loop video **/
myVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
myVideoView.start();
}
});
/** next video **/
Button button= (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
count++;
Toast.makeText(getApplicationContext(), "Loading...", Toast.LENGTH_LONG).show();
getVideos();
}
});
}
}
} else {
Toast.makeText(getApplicationContext(), "Unable to retrieve videos, please check back later.", Toast.LENGTH_LONG).show();
}
}
});
}
Each time the button is pressed, it increments count, and gets the video for that ID from the API. What I am trying to figure out is how can I retrieve say the latest 20 videos from the API the correct way?
The way I can think the proper way to do it is this:
Get latest 20 videos from API, store in array, then when button is pressed loop thru each. How would I pass them each to the textview? And how should I know when it's the last video (20) and to call the API again and pass back the new results?

You can create a List<String> oldMovies which will hold the ids of the movies you already received, now each time you want bring more movies in your query add this constraint movieQuery.notConteindIn("onjectId", oldMovies). That shall return a list of movies that doesn't have one of the objectsId contained in the oldMovies. Each time you will need to update the oldMovie list of ids.

Related

How to store users coins on firebase database and retrive them?

I am creating an app in which coins/points increases on watching reward video ads and those coins/points should be saved to firebase.
For example: every time on button click the coins value increases to 10 points. Now when I completely destroy the app and open it again, the points value should show the same, not zero
Here is my code till now without database implementation
private TextView mText;
private int coinCount;
mText = (TextView) findViewById(R.id.money);
coinCount = 0;
mText.setText(" " + coinCount);
Button button = (Button) findViewById(R.id.buynow);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (coinCount <= 29) {
//if(coinCount <30) {
new MaterialStyledDialog.Builder(MainActivity.this)
.setTitle("Not Enough Coins")
.setDescription("Watch the Ad To Get 10 coins")
.setIcon(R.drawable.ic_money)
.withIconAnimation(true)
.withDialogAnimation(true)
.withDarkerOverlay(true)
.setHeaderColor(R.color.color)
.setPositiveText("Get some coins")
.onPositive(new MaterialDialog.SingleButtonCallback() {
#Override
public void onClick(#NonNull MaterialDialog dialog, #NonNull DialogAction which) {
mRewardedVideoAd.show();
}
})
.show();
} else {
coinCount = coinCount - 30;
mText.setText(String.valueOf(coinCount));
}
}
});
My queston is how to Save The Coin value to DATABASE and retrieve it ?

Android Studio TextToSpeech run issue

I am basically making a firstaid training app (to help get people prepared for NL (National lifeguard) and Standard first aid).
This is done in a multiple choice form factor, and I have an activity which pulls all the questions, answers, and explanations and stores them in an array. As the user answers each question, it moves onto the next by replacing the text on the buttons and textview of the question, and I have made it so android says the question using TextToSpeech.
My error, is that for some reason on the first question, the string (question) gets given to the TextToSpeech talker, but it does not say it? What is weird is that for the other questions (2,3,4,etc.) it works, just not for the first.
I thought that maybe it was that it didnt have enough time to construct (which some other thread said was the problem when the TextToSpeech lags), so I added a delay to the button that starts the multiple choice activity and it still did not work for the first question, but works for the rest.
Here is my code for the TextToSpeech:
In the onCreate of the class:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz_menu);
prefs = getSharedPreferences("com.comsci.michelaustin.comscisummative", MODE_PRIVATE);
moduleNumber = getIntent().getIntExtra("MODULE_ID", 0);
talker = new TextToSpeech(QuizMenuActivity.this, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS){
result = talker.setLanguage(Locale.UK);
}
else
{
Toast.makeText(getApplicationContext(), "Talking feature not supported on this device", Toast.LENGTH_SHORT).show();
}
}
});
In the method that sets the textview and buttons to the correct question and answers:
private void displayQuestions(){
String ques = mQuestionLibraryTest.getQuestion(questionNumber);
questionLabel.setText(ques);
talker.speak(ques,TextToSpeech.QUEUE_FLUSH,null);
option1.setText(getChoice(questionNumber,0));
option2.setText(getChoice(questionNumber,1));
option1.setEnabled(true);
option2.setEnabled(true);
option3.setEnabled(true);
option4.setEnabled(true);
option1.setBackgroundColor(getResources().getColor(R.color.colorLightblue));
option2.setBackgroundColor(getResources().getColor(R.color.colorLightblue));
option3.setBackgroundColor(getResources().getColor(R.color.colorLightblue));
option4.setBackgroundColor(getResources().getColor(R.color.colorLightblue));
//to test specifically for true and false questions and to remove visibility of the last two buttons
if (testWhetherBlank(2)) {
option3.setVisibility(View.GONE);
}
else{
option3.setVisibility(View.VISIBLE);
option3.setText(getChoice(questionNumber,2));
}
if (testWhetherBlank(3)) {
option4.setVisibility(View.GONE);
}
else{
option4.setVisibility(View.VISIBLE);
option4.setText(getChoice(questionNumber,3));
}
//
//answerArray=(ArrayList<Object>)mQuestionLibrary.getCorrectAnswer(questionNumber).clone();
answerArray = (ArrayList<String>) mQuestionLibraryTest.getCorrectAnswer(questionNumber).clone();
//Collections.copy(mQuestionLibraryTest.getCorrectAnswer(questionNumber), answerArray);
//explanation=mQuestionLibrary.getExplanation(questionNumber);
explanation = mQuestionLibraryTest.getExplanation(questionNumber);
amountCorrect=mQuestionLibraryTest.getAnswerAmount(questionNumber);
nextArrowButton.setVisibility(View.GONE);
writeResume();
}
//allows the UI to test and remove buttons if the options are blank
public boolean testWhetherBlank(int q){
/*if(mQuestionLibrary.getChoice(questionNumber,q).equals("")){
return true;
}*/
if(mQuestionLibraryTest.getChoice(questionNumber,q).equals("")){
return true;
}
else{
return false;
}
}
Any help is greatly appreciated!

Retrieving ArrayList<Object> from FireBase inner class

I've been looking at the firebase documentation and tried to make firebase work with an android app I'm building.
All the code examples I could find show how to get a value, then immediately print it within the firebase ValueEventListener inner class. I would like to get the values and store them in an array for later use.
What I try to do is when a user clicks the highscore button the client gets the current scoreboard from firebase, and sends that list to the highscoreboard class.
UPDATE: I have been able to retrieve the data now but there is a behavior that confuses me greatly. If the user clicks the highscorebutton the scores list gets populated and highscore class is correctly showing 10 elements. If I exit the scoreboard and enter it again it will now show all scores twice (understandably so, as I am just adding to the same list). But any calls to scores.clear() or scores = new ArrayList(); between the two clicks results in scores being empty even after the second click (I assumed that populating scores, then emptying it and repopulating it would leave 10 items in there) This behavior was the reason I thought my scores array never got populate when first posting here as I had a scores.clear() call inside the load function since I didn't want to duplicate values. If anyone is able to explain why this happens that would be fantastic.
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
ArrayList<Score> scores;
Firebase myFirebase;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Firebase.setAndroidContext(this);
myFirebase = new Firebase(FirebaseURL);
scores = new ArrayList<Score>();
loadScoresFromFireBase();
}
public void loadScoresFromFireBase() {
String entry = "";
for (int i = 0; i < 10; i++) {
entry = "Name_" + i;
myFirebase.child("users").child(entry).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
//getValue correctly returns a Score object
scores.add(snapshot.getValue(Score.class));
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
}
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//....
if ( id == 2) {
Intent intent = new Intent(getApplicationContext(), ScoreBoard.class);
Bundle bundle = new Bundle();
//calling scores.clear() here leaves the scores array empty even though loadscores is called afterwards.
loadScoresFromFireBase();
Collections.sort(scores);
bundle.putSerializable("players", scores);
intent.putExtra("players", bundle);
startActivityForResult(intent, 0);
}
}
}
You're falling for the classic asynchronous trap:
loadScoresFromFireBase();
Collections.sort(scores);
When you call loadScoresFromFireBase() (it's spelled Firebase btw), the program starts synchronizing the scores from the server. Loading this data takes some time. Instead of making your program wait (which would be a bad user experience), Firebase makes you pass in a ValueEventListener that it then calls when the data is available. But you're calling Collections.sort(scores) straight away, before the (first) data has been loaded.
You can most easily see this by adding a few log statements:
public void loadScoresFromFireBase() {
String entry = "";
for (int i = 0; i < 10; i++) {
entry = "Name_" + i;
myFirebase.child("users").child(entry).addValueEventListener(new ValueEventListener() {
public void onDataChange(DataSnapshot snapshot) {
System.out.println("Adding score to array");
scores.add(snapshot.getValue(Score.class));
}
public void onCancelled(FirebaseError firebaseError) { }
});
}
}
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//....
if (id == 2) {
Intent intent = new Intent(getApplicationContext(), ScoreBoard.class);
Bundle bundle = new Bundle();
System.out.println("Before calling loadScores");
loadScoresFromFireBase();
System.out.println("After calling loadScores");
Collections.sort(scores);
System.out.println("After sorting scores");
The output of these log statements will be:
Before calling loadScores
After calling loadScores
After sorting scores
Adding score to array
That is probably not what you expected. But it is completely normal when you're dealing with asynchronous/event driven code, like is common in modern internet programming.
The most direct solution is to move the code that needs the scores into the function that loads them:
public void loadScoresFromFireBase() {
String entry = "";
for (int i = 0; i < 10; i++) {
entry = "Name_" + i;
myFirebase.child("users").child(entry).addValueEventListener(new ValueEventListener() {
public void onDataChange(DataSnapshot snapshot) {
scores.add(snapshot.getValue(Score.class));
Collections.sort(scores);
Intent intent = new Intent(getApplicationContext(), ScoreBoard.class);
Bundle bundle = new Bundle();
bundle.putSerializable("players", scores);
intent.putExtra("players", bundle);
startActivityForResult(intent, 0);
}
public void onCancelled(FirebaseError firebaseError) { }
});
}
}
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//....
if (id == 2) {
loadScoresFromFireBase();
Also see this answer I wrote a while ago: Setting Singleton property value in Firebase Listener
As well as these great answers on the same problem:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
How do I return the response from an asynchronous call?
Although these are about JavaScript, they deal with the exact same problem.
As you have not initialized scores you will be getting a NullPointerException when calling add
If you do
ArrayList<Score> scores = new ArrayList ();
it should work

Communicating between two autocompletetextviews

I'm fairly new to Android, and I'm using Android Studio for development.
I'm developing an app which communicates with SQL Server and retrieves data to Android and displays them on user request.
I'm currently running into an error. What I'm supposed to do is, there is an AutoCompleteTextView field for which I'm retrieving data and displaying for user selection (say, Organization/Company Names). Now, on selecting an option on this field, I have to send a query with this option (the Organization/Company Name) and retrieve data pertaining to this option from the database (say, the Contact Person Names in the selected Organization/Company) and display this data as options on the second AutoCompleteTextView field.
I did this within the OnCreate method using an ArrayAdapter, but the app kept crashing and now I realized that it's because the values for the second AutoCompleteTextView field are not available during OnCreate.
I need to be able to dynamically change the second AutoCompleteTextView field as and when the value for the first AutoCompleteTextView field is selected.
Any suggestions on how I could overcome this?
No need to try to set the result in the second AutoCompleteTextView inside onCreate(). You can do your task outside and when it's done, you set the values to it.Check out the AsyncTask, it might be so useful.
You can inspired with this code and use that :
txtSearch = (TextView) findViewById(R.id.txtSearch);
txtSearch.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence value, int start, int count, int after) {
if(value.length() > 0){
notes.clear();
cursorS = sql.rawQuery("SELECT CategoryID,Title from WebSite_CategoryDB WHERE ParentID = 0 AND Title LIKE + '" + "%" + value + "%" + "'",null);
try {
if (cursorS != null) {
if (cursorS.moveToFirst()) {
do {
StartActivity_Entity nte = new StartActivity_Entity();
nte._CategoryID = cursorS.getInt(cursorS.getColumnIndex("CategoryID"));
nte._Title = cursorS.getString(cursorS.getColumnIndex("Title"));
notes.add(nte);
} while (cursorS.moveToNext());
}
adapter.notifyDataSetChanged();
}
} catch (Exception e) {
} finally {
cursorS.close();
}
}else if(value.length() == 0){
populateListView();
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
Good look.

Caught in an infinite loop

I'm trying to perform a check on some information in a database. If i run the following code without it being in a loop it runs fine, but only checking the first row, what i need it to do is to check the names and dates for each row.
If i understand the while loop correctly it would move my cursor to the next row then just run the code again. Can anyone see why this is looping until my program crashes?
while (cursor.moveToNext()) {
String titlefromdb = cursor.getString(3);
if (strTitle.equals(titlefromdb)&& cursor.getString(1).equals(dateselforap)) {
Log.d("insidematch", "date and title matched");
final Dialog matchdiag = new DialogCW2Organisor.this);
matchdiag.setContentView(R.layout.apptmatch);
matchdiag.setTitle("View/Edit Appointment");
matchdiag.setCancelable(true);
TextView matchtxt = (TextView) matchdiag.findViewById(R.id.matchtxt);
matchtxt.setText("Appointment \""+ titlefromdb + "\" already exists, please choose a different event title");
Button btnmatchok = (Button) matchdiag.findViewById(R.id.btnmatch);
btnmatchok.setOnClickListener(new OnClickListener() {
//on click for cancel button
#Override
public void onClick(View v) {
matchdiag.dismiss();}
});
matchdiag.show();
} else {
addAppt(strTime, strTitle, strDet);
cursor = getAppts();
dialog.dismiss();
}
}
Try moving to the first record before calling moveToNext().
Move your functionality into a do/while loop so you can still grab the first record
if (!cursor.moveToFirst())
return; //nothing to do since the cursor is empty
do
{
String titlefromdb = cursor.getString(3);
if (strTitle.equals(titlefromdb)&& cursor.getString(1).equals(dateselforap)) {
Log.d("insidematch", "date and title matched");
final Dialog matchdiag = new DialogCW2Organisor.this);
matchdiag.setContentView(R.layout.apptmatch);
matchdiag.setTitle("View/Edit Appointment");
matchdiag.setCancelable(true);
TextView matchtxt = (TextView) matchdiag.findViewById(R.id.matchtxt);
matchtxt.setText("Appointment \""+ titlefromdb + "\" already exists, please choose a different event title");
Button btnmatchok = (Button) matchdiag.findViewById(R.id.btnmatch);
btnmatchok.setOnClickListener(new OnClickListener() {
//on click for cancel button
#Override
public void onClick(View v) {
matchdiag.dismiss();
}
});
matchdiag.show();
} else {
addAppt(strTime, strTitle, strDet);
cursor = getAppts();
dialog.dismiss();
}
} while (cursor.moveToNext());
I have also run into the infinite loop problem, which really baffled me as well, since a while !moveToNext() loop should definitely finish.
However, the workaround is to use a for loop over the length of the cursor, and process each cursor.moveToPosition(i).
for (int i = 0; i <= cursorLen; i++) {
if (!cursor.moveToPosition(i)) {
return;
}
// process your cursor
}
I feel like this must be a bug with the Cursor implementation, because a while loop over cursor.moveToNext() should always finish.

Categories

Resources