I have a 2 radioButtons in my layout. One is for yes and the other is for no when asked if insured or not. When I click my save button and the data posts to firestore, it shows both NO INSURED and YES INSURED. The way I have my code set up is why it's that way but what I want to do is have one source where if the person clicks yes or no then in firestore I will have Insured : Yes or Insured : No. I will post my code down below
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.Spinner;
import android.widget.Toast;
import com.google.android.gms.dynamic.ObjectWrapper;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.firestore.FirebaseFirestore;
import java.util.HashMap;
import java.util.Map;
public class ProviderSignUp extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
private static final String TAG = "MainActivity";
private static final String KEY_FNAME = "First Name";
private static final String KEY_LNAME = "Last Name";
private static final String KEY_ADDRESS = "Address";
private static final String KEY_SPINNER_VALUE = "Spinner Value";
private static final String KEY_FIXED= "Fixed Rate";
private static final String KEY_HOURLY = "Hourly Rate";
private static final String KEY_AGE_VALE= "Age Value";
private static final String KEY_DOLLAR_VALUE = "Dollar Value";
private static final String KEY_YES_INSURED = "Yes Insured";
private static final String KEY_NO_INSURED = "No Insured";
private EditText fName;
private EditText lName;
private EditText address;
private Spinner my_spinner;
private RadioButton fixedRadioButton;
private RadioButton hourlyRadioButton;
private EditText ageEditText;
private EditText dollarEditText;
private RadioButton yesButton;
private RadioButton noButton;
// Reference to firestore database
private FirebaseFirestore db = FirebaseFirestore.getInstance();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.provider_signup);
Spinner spinner = findViewById(R.id.mySpinner);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.provider_choices, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(this);
// FireStore Storage for Provider
fName = findViewById(R.id.firstName);
lName = findViewById(R.id.lastName);
address = findViewById(R.id.Address);
my_spinner = (Spinner)findViewById(R.id.mySpinner);
fixedRadioButton = findViewById(R.id.fixedRadioButton);
hourlyRadioButton = findViewById(R.id.hourlyRadioButton);
ageEditText = findViewById(R.id.ageEditText);
dollarEditText = findViewById(R.id.dollarEditText);
yesButton = findViewById(R.id.yesRadioButton);
noButton = findViewById(R.id.noRadioButton);
}
#Override
public void onBackPressed() {
startActivity(new Intent(ProviderSignUp.this,PreSignUp.class));
finish();
}
// These two methods below are for the spinner in the ProviderSignUp
#Override
// Will show a toast message after user selects spinner item
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long l) {
String text = adapterView.getItemAtPosition(position).toString();
Toast.makeText(adapterView.getContext(), text, Toast.LENGTH_SHORT).show();
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
String fname = fName.getText().toString();
String lname = lName.getText().toString();
String my_address = address.getText().toString();
String spinner = my_spinner.getSelectedItem().toString();
String fixed_radioButton = fixedRadioButton.getText().toString();
String hourly_Radiobutton = hourlyRadioButton.getText().toString();
String age = ageEditText.getText().toString();
String dollar = dollarEditText.getText().toString();
String yes_button = yesButton.getText().toString();
String no_button = noButton.getText().toString();
Map<String,Object> myMap = new HashMap<String,Object>();
myMap.put(KEY_FNAME,fname);
myMap.put(KEY_LNAME,lname);
myMap.put(KEY_ADDRESS, my_address);
myMap.put(KEY_FIXED, fixed_radioButton);
myMap.put(KEY_HOURLY, hourly_Radiobutton);
myMap.put(KEY_AGE_VALE, age);
myMap.put(KEY_DOLLAR_VALUE, dollar);
myMap.put(KEY_YES_INSURED, yes_button);
myMap.put(KEY_NO_INSURED, no_button);
myMap.put(KEY_SPINNER_VALUE , spinner);
db.collection("demoProviders").document("First Provider")
.set(myMap).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(ProviderSignUp.this, "User Saved", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(ProviderSignUp.this, "Error!", Toast.LENGTH_SHORT).show();
Log.d(TAG, e.toString());
}
});
}
}
First thing first,
When I click my save button and the data posts to firestore
This is not happening according to your code. You should use OnClickListener method to implement your thought. I suggest going through this documentation.
Second thing second,
Hope, you are using RadioGroup for your RadioButton. That won't allow more than one RadioButton to be selected at a single time. Here is how you can implement RadioGroup.
Last thing last,
Use a single key to store a boolean value instead of storing multiple key-value pairs for RadioButton state in Firestore. Try this :
if (radioGroup.getCheckedRadioButtonId() == R.id.yesRadioButton){
myMap.put("isInsured", true);
} else {
myMap.put("isInsured", false);
}
instead of this :
myMap.put(KEY_YES_INSURED, yes_button);
myMap.put(KEY_NO_INSURED, no_button);
If you do all the mentioned steps correctly your database should store one value for your RadioButton states. Try and let us know if this worked or not.
Related
I made a simple quiz on Android Studio which contains 3+ questions. How to make the questions become random without duplicated. This app does not use a database. I'm new to programming so I don't know what to do about this
MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.app.AlertDialog; import android.graphics.Color; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
TextView totalQuestionsTextView;
TextView questionTextView;
Button ansA,ansB,ansC,ansD;
Button submitBtn;
int score=0;
int totalQuestions = QuestionAnswer.question.length;
int currentQuestionIndex = 0;
String selectedAnswer = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
totalQuestionsTextView = findViewById(R.id.total_questions);
questionTextView = findViewById(R.id.question);
ansA = findViewById(R.id.ans_A);
ansB = findViewById(R.id.ans_B);
ansC = findViewById(R.id.ans_C);
ansD = findViewById(R.id.ans_D);
submitBtn = findViewById(R.id.submbit_btn);
ansA.setOnClickListener(this);
ansB.setOnClickListener(this);
ansC.setOnClickListener(this);
ansD.setOnClickListener(this);
submitBtn.setOnClickListener(this);
totalQuestionsTextView.setText("Total Questions : "+totalQuestions);
loadNewQuestion();
}
#Override
public void onClick(View view) {
ansA.setBackgroundColor(Color.WHITE);
ansB.setBackgroundColor(Color.WHITE);
ansC.setBackgroundColor(Color.WHITE);
ansD.setBackgroundColor(Color.WHITE);
Button clickedButton = (Button) view;
if(clickedButton.getId()==R.id.submbit_btn){
currentQuestionIndex++;
loadNewQuestion();
}else{
//choices button clicked
selectedAnswer = clickedButton.getText().toString();
clickedButton.setBackgroundColor(Color.MAGENTA);
}
}
void loadNewQuestion(){
if(currentQuestionIndex == totalQuestions){
finishQuiz();
return;
}
questionTextView.setText(QuestionAnswer.question[currentQuestionIndex]);
ansA.setText(QuestionAnswer.choices[currentQuestionIndex][0]);
ansB.setText(QuestionAnswer.choices[currentQuestionIndex][1]);
ansC.setText(QuestionAnswer.choices[currentQuestionIndex][2]);
ansD.setText(QuestionAnswer.choices[currentQuestionIndex][3]);
}
void finishQuiz(){
String passStatus = "";
if (score > totalQuestions*0.60){
passStatus = "Passes";
}else{
passStatus = "Failed";
}
new AlertDialog.Builder(this)
.setTitle(passStatus)
.setMessage("Score is "+score+" out of "+ totalQuestions)
.setPositiveButton("Restart",(dialogInterface, i) -> restartQuiz())
.setCancelable(false)
.show();
}
void restartQuiz(){
score = 0;
currentQuestionIndex = 0;
loadNewQuestion();
}
QuestionAnswer.java
import java.util.Arrays; import java.util.List; import java.util.Random;
public class QuestionAnswer {
public static String[] question = {
"Which company own the android?",
"Which one is not the programming language?",
"Where are you watching this video"
};
public static String choices[][] = {
{"Google", "Apple", "Nokia", "Samsung"},
{"Java", "Kotlin", "Notepad", "Python"},
{"Facebook", "Whatsapp", "Instagram", "Youtube"},
};
public static String correctAnswers[] = {
"Google",
"Notepad",
"Youtube"
};
}
how can i add shuffle.collection or random to make my app show random question instead
You need to find out about Random class first in Java. Thereafter, you will create a random number using Random class in onClick function, then set a question's index to your Random number
This question already has answers here:
How can I serialize my User class for the Firebase Database and fix this error?
(2 answers)
Closed 4 years ago.
Having previously had my application working perfectly, it now continually crashes now that I have attempted to add extra, but almost identical functionally. By extra functionality I mean Edit Texts, Spinners, etc. This is hugely frustrating, as it clearly is something very small that seems to be the issue.
My LogCat is showing that there is an error on Line 114 of my Property class, however, I can't understand why this would be an issue as it did not affect the application before added functionality was implemented.
LogCat
02-26 21:19:20.424 9478-9478/com.example.benchalmers.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.benchalmers.myapplication, PID: 9478
com.google.firebase.database.DatabaseException: Class com.example.benchalmers.myapplication.Property does not define a no-argument constructor. If you are using ProGuard, make sure these constructors are not stripped.
at com.google.android.gms.internal.zzelx.zze(Unknown Source:51)
at com.google.android.gms.internal.zzelw.zzb(Unknown Source:772)
at com.google.android.gms.internal.zzelw.zza(Unknown Source:0)
at com.google.firebase.database.DataSnapshot.getValue(Unknown Source:10)
at com.example.benchalmers.myapplication.PropertyActivity$4.onDataChange(PropertyActivity.java:114)
at com.google.android.gms.internal.zzegf.zza(Unknown Source:13)
at com.google.android.gms.internal.zzeia.zzbyc(Unknown Source:2)
at com.google.android.gms.internal.zzeig.run(Unknown Source:65)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
02-26 21:19:20.425 9478-9478/com.example.benchalmers.myapplication E/UncaughtException: com.google.firebase.database.DatabaseException: Class com.example.benchalmers.myapplication.Property does not define a no-argument constructor. If you are using ProGuard, make sure these constructors are not stripped.
at com.google.android.gms.internal.zzelx.zze(Unknown Source:51)
at com.google.android.gms.internal.zzelw.zzb(Unknown Source:772)
at com.google.android.gms.internal.zzelw.zza(Unknown Source:0)
at com.google.firebase.database.DataSnapshot.getValue(Unknown Source:10)
at com.example.benchalmers.myapplication.PropertyActivity$4.onDataChange(PropertyActivity.java:114)
at com.google.android.gms.internal.zzegf.zza(Unknown Source:13)
at com.google.android.gms.internal.zzeia.zzbyc(Unknown Source:2)
at com.google.android.gms.internal.zzeig.run(Unknown Source:65)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Previous to making these changes, I was able to add, update and delete records perfectly, with no hiccups whatsoever. This is what leads me to believe that the issues I'm having are easily fixed.
At the moment the screen loads up for 1 second and then it crashes almost immediately.
I have made small changes to variable names etc. thinking that that might help, but to no avail.
Any help on this would be much appreciated. I'm very new at Android, and with Stack! First Post!
PropertyActivity.java
package com.example.benchalmers.myapplication;
import android.content.Intent;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.List;
public class PropertyActivity extends AppCompatActivity {
public static final String PROPERTY_NAME = "propertyname";
public static final String PROPERTY_ID = "propertyid";
EditText editTextProperty;
EditText editTextPostcode;
EditText editTextBedrooms;
EditText editTextBathrooms;
Button buttonAddProperty;
Spinner spinnerFuel;
Spinner spinnerStatus;
Spinner spinnerEPC;
DatabaseReference databaseProperties;
ListView listViewProperties;
List<Property> propertyList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_property);
databaseProperties = FirebaseDatabase.getInstance().getReference("properties");
editTextProperty = (EditText) findViewById(R.id.editTextProperty);
editTextPostcode = (EditText) findViewById(R.id.editTextPostcode);
editTextBedrooms = (EditText) findViewById(R.id.editTextBedrooms);
editTextBathrooms = (EditText) findViewById(R.id.editTextBathrooms);
buttonAddProperty = (Button) findViewById(R.id.buttonAddProperty);
spinnerStatus = (Spinner) findViewById(R.id.spinnerStatus);
spinnerEPC = (Spinner) findViewById(R.id.spinnerEPC);
spinnerFuel = (Spinner) findViewById(R.id.spinnerFuel);
listViewProperties = (ListView) findViewById(R.id.listViewProperties);
propertyList = new ArrayList<>();
buttonAddProperty.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addProperty();
}
});
listViewProperties.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
Property property = propertyList.get(position);
Intent intent = new Intent(getApplicationContext(), AddTenantsActivity.class);
intent.putExtra(PROPERTY_ID, property.getPropertyId());
intent.putExtra(PROPERTY_NAME, property.getPropertyAddress());
startActivity(intent);
}
});
listViewProperties.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
Property property = propertyList.get(position);
showUpdateDialog(property.getPropertyId(), property.getPropertyAddress(), property.getPropertyPostcode(), property.getPropertyBedrooms(), property.getPropertyBathrooms(), property.getPropertyStatus(), property.getPropertyEPC(), property.getPropertyFuel());
return false;
}
});
}
#Override
protected void onStart() {
super.onStart();
databaseProperties.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
propertyList.clear();
for(DataSnapshot propertySnapshot : dataSnapshot.getChildren()){
Property property = propertySnapshot.getValue(Property.class);
propertyList.add(property);
}
PropertyList adapter = new PropertyList (PropertyActivity.this, propertyList);
listViewProperties.setAdapter(adapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void showUpdateDialog(final String id, String propertyAddress, String propertyPostcode, String propertyBedrooms, String propertyBathrooms, String propertyStatus, final String propertyId, String propertyName) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
LayoutInflater inflater = getLayoutInflater();
final View dialogView = inflater.inflate(R.layout.update_dialog, null);
dialogBuilder.setView(dialogView);
final EditText editTextName = (EditText) dialogView.findViewById(R.id.editTextName);
final Button buttonUpdate = (Button) dialogView.findViewById(R.id.buttonUpdate);
final Spinner spinnerFuel = (Spinner) dialogView.findViewById(R.id.spinnerFuel);
final Button buttonDelete = (Button) dialogView.findViewById(R.id.buttonDelete);
dialogBuilder.setTitle("Updating Property " + propertyName);
final AlertDialog alertDialog = dialogBuilder.create();
alertDialog.show();
buttonUpdate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String name = editTextName.getText().toString().trim();
String postcode = editTextPostcode.getText().toString().trim();
String bedrooms = editTextBedrooms.getText().toString().trim();
String bathrooms = editTextBathrooms.getText().toString().trim();
String status = spinnerStatus.getSelectedItem().toString();
String epc = spinnerEPC.getSelectedItem().toString();
String fuel = spinnerFuel.getSelectedItem().toString();
if(TextUtils.isEmpty(name)){
editTextName.setError("Name Required");
return;
}
updateProperty(propertyId, status, postcode, bedrooms, bathrooms, id, name, epc, fuel);
alertDialog.dismiss();
}
});
buttonDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
deleteProperty(propertyId);
}
});
}
private void deleteProperty(String propertyId) {
DatabaseReference drProperty = FirebaseDatabase.getInstance().getReference("properties").child(propertyId);
DatabaseReference drTenants = FirebaseDatabase.getInstance().getReference("tenants").child(propertyId);
drProperty.removeValue();
drTenants.removeValue();
Toast.makeText(this, "Property has been deleted", Toast.LENGTH_LONG).show();
}
private boolean updateProperty(String propertyId, String status, String postcode, String bedrooms, String bathrooms, String id, String name, String epc, String fuel){
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("properties").child(id);
Property property = new Property (id, name, postcode, bedrooms, bathrooms, status, epc, fuel);
databaseReference.setValue(property);
Toast.makeText(this, "Property Updated Successfully", Toast.LENGTH_LONG).show();
return true;
}
private void addProperty(){
String address = editTextProperty.getText().toString().trim();
String postcode = editTextPostcode.getText().toString().trim();
String bedrooms = editTextBedrooms.getText().toString().trim();
String bathrooms = editTextBathrooms.getText().toString().trim();
String status = spinnerStatus.getSelectedItem().toString();
String epc = spinnerEPC.getSelectedItem().toString();
String fuel = spinnerFuel.getSelectedItem().toString();
if(!TextUtils.isEmpty(address)){
String id = databaseProperties.push().getKey();
Property property = new Property (id, address, postcode, bedrooms, bathrooms, status, epc, fuel);
databaseProperties.child(id).setValue(property);
Toast.makeText(this, "Property Added", Toast.LENGTH_LONG).show();
}else {
Toast.makeText(this, "You must enter a property", Toast.LENGTH_LONG).show();
}
}
}
Property.java
package com.example.benchalmers.myapplication;
/**
* Created by benchalmers on 21/02/2018.
*/
public class Property {
String propertyId;
String propertyAddress;
String propertyPostcode;
String propertyFuel;
String propertyBedrooms;
String propertyBathrooms;
String propertyEPC;
String propertyStatus;
public Property(String id, String address, String postcode, String bedrooms, String bathrooms, String status, String epc, String fuel ) {
this.propertyId = propertyId;
this.propertyAddress = propertyAddress;
this.propertyPostcode = postcode;
this.propertyFuel = propertyFuel;
this.propertyBedrooms = bedrooms;
this.propertyBathrooms = bathrooms;
this.propertyEPC = epc;
this.propertyStatus = status;
}
public String getPropertyId() {
return propertyId;
}
public String getPropertyAddress() {
return propertyAddress;
}
public String getPropertyPostcode() {
return propertyPostcode;
}
public String getPropertyFuel() {
return propertyFuel;
}
public String getPropertyBedrooms() {
return propertyBedrooms;
}
public String getPropertyBathrooms() {
return propertyBathrooms;
}
public String getPropertyEPC() {
return propertyEPC;
}
public String getPropertyStatus() {
return propertyStatus;
}
}
PropertyList.java
package com.example.benchalmers.myapplication;
import android.app.Activity;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.List;
public class PropertyList extends ArrayAdapter<Property> {
private Activity context;
private List<Property> propertyList;
public PropertyList(Activity context, List<Property> propertyList) {
super(context, R.layout.property_list_layout, propertyList);
this.context = context;
this.propertyList = propertyList;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View listViewItem = inflater.inflate(R.layout.property_list_layout, null, true);
TextView textViewProperty = (TextView) listViewItem.findViewById(R.id.textViewProperty);
TextView textViewPostcode = (TextView) listViewItem.findViewById(R.id.textViewPostcode);
TextView textViewBedrooms = (TextView) listViewItem.findViewById(R.id.textViewBedrooms);
TextView textViewBathrooms = (TextView) listViewItem.findViewById(R.id.textViewBathrooms);
TextView textViewStatus = (TextView) listViewItem.findViewById(R.id.textViewStatus);
TextView textViewEPC = (TextView) listViewItem.findViewById(R.id.textViewEPC);
TextView textViewFuel = (TextView) listViewItem.findViewById(R.id.textViewFuel);
Property property = propertyList.get(position);
textViewProperty.setText(property.getPropertyAddress());
textViewPostcode.setText(property.getPropertyPostcode());
textViewBedrooms.setText(property.getPropertyBedrooms());
textViewBathrooms.setText(property.getPropertyBathrooms());
textViewStatus.setText(property.getPropertyStatus());
textViewEPC.setText(property.getPropertyEPC());
textViewFuel.setText(property.getPropertyFuel());
return listViewItem;
}
}
Firebase requires a no-argument constructor in your Property class so that you can use getValue(Property.class). So add this constructor to your Property class:
public Property() {}
I'm working on a app where saxophone players can choose a saxophone (soprano, alto, tenor or baritone). The database should output all the music pieces that are available for that specific saxophone, together with the composer and publisher.
I've used a prepopulated db (created with SQLite Manager) and used the SQLite Asset Helper.
The database (so far) has some 600 records.
Whenever I query the database (let's say on 'alto'), it takes some 10 seconds before the results are found.
I've tried many things: indexing (both in the db file as in the Java code), changed between sqlite-file and db-file, tried on a real device instead of emulator etc, etc.
Nothing seems to work... I hope someone out there can help me on this...
I use two java classes: MyDatabase and SQLiteOpenHelper. If you need more info, please let me know.
MyDatabase class:
package com.example.musicrepertoiredatabase2;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import com.readystatesoftware.sqliteasset.SQLiteAssetHelper;
public class MyDatabase extends SQLiteAssetHelper {
SqliteAssetHelper helper = new SqliteAssetHelper();
private static final String DATABASE_NAME = "saxophone_repertoire.sqlite";
private static final String TABLE_NAME = "repertoire";
private static final int DATABASE_VERSION = 1;
private static final String ID = "id";
private static final String COMPOSER = "composer";
private static final String TITLE = "title";
private static final String PUBLISHER = "publisher";
private static final String SAXOPHONE = "saxophone";
private static final String ACCOMPANIMENT = "form";
public MyDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public Cursor getData() {
SQLiteDatabase db = this.getWritableDatabase();
String saxSort = SqliteAssetHelper.chooseSax;
String composer = SqliteAssetHelper.chooseComposer;
Cursor result = db.rawQuery("SELECT Composer, id FROM " + TABLE_NAME
+ " WHERE " + SAXOPHONE + "='" + saxSort + "'", null);
return result;
}
}
My SQLiteAssetHelper class:
package com.example.musicrepertoiredatabase2;
import android.app.ProgressDialog;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.ActionBarActivity;
import android.text.Html;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
public class SqliteAssetHelper extends ActionBarActivity implements
OnItemSelectedListener, OnClickListener {
TextView composer, title, saxophone, accompaniment, showInfo, count;
EditText etComposer, etTitle;
Spinner spinnerSaxophone, spinnerAccompaniment;
Button search, clear;
String[] arraySaxophone = { "Soprano", "Alto", "Tenor", "Baritone" };
String[] arrayAccompaniment = { "Solo", "Piano" };
public static String chooseSax = null;
public static String chooseComposer = null;
Handler updateBarHandler;
private MyDatabase db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
updateBarHandler = new Handler();
spinnerSaxophone = (Spinner) findViewById(R.id.spinner_saxophone);
spinnerSaxophone.setOnItemSelectedListener(this);
ArrayAdapter<String> adapter1 = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, arraySaxophone);
spinnerSaxophone.setAdapter(adapter1);
spinnerAccompaniment = (Spinner) findViewById(R.id.spinner_accompaniment);
spinnerAccompaniment.setOnItemSelectedListener(this);
ArrayAdapter<String> adapter2 = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, arrayAccompaniment);
spinnerAccompaniment.setAdapter(adapter2);
etComposer = (EditText) findViewById(R.id.et_composer);
etComposer.setHint(Html.fromHtml("<small>"
+ getString(R.string.hint_composer) + "<small>"));
etTitle = (EditText) findViewById(R.id.et_title);
etTitle.setHint(Html.fromHtml("<small>"
+ getString(R.string.hint_title) + "<small>"));
search = (Button) findViewById(R.id.btn_search);
clear = (Button) findViewById(R.id.btn_clear);
search.setOnClickListener(this);
clear.setOnClickListener(this);
showInfo = (TextView) findViewById(R.id.tv_showinfo);
count = (TextView) findViewById(R.id.tv_count);
db = new MyDatabase(this);
}
public void launchRingDialog() {
final ProgressDialog ringProgressDialog = ProgressDialog.show(this,
"Searching database...", "Please wait...", true);
ringProgressDialog.setCancelable(true);
new Thread(new Runnable(){
#Override
public void run(){
try{
Thread.sleep(5000);
}catch (Exception e){
}
ringProgressDialog.dismiss();
}
}).start();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position,
long id) {
int choosePositionSax = spinnerSaxophone.getSelectedItemPosition();
switch (choosePositionSax) {
case 0:
chooseSax = "Soprano";
break;
case 1:
chooseSax = "Alto";
break;
case 2:
chooseSax = "Tenor";
break;
case 3:
chooseSax = "Baritone";
break;
default:
break;
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_search:
launchRingDialog();
chooseComposer = etComposer.getText().toString();
Cursor result = db.getData();
if (result.getCount() == 0) {
Toast.makeText(this, "Nothing found", Toast.LENGTH_SHORT)
.show();
}
launchRingDialog();
StringBuffer buffer = new StringBuffer();
while (result.moveToNext()) {
//buffer.append("Title: " + result.getString(2) + "\n");
buffer.append("Composer: " + result.getString(1) + "\n\n");
showInfo.setText(buffer);
int countFiles = result.getCount();
count.setText(Integer.toString(countFiles));
}
break;
case R.id.btn_clear:
showInfo.setText("");
etComposer.setText("");
etComposer.requestFocus();
break;
default:
break;
}
}
}
Well you have to wait for 5 seconds, why =) ?
Thread.sleep(5000);
Delete this line and your query will be faster!
I have seen that you have launchRingDialog() declared two times in your code so you have to wait for 10 seconds. Your query should last no more than milliseconds so probably you don´t need any ProgressDialog.
I'd suggest adding an index to your table:
Create Index IF NOT EXISTS _index_saxophone on T_ResultsSummary(saxophone);
In my Android app, I made an SQLite database containig
(_id, FRIEND_NAME, FRIEND_PLACE(detailed address), FRIEND_PHONE, FRIEND_LOC(location), FRIEND_CATEG)
Also i implemented a List View wich displays all the FRIEND_NAMEs (from the database).
I want to call the selected friend when i click his name.
Infortunatly in despite of calling his number, the app calls always this number "74663".
In fact, I think that the problem is in the assignement of the variable "phone" so when i use (Intent.ACTION_CALL, Uri.parse(phone)) , it gives everytime this same number(74663) (maybe when it does "parse uri" or in the cursor of the database's listview).
1) Where is the problem?
2) Why it always gives the number 74663 to dial
3) can you (please) tell me how to assign the variable phone to get the FRIEND_PHONE of the clicked FRIEND_NAME?
this is the code of the class
`package com.softeq.prepopdb.activity;
import java.util.ArrayList;
import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.softeq.android.prepopdb.R;
import com.softeq.prepopdb.dbhelper.ExternalDbOpenHelper;`
//������� ��������� �������� ������� ���� ����� ��
public class PrepopSqliteDbActivity extends ListActivity {
private static final String DB_NAME = "yourdb.sqlite";
private static final String TABLE_NAME = "friends";
private static final String FRIEND_ID = "_id";
private static final String FRIEND_NAME = "name";
public static final String FRIEND_PLACE = "place";
public static final String FRIEND_PHONE = "phone";
public static final String FRIEND_LOC = "loc";
public static final String FRIEND_CATEG = "categ";
private SQLiteDatabase database;
private ListView listView;
private ArrayList<String> friends;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//��� �������� ������
ExternalDbOpenHelper dbOpenHelper = new ExternalDbOpenHelper(this, DB_NAME);
database = dbOpenHelper.openDataBase();
//��� ���� ����������
fillFreinds();
setUpList();
}
//filling the list with friends//
private void fillFreinds() {
friends = new ArrayList<String>();
Cursor friendCursor = database.query(TABLE_NAME,
new String[]
{FRIEND_ID, FRIEND_NAME,FRIEND_PLACE,FRIEND_PHONE,FRIEND_LOC,FRIEND_CATEG},
null, null,null,null, FRIEND_CATEG);
friendCursor.moveToFirst();
if(!friendCursor.isAfterLast()) {
do {
String name = friendCursor.getString(1);
String phone= friendCursor.getString(3);
friends.add(name);
friends.add(phone);
} while (friendCursor.moveToNext());
}
friendCursor.close();
}
//setting up the list to call (or dial) a friend's number onItemClick
private void setUpList() {
setListAdapter(new ArrayAdapter<String>(this,android.R.layout. simple_expandable_list_item_1 , friends));
listView = getListView();
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,int position,long id) {
String phone = "tel:" + FRIEND_PHONE.toString().trim();
Intent i = new Intent(Intent.ACTION_CALL, Uri.parse(phone));
startActivity(i);
}
});
}
}
Create two separate lists for names and phones.
ArrayList<String> names;
ArrayList<String> phones;
Change this portion of your code:
do {
String name = friendCursor.getString(1);
String phone = friendCursor.getString(3);
names.add(name);
phones.add(phone);
} while (friendCursor.moveToNext());
Set names as the data source of your adapter.
setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, names));
And access the appropriate phone number in the list like this:
String phone = "tel:" + phones.get(position);
Intent i = new Intent(Intent.ACTION_CALL, Uri.parse(phone));
startActivity(i);
Obviously you will give same value.
use getItemAtPosition(position); to get the exact item on which you have clicked.
Everytime I tried to run these code the program crashed then I tried to get an Array of Objects from my LinkedList.
Product[] arr = (Product[])produktliste.toArray(); causes the crash
This is the source of the MainActivity:
package at.lamprechtdominik.myfirstlistapp;
import java.util.LinkedList;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
import android.app.Activity;
import android.content.Intent;
public class MainActivity extends Activity {
public static LinkedList<Product> produktliste = new LinkedList<Product>();
private Button benutzerAnlegen;
private Button listeAnzeigen;
private EditText nameProdukt;
private EditText preisProdukt;
private CheckBox istVorhanden;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
benutzerAnlegen = (Button) findViewById(R.id.btBenutzerAnlegen);
nameProdukt = (EditText) findViewById(R.id.etProduktname);
preisProdukt = (EditText) findViewById(R.id.etPreis);
istVorhanden = (CheckBox) findViewById(R.id.cbProduktVorhanden);
listeAnzeigen = (Button) findViewById(R.id.btZeigeListe);
benutzerAnlegen.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
produktliste.add(neuesProduktAnlegen());
Toast.makeText(getBaseContext(), R.string.anlegen_erfolgreich, Toast.LENGTH_LONG).show();
}
});
listeAnzeigen.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//Intent i = new Intent(getBaseContext(), Produktauflistung.class);
//startActivity(i);
Product[] arr = (Product[])produktliste.toArray();
}
});
}
private Product neuesProduktAnlegen(){
String name = nameProdukt.toString();
Double preis = Double.parseDouble(preisProdukt.getText().toString());
boolean vorhanden;
if(istVorhanden.isChecked()){
vorhanden = true;
} else {
vorhanden = false;
}
Product neuesProdukt = new Product(name, preis , vorhanden);
return(neuesProdukt);
}
}
class file Product:
package at.lamprechtdominik.myfirstlistapp;
public class Product {
private String name;
private Double preis;
private boolean istVorhanden;
public Product(String name, Double preis, boolean istVorhanden){
this.name = name;
this.preis = preis;
this.istVorhanden = istVorhanden;
}
public String getName(){
return(name);
}
public Double getPreis(){
return(preis);
}
public boolean getIstVorhanden(){
return(istVorhanden);
}
}
Does anyone know how what i did wrong?
Thanks for your help.
You cannot simply cast the result of toArray() to a Product[] array.
Use this:
Product[] meineProdukte = new Product(produktliste.size());
meineProdukte = produktliste.toArray(meineProdukte);
Try to change to
Product[] arr = produktliste.toArray(new Product[produktliste.size()]);