unable to disable button in android - java

I tried everything but unable to disable that save button. i wrote it at the end of my onCreate.
Actually i wanted if user edits some notes and selects category from spinner it will automatically get enabled and i achieved it.
But i want that first when user is on this page button should be disabled. When user dose his work it will enable.
But how should i disable this save button.
Here is my OfflinePBDetails.java class
package passbookManager;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.Properties;
import logs.TraceLog;
import mainApplication.*;
import forbes.mPassbook.R;
import databaseClasses.DBAccountStatement;
import databaseClasses.DBCategoryMaster;
import android.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.StrictMode;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
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;
import android.os.Build;
public class OfflinePBDetails extends Activity implements OnItemSelectedListener
{
TextView tvDate;
TextView tvAmount;
TextView tvBalance;
TextView tvParticular;
TextView tvTitleAmount;
EditText etNotes;
Spinner spinnerCategory;
Button btnBack;
Button btnSave;
String file_Path;
Properties properties_config;
long sessionTimeout;
String passTransId;
String passDate;
String passParticular;
String passDebitCreditIndicator;
String passAmount;
String passTransString;
String passBalance;
String passFlag;
String transId;
String notes;
int countDBRows;
int countDBColumns;
String dbSubCategory;
String dbNotes;
String selectedCategory;
String[][] tableCategory ;
ArrayList<String> categoryIncome;
ArrayList<String> categoryExpense;
ArrayAdapter<String> adapterSelect;
DBCategoryMaster dbCMaster;
DBAccountStatement dbStatement;
TraceLog tc = new TraceLog();
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
ActionBar bar=getActionBar();
bar.hide();
setContentView(R.layout.activity_offline_pbdetails);
dbCMaster = new DBCategoryMaster(this);
dbStatement = new DBAccountStatement(this);
file_Path=Environment.getExternalStorageDirectory()+ "/Android/data/forbes.mPassbook/";
readConfigFileDetails();
if( Build.VERSION.SDK_INT >= 9)
{
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
try
{
tvDate = (TextView)findViewById(R.id.tv_getDate);
tvParticular = (TextView)findViewById(R.id.tv_getParticular);
tvAmount = (TextView)findViewById(R.id.tv_getAmount);
tvTitleAmount = (TextView)findViewById(R.id.tv_titleAmount);
tvBalance = (TextView)findViewById(R.id.tv_getBalance);
spinnerCategory = (Spinner)findViewById(R.id.spn_selectCategory);
etNotes = (EditText)findViewById(R.id.et_getNotes);
btnBack = (Button)findViewById(R.id.btnBack);
btnSave = (Button)findViewById(R.id.btnSave);
Intent intent = getIntent();
passTransId = intent.getExtras().getString("TransactionId");
passDate = intent.getExtras().getString("Date");
passParticular = intent.getExtras().getString("Particular");
passAmount = intent.getExtras().getString("Amount");
passTransString = intent.getExtras().getString("TransString");
passDebitCreditIndicator = intent.getExtras().getString("Indicator");
passBalance = intent.getExtras().getString("Balance");
passFlag = intent.getExtras().getString("FilterFlag");
tvDate.setText(passDate);
tvParticular.setText(passParticular);
tvTitleAmount.setText(passTransString);
if(tvTitleAmount.getText().equals("Withdrawal Amount"))
{
tvAmount.setTextColor(Color.RED);
}
else
{
tvAmount.setTextColor(Color.rgb(48,128,20));
}
String trimAmount = passAmount.trim();
String trimBalance = passBalance.trim();
tvAmount.setText(trimAmount);
tvBalance.setText(trimBalance);
etNotes.addTextChangedListener(new TextWatcher()
{
#Override
public void afterTextChanged(Editable arg0)
{
btnSave.setEnabled(true);
resetDisconnectTimer();
// Toast.makeText(getApplicationContext(), "After Typing", Toast.LENGTH_LONG).show();
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
// Toast.makeText(getApplicationContext(), "Before Typing", Toast.LENGTH_LONG).show();
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
// Toast.makeText(getApplicationContext(), "Typing", Toast.LENGTH_LONG).show();
}
});
btnBack.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
if(passFlag.equalsIgnoreCase("OfflinePB"))
{
Intent i = new Intent(OfflinePBDetails.this,OfflinePB.class);
i.putExtra("filterFlag","notes");/**********Code to go back to DisplayFilter Page***************************/
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
finish();
}
else if(passFlag.equalsIgnoreCase("notes"))
{
Intent i = new Intent(OfflinePBDetails.this,DisplayFilters.class);
i.putExtra("filterFlag","notes");
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
finish();
}
else if(passFlag.equalsIgnoreCase("transfer"))
{
Intent i = new Intent(OfflinePBDetails.this,DisplayFilters.class);
i.putExtra("filterFlag","transfer");
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
finish();
}
else if(passFlag.equalsIgnoreCase("cheque"))
{
Intent i = new Intent(OfflinePBDetails.this,DisplayFilters.class);
i.putExtra("filterFlag","cheque");
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
finish();
}
}
});
btnSave.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
try
{
btnSave.setEnabled(false);
transId = passTransId;
notes = etNotes.getText().toString();
// if(spinnerCategory.length()==0)
// {
// spinnerCategory.setError("Please Enter mPIN ");
// mPin.requestFocus();
// }
// else
// if(notes.trim().length()==0)
// {
// etNotes.setError("Please Add Your Notes ");
// etNotes.setText(null);
// etNotes.requestFocus();
// }
if(dbStatement.updatePassbook(transId, selectedCategory, notes))
{
Toast.makeText(getApplicationContext(), "Data Updated Successfully", Toast.LENGTH_LONG).show();
// Toast.makeText(getApplicationContext(), "selectedCategory : " + selectedCategory, Toast.LENGTH_LONG).show();
// Toast.makeText(getApplicationContext(), "notes : " + notes, Toast.LENGTH_LONG).show();
}
}
catch(Exception e)
{
tc.WriteToTransactionLog("Exception: OfflinePBDetails.java Save.setOnClickListener():- "+e.toString());
}
}
});
dbGetCategoryList();
btnSave.setEnabled(false);
}
catch(Exception e)
{
tc.WriteToTransactionLog("Exception: OfflinePBDetails.java onCreate():- "+e.toString());
}
}
public void dbGetCategoryList()
{
int element;
try
{
Cursor rs = dbCMaster.getData();
countDBRows = rs.getCount();
countDBColumns = rs.getColumnCount();
tableCategory = new String[countDBRows][countDBColumns];
rs.moveToFirst();
for(element = 0; element < countDBRows; element++)
{
tableCategory[element][0] = rs.getString(0); // subCategory
tableCategory[element][1] = rs.getString(1); // Category
tableCategory[element][2] = rs.getString(2); // transType
rs.moveToNext();
// String finalData = tableCategory[element][0]+ " " + tableCategory[element][1]
// + " " + tableCategory[element][2];
// Toast.makeText(getApplicationContext(), "finalData : " + finalData, Toast.LENGTH_SHORT).show();
}
rs.close();
showCategoryList();
}
catch(Exception e)
{
tc.WriteToTransactionLog("Exception: OfflinePBDetails.java dbGetCategoryList():- "+e.toString());
}
}
public void showCategoryList()
{
int i = 0;
int j = 0;
int element;
String transType;
categoryIncome = new ArrayList<String>();
categoryExpense = new ArrayList<String>();
// categoryIncome = new String[2];
// categoryExpense = new String[3];
try
{
for(element = 0; element < countDBRows; element++)
{
transType = tableCategory[element][2];
// Toast.makeText(getApplicationContext(), "transType : " + transType, Toast.LENGTH_SHORT).show();
// Toast.makeText(getApplicationContext(), "passDebitCreditIndicator : " + passDebitCreditIndicator, Toast.LENGTH_SHORT).show();
if(passDebitCreditIndicator.equalsIgnoreCase("D"))
{
if(passDebitCreditIndicator.equalsIgnoreCase(transType))
{
if(tableCategory[element][0].equalsIgnoreCase("Others-E"))
{
categoryExpense.add("Others");
}
else
{
categoryExpense.add(tableCategory[element][0]);
}
// Toast.makeText(getApplicationContext(), "categoryExpense : " + categoryExpense, Toast.LENGTH_SHORT).show();
i++;
}
}
else
{
if(passDebitCreditIndicator.equalsIgnoreCase(transType))
{
if(tableCategory[element][0].equalsIgnoreCase("Others-I"))
{
categoryIncome.add("Others");
}
else
{
categoryIncome.add(tableCategory[element][0]);
}
// Toast.makeText(getApplicationContext(), "categoryIncome : " + categoryIncome, Toast.LENGTH_SHORT).show();
j++;
}
}
}
if(passDebitCreditIndicator.equalsIgnoreCase("D"))
{
adapterSelect = new ArrayAdapter<String>(this, R.layout.spinner_pb_details,categoryExpense);
// adapterSelect = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, categoryExpense);
}
else
{
adapterSelect = new ArrayAdapter<String>(this, R.layout.spinner_pb_details,categoryIncome);
// adapterSelect = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, categoryIncome);
}
adapterSelect.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerCategory.setAdapter(adapterSelect);
spinnerCategory.setOnItemSelectedListener(this);
checkDBData();
if(dbSubCategory.equalsIgnoreCase("Others-E") || dbSubCategory.equalsIgnoreCase("Others-I"))
{
dbSubCategory = "Others";
}
ArrayAdapter myAdap = (ArrayAdapter) spinnerCategory.getAdapter(); //cast to an ArrayAdapter
int spinnerPosition = myAdap.getPosition(dbSubCategory);
//set the default according to value
spinnerCategory.setSelection(spinnerPosition);
etNotes.setText(dbNotes);
// to disable save button after notes is filled with note from db and item is selected from item listner
}
catch(Exception e)
{
tc.WriteToTransactionLog("Exception: OfflinePBDetails.java showCategoryList():- "+e.toString());
}
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
// try
// {
spinnerCategory.setSelection(position);
selectedCategory = (String) spinnerCategory.getSelectedItem();
if(passDebitCreditIndicator.equalsIgnoreCase("D"))
{
if(selectedCategory.equalsIgnoreCase("Others"))
{
selectedCategory = "Others-E";
}
// else
// {
// selectedCategory = selectedCategory;
// }
// Toast.makeText(getApplicationContext(), "selectedCategory : " + selectedCategory, Toast.LENGTH_SHORT).show();
}
else
{
if(selectedCategory.equalsIgnoreCase("Others"))
{
selectedCategory = "Others-I";
}
// else
// {
// selectedCategory = (String) spinnerCategory.getSelectedItem();
// }
// Toast.makeText(getApplicationContext(), "selectedCategory : " + selectedCategory, Toast.LENGTH_SHORT).show();
}
btnSave.setEnabled(true);
// switch (position) {
// case 0:
// // Whatever you want to happen when the first item gets selected
// break;
// case 1:
// // Whatever you want to happen when the second item gets selected
// break;
// case 2:
// // Whatever you want to happen when the thrid item gets selected
// break;}
// }
// catch(Exception e)
// {
// Toast.makeText(getApplicationContext(), "Exception onItemSelected : " + e, Toast.LENGTH_SHORT).show();
// }
}
public void checkDBData()
{
try
{
int element;
Cursor rs = dbStatement.getCategory(passTransId);
// int countCategoryRow = rs.getCount();
// int countCategoryColumn = rs.getColumnCount();
rs.moveToFirst();
dbSubCategory = rs.getString(13);
dbNotes = rs.getString(14);
rs.moveToNext();
// String reducedNotes = dbNotes.replace("\n", "").replace("\r", "");
//// String str =dbNotes.substring(0, 3);
// Toast.makeText(getApplicationContext(), "reducedNotes : " + reducedNotes, Toast.LENGTH_SHORT).show();
}
catch(Exception e)
{
tc.WriteToTransactionLog("Exception: OfflinePBDetails.java checkDBData():- "+e.toString());
}
}
#Override
public void onNothingSelected(AdapterView<?> parent)
{
// TODO Auto-generated method stub
}
public void readConfigFileDetails()
{
try
{
properties_config= new Properties();
FileInputStream fis2 = new FileInputStream(file_Path + "config.properties");
properties_config.load(fis2);
sessionTimeout = Long.parseLong(properties_config.getProperty("session_timeout"));
fis2.close();
}
catch(Exception e)
{
e.printStackTrace();
tc.WriteToTransactionLog("Exception: OfflinePBDetails.java readConfigFileDetails():- "+e.toString());
}
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if ( keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0)
{
onBackPressed();
}
return super.onKeyDown(keyCode, event);
}
#Override
public void onBackPressed()
{
return;
}
public void onRestart()
{
finish();
super.onRestart();
startActivity(new Intent(this, Welcome.class).addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
finish();
}
private Handler disconnectHandler = new Handler(){
public void handleMessage(Message msg)
{
}
};
private Runnable disconnectCallback = new Runnable()
{
#Override
public void run()
{
Toast.makeText(getApplicationContext(), "Session Expired", Toast.LENGTH_LONG).show();
System.out.println("Session Expired");
Intent intent = new Intent(getApplicationContext(),Welcome.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
}
};
public void resetDisconnectTimer()
{
disconnectHandler.removeCallbacks(disconnectCallback);
disconnectHandler.postDelayed(disconnectCallback, sessionTimeout);
}
public void stopDisconnectTimer()
{
disconnectHandler.removeCallbacks(disconnectCallback);
}
#Override
public void onUserInteraction()
{
resetDisconnectTimer();
}
#Override
public void onResume()
{
super.onResume();
resetDisconnectTimer();
}
#Override
public void onStop()
{
super.onStop();
stopDisconnectTimer();
}
}
Here is my .xml file :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/bbk_base_all"
android:focusable="true"
android:focusableInTouchMode="true"
android:paddingRight="3dp" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignTop="#+id/txtwelcome" />
<TableLayout
android:id="#+id/tableLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginTop="130dp"
android:gravity="center" >
<TableRow
android:layout_width="wrap_content"
android:layout_height="30dp"
android:background="#drawable/buttonborder"
android:paddingTop="10dp" >
<TextView
android:id="#+id/tv_titleDate"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:gravity="left"
android:paddingLeft="25dp"
android:text="Transaction Date"
android:textColor="#FFFFFF"
android:textSize="15sp"
android:textStyle="bold|italic" />
<TextView
android:id="#+id/tv_getDate"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:gravity="left"
android:paddingBottom="5dp"
android:paddingLeft="30dp"
android:text="Date"
android:textColor="#FFFFFF"
android:textSize="15sp" />
</TableRow>
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/buttonborder"
android:paddingTop="10dp" >
<TextView
android:id="#+id/tv_titleParticulars"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:paddingLeft="25dp"
android:text="Particulars"
android:textColor="#FFFFFF"
android:textSize="15sp"
android:textStyle="bold|italic" />
<TextView
android:id="#+id/tv_getParticular"
android:layout_width="30dp"
android:layout_height="wrap_content"
android:ems="50"
android:gravity="left"
android:maxLines="4"
android:paddingLeft="30dp"
android:text="Particulars"
android:textColor="#FFFFFF"
android:textSize="15sp" />
</TableRow>
<TableRow
android:layout_width="250dp"
android:layout_height="30dp"
android:background="#drawable/buttonborder"
android:paddingTop="10dp" >
<TextView
android:id="#+id/tv_titleAmount"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:gravity="left"
android:paddingLeft="25dp"
android:text="Amount"
android:textColor="#FFFFFF"
android:textSize="15sp"
android:textStyle="bold|italic" />
<TextView
android:id="#+id/tv_getAmount"
android:layout_width="125dp"
android:layout_height="wrap_content"
android:gravity="left"
android:paddingLeft="30dp"
android:text="Amount"
android:textColor="#FFFFFF"
android:textSize="15sp" />
</TableRow>
<TableRow
android:layout_width="250dp"
android:layout_height="30dp"
android:background="#drawable/buttonborder"
android:paddingTop="10dp" >
<TextView
android:id="#+id/tv_titleBalance"
android:layout_width="150dp"
android:layout_height="25dp"
android:gravity="left"
android:paddingLeft="25dp"
android:text="Balance Amount"
android:textColor="#FFFFFF"
android:textSize="15sp"
android:textStyle="bold|italic" />
<TextView
android:id="#+id/tv_getBalance"
android:layout_width="125dp"
android:layout_height="25dp"
android:gravity="left"
android:paddingLeft="30dp"
android:text="Balance"
android:textColor="#FFFFFF"
android:textSize="15sp" />
</TableRow>
<TableRow
android:layout_width="250dp"
android:layout_height="wrap_content"
android:background="#drawable/buttonborder"
android:paddingTop="10dp" >
<TextView
android:id="#+id/tv_titleCategory"
android:layout_width="150dp"
android:layout_height="25dp"
android:gravity="center_vertical"
android:paddingLeft="25dp"
android:text="Select Category"
android:textColor="#FFFFFF"
android:textSize="15sp"
android:textStyle="bold|italic" />
<Spinner
android:id="#+id/spn_selectCategory"
android:layout_width="125dp"
android:layout_height="wrap_content"
android:gravity="left"
android:paddingLeft="30dp"
android:textColor="#FFFFFF" />
</TableRow>
<TableRow
android:layout_width="250dp"
android:layout_height="wrap_content"
android:background="#drawable/buttonborder"
android:paddingTop="10dp" >
<TextView
android:id="#+id/tv_titleNotes"
android:layout_width="150dp"
android:layout_height="25dp"
android:gravity="center_vertical"
android:paddingLeft="25dp"
android:text="Notes"
android:textColor="#FFFFFF"
android:textSize="15sp"
android:textStyle="bold|italic" />
<EditText
android:id="#+id/et_getNotes"
android:layout_width="30dp"
android:layout_height="wrap_content"
android:layout_below="#+id/tableLayout1"
android:layout_toLeftOf="#+id/imageView1"
android:hint="Add Your Own Notes"
android:maxLines="3"
android:paddingLeft="30dp"
android:textColor="#FFFFFF" >
</EditText>
</TableRow>
</TableLayout>
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/imageView1"
android:layout_centerHorizontal="true"
android:layout_marginTop="70dp"
android:gravity="center"
android:text="Transaction Details"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#FFFFFF"
android:textSize="24dp"
android:textStyle="bold|italic" />
<Button
android:id="#+id/btnSave"
android:layout_width="110dp"
android:layout_height="30dp"
android:layout_alignParentLeft="true"
android:layout_below="#+id/tableLayout1"
android:layout_marginLeft="20dp"
android:layout_marginTop="30dp"
android:background="#drawable/normalbuttonborder"
android:text="Save"
android:textSize="16sp"
android:textStyle="bold"
android:enabled="false" />
<Button
android:id="#+id/btnBack"
android:layout_width="110dp"
android:layout_height="30dp"
android:layout_alignBaseline="#+id/btnSave"
android:layout_alignBottom="#+id/btnSave"
android:layout_marginRight="20dp"
android:layout_toLeftOf="#+id/imageView1"
android:background="#drawable/normalbuttonborder"
android:text="Back"
android:textSize="16sp"
android:textStyle="bold" />
</RelativeLayout>
Please help me.

Initially disable that Button after findViewById like this
btnSave = (Button)findViewById(R.id.btnSave);
btnSave.setEnabled(false);
The problem is you have Spinner where u enabling that Button. By default 1st item of Spinner is selected automatically and it is call in onCreate(...) and your Button gets enabled what you can do
Change logic of enabling that Button in Spinner's OnItemSelected(...) check if previously selected value and currently selected value is equal and EditText's value has not been changed then disable that Button otherwise enable that Button. Use boolean flag for this work.

You didnt disable your button before enabling it.
disble your button after declaring it.
btnSave.setEnabled(false);
Then enable it in your textChanged method

Since you want to disable your button use:
btnSave.setEnabled(false);
or try setting:
btnSave.setClickable(false);
along with setEnabled(false)
Alternatively, use below line in your xml:
android:clickable = "false"
android:enabled = "false"
and whenever user is done with note editing (i.e after selecting spinner item ) enable both(enabled & clickable) on btnSave according to your logic i.e use:
btnSave.setClickable(true);
btnSave.setEnabled(true);

Related

Search In Json Functionality

So, I get some data from a nutrition database and I want to add a search option. I'm new to Android Studio so some advice would help me.
This is the app:
This edittext should search in the database and show after the name of products. Is there an easier way to make this work?
This is the activity layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".NutritionDatabase">
<EditText
android:id="#+id/et_dataInput"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Search Database"
android:inputType="textPersonName"
android:layout_marginTop="-58dp"
app:layout_constraintTop_toTopOf="#id/list"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="123dp"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="0dp" />
<RelativeLayout
android:id="#+id/relativeLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="411dp"
android:layout_height="wrap_content"
android:background="#000000" />
<ImageView
android:id="#+id/back_to_home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="40dp"
android:minHeight="45dp"
android:paddingTop="15dp"
android:src="#drawable/ic_back" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:text="Nutrition Database"
android:textAlignment="center"
android:textColor="#FFFFFFFF"
android:textSize="20sp"
android:textStyle="bold" />
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
This is the java class:
package com.example.myapplication;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
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 org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
public class NutritionDatabase extends AppCompatActivity {
EditText et_dataInput;
private String TAG = MainActivity.class.getSimpleName();
private ListView lv;
ArrayList<HashMap<String, String>> resultList;
#Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case android.R.id.home:
finish();
break;
}
return true;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nutrition_database);
et_dataInput=findViewById(R.id.et_dataInput);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if (getSupportActionBar() != null){
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
resultList = new ArrayList<>();
lv = (ListView) findViewById(R.id.list);
new GetContacts().execute();
}
private class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(NutritionDatabase.this,"Json Data is downloading",Toast.LENGTH_LONG).show();
}
#Override
protected Void doInBackground(Void... arg0) {
HttpHandler sh = new HttpHandler();
// Making a request to url and getting response
String url = "https://wger.de/api/v2/ingredient/?language=2&limit=11865";
String jsonStr = sh.makeServiceCall(url);
Log.e(TAG, "Response from url: " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
JSONArray results = jsonObj.getJSONArray("results");
// looping through All Contacts
for (int i = 0; i < results.length(); i++) {
JSONObject c = results.getJSONObject(i);
String name = c.getString("name");
String fat = c.getString("fat");
String protein = c.getString("protein");
String energy = c.getString("energy");
String carbohydrates = c.getString("carbohydrates");
String carbohydrates_sugar = c.getString("carbohydrates_sugar");
String fat_saturated = c.getString("fat_saturated");
String fibres = c.getString("fibres");
String sodium = c.getString("sodium");
// tmp hash map for single contact
HashMap<String, String> result = new HashMap<>();
// adding each child node to HashMap key => value
result.put("name","Name :"+ name);
result.put("fat","Fat :"+ fat);
result.put("protein","Protein :"+ protein);
result.put("energy","Energy :"+ energy);
result.put("carbohydrates","Carbohydrates :"+ carbohydrates);
result.put("carbohydrates_sugar","Carbohydrates from sugar :"+ carbohydrates_sugar);
result.put("fat_saturated","Saturated Fat:"+ fat_saturated);
result.put("fibres","Fibres :"+ fibres);
result.put("sodium","Sodium :"+ sodium);
// adding contact to contact list
resultList.add(result);
}
} catch (final JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Json parsing error: " + e.getMessage(),Toast.LENGTH_LONG).show();
}
});
}
} else {
Log.e(TAG, "Couldn't get json from server.");
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Couldn't get json from server. Check LogCat for possible errors!",
Toast.LENGTH_LONG).show();
}
});
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
ListAdapter adapter = new SimpleAdapter(NutritionDatabase.this, resultList,
R.layout.list_item_nutrition, new String[]{ "name","fat","energy","protein","carbohydrates","carbohydrates_sugar","fat_saturated","fibres","sodium"},
new int[]{R.id.name, R.id.fat,R.id.protein,R.id.energy,R.id.carbohydrates,R.id.carbohidrates_sugar,R.id.fat_saturated,R.id.fibres,R.id.sodium});
lv.setAdapter(adapter);
}
}
}
This is the list that I use :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="#dimen/activity_horizontal_margin">
<TextView
android:paddingTop="10dp"
android:id="#+id/name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#color/colorAccent"
android:text="Name:"/>
<TextView
android:id="#+id/energy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#5d5d5d"
android:textStyle="bold"
android:paddingTop="10dp"
android:text="Energy:"
/>
<TextView
android:id="#+id/protein"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#5d5d5d"
android:textStyle="bold"
android:text="Protein:"
/>
<TextView
android:id="#+id/carbohydrates"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#5d5d5d"
android:textStyle="bold"
android:text="Carbohydrates:"
/>
<TextView
android:id="#+id/carbohidrates_sugar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#5d5d5d"
android:textStyle="bold"
android:text="Carbohydrates from sugar:"
/>
<TextView
android:id="#+id/fat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#5d5d5d"
android:textStyle="bold"
android:text="Fat:"
/>
<TextView
android:id="#+id/fat_saturated"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#5d5d5d"
android:textStyle="bold"
android:text="Saturated Fat:"
/>
<TextView
android:id="#+id/fibres"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#5d5d5d"
android:textStyle="bold"
android:text="Fibres:"
/>
<TextView
android:id="#+id/sodium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#5d5d5d"
android:textStyle="bold"
android:text="Sodium:"
/>
</LinearLayout>
Implements NutritionDatabase activity with Filterable class and implements Filterable class method in your NutritionDatabase activity.
#Override
public Filter getFilter() {
return myFilter;
}
Filter myFilter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
ArrayList<String> tempList = new ArrayList<String>();
//constraint is the result from text you want to filter against.
//objects is your data set you will filter from
if (constraint != null && your_list != null) {
int length = your_list.size();
int i = 0;
while (i < length) {
String item = your_list.get(i);
//do whatever you wanna do here
//adding result set output array
tempList.add(item);
i++;
}
//following two lines is very important
//as publish result can only take FilterResults objects
filterResults.values = tempList;
filterResults.count = tempList.size();
}
return filterResults;
}
#Override
protected void publishResults(CharSequence contraint, FilterResults results) {
your_list = (ArrayList<String>) results.values;
if (results.count > 0) {
your_adapter.notifyDataSetChanged();
} else {
}
}
};
Implement your search edittext like
et_dataInput.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
String text = et_dataInput.getText().toString());
your_adapter.getFilter().filter(text);
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1,
int arg2, int arg3) {
// TODO Auto-generated method stub
}
#Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
});
use this code for search name from your list.

I am unable to evaluate string using eval()

I am trying to make a calculator application.I want to evaluate the contents of a TextView and display it as a toast message. The eval() statement throws an exception for ScriptException as below.
"Unhandled exception: javax.script.ScriptException"
Even when I have imported javax.script.ScriptException. I am not getting from why it is throwing exception.
Here is my xml code:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="0dp">
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_marginTop="95dp"
android:textAlignment="center"
android:textSize="36sp" />
<Button
android:id="#+id/n1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="18dp"
android:layout_marginTop="194dp"
android:text="1" />
<Button
android:id="#+id/n2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/n1"
android:layout_centerHorizontal="true"
android:text="2" />
<Button
android:id="#+id/n3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignTop="#+id/n1"
android:layout_marginEnd="16dp"
android:text="3" />
<Button
android:id="#+id/n4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="#+id/n1"
android:layout_centerVertical="true"
android:text="4" />
<Button
android:id="#+id/n5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="5" />
<Button
android:id="#+id/n6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="#+id/n3"
android:layout_centerVertical="true"
android:text="6" />
<Button
android:id="#+id/n7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignStart="#+id/n1"
android:layout_marginBottom="194dp"
android:text="7" />
<Button
android:id="#+id/n8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/n7"
android:layout_centerHorizontal="true"
android:text="8" />
<Button
android:id="#+id/n9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="#+id/n3"
android:layout_alignTop="#+id/n7"
android:text="9" />
<Button
android:id="#+id/n0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="129dp"
android:text="0" />
<Button
android:id="#+id/clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="#+id/n3"
android:layout_alignTop="#+id/n0"
android:text="CLEAR" />
<Button
android:id="#+id/plus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="73dp"
android:text="+" />
<Button
android:id="#+id/equal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="#+id/n3"
android:layout_alignTop="#+id/plus"
android:text="=" />
</RelativeLayout>
</android.support.constraint.ConstraintLayout>
and here is my java code:
package com.example.poopypigeon.calx;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class MainActivity extends AppCompatActivity {
Button n1;
Button n2;
Button n3;
Button n4;
Button n5;
Button n6;
Button n7;
Button n8;
Button n9;
Button n0;
Button clear;
Button plus;
Button equal;
TextView value;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
value = findViewById(R.id.textView);
n1 = findViewById(R.id.n1);
n1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String val = value.getText().toString();
value.setText(val+"1");
}
});
n2 = findViewById(R.id.n2);
n2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String val = value.getText().toString();
value.setText(val+"2");
}
});
n3 = findViewById(R.id.n3);
n3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String val = value.getText().toString();
value.setText(val+"3");
}
});
n4 = findViewById(R.id.n4);
n4.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String val = value.getText().toString();
value.setText(val+"4");
}
});
n5 = findViewById(R.id.n5);
n5.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String val = value.getText().toString();
value.setText(val+"5");
}
});
n6 = findViewById(R.id.n6);
n6.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String val = value.getText().toString();
value.setText(val+"6");
}
});
n7 = findViewById(R.id.n7);
n7.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String val = value.getText().toString();
value.setText(val+"7");
}
});
n8 = findViewById(R.id.n8);
n8.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String val = value.getText().toString();
value.setText(val+"8");
}
});
n9 = findViewById(R.id.n9);
n9.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String val = value.getText().toString();
value.setText(val+"9");
}
});
n0 = findViewById(R.id.n0);
n0.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String val = value.getText().toString();
value.setText(val+"0");
}
});
clear = findViewById(R.id.clear);
clear.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
value.setText("");
}
});
plus = findViewById(R.id.plus);
plus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String val = value.getText().toString();
value.setText(val + "+");
}
});
equal = findViewById(R.id.equal);
equal.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String val = value.getText().toString();
ScriptEngine engine = new ScriptEngineManager().getEngineByExtension("js");
Object ans = engine.eval(val);
Toast toast = Toast.makeText(MainActivity.this,"the ans is: "+ ans,Toast.LENGTH_SHORT);
toast.show();
}
});
}
}
PS. i need a reply as soon as possible as this is for a school project
I would do it like this to further investigate:
try{
ScriptEngineManager manager = new ScriptEngineManager()
ScriptEngine engine = manager.getEngineByExtension("js");
Object ans = engine.eval(val);
Toast toast = Toast.makeText(MainActivity.this,"the ans is: "+ ans,Toast.LENGTH_SHORT);
toast.show();
catch(ScriptEngineManager e) {
// handle exception
System.err.println("Error making calculation: " + e.getMessage());
}
EDIT: Change:
String val = value.getText().toString();
value.setText(val+"1");
You have only the value in the String val - but you need the content of value textfield. In the String val there has to be something like "4+4".
You just add numbers to the textfield but no operators.
value.setText(val+"1"); -> You just add the Number 1 to the Textfield, so after clicking some Buttons you have like this in your Textfield "512312"
Copy this import statement
import javax.script.ScriptException;
Try is code:
try {
Object ans = engine.eval(val);
System.out.println("It worked!:" + ans.toString());
}
catch (ScriptException se) {
System.out.println("Problem in eval:", se.getmessage());
}
Change ScriptException with Exception
try {
ans = engine.eval(val);
} catch (Exception e) {
e.printStackTrace();
}
You are not sure for which type of exception it may trigger so it will display the same message for all the exceptions and user may not be able to understand which exception occurred. Thats the reason you should place is at the end of all the specific exception catch blocks
To simplify the debugging here, focus on this line:
Object ans = engine.eval(val);
Print the value of val so we can see the source that is being evaluated.
Wrap that line in a try catch block and print the full stack trace so we can see the full error diagnostic.

How to save the old state of a checkbox?

I want to save the old state of checkbox With checkbox I want to update my data in database. When user changes the activity I lose his checked checkbox and when he again comes to that activity then every checkbox is unchecked and when he click to save with new values it will not saved because I set date as primary key in database. If I update the data with new values I lost my old data....
CheckBoxActivity.java
package com.example.shakeelmughal.assanislam;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.preference.PreferenceManager;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.Toast;
import java.text.SimpleDateFormat;
import java.util.Date;
public class NamazCounterActivity extends AppCompatActivity {
DatabaseHelper mydb;
CheckBox cb1,cb2,cb3,cb4,cb5;
Button B1,B2,B3;
int vcb1=0,vcb2=0,vcb3=0,vcb4=0,vcb5=0,vet=0;
Date date = new Date();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_namaz_counter);
mydb = new DatabaseHelper(this);
SharedPreferences settings = getSharedPreferences("mysettings", 0);
SharedPreferences.Editor editor = settings.edit();
cb1 = findViewById(R.id.namaz1);
cb2 = findViewById(R.id.namaz2);
cb3 = findViewById(R.id.namaz3);
cb4 = findViewById(R.id.namaz4);
cb5 = findViewById(R.id.namaz5);
B1 = findViewById(R.id.result);
B2 = (Button) findViewById(R.id.dateee);
B3 = findViewById(R.id.sumr);
c_date();
B1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
InsertingData();
}
});
B3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Cursor cr = mydb.getAllData();
if(cr.getCount() == 0)
{
showData("Error","No Data Found");
return;
}
StringBuffer buffer = new StringBuffer();
while (cr.moveToNext())
{
buffer.append("ID: "+cr.getString(0)+ "\n");
buffer.append("Fajar: "+cr.getString(1)+ "\n");
buffer.append("Zohr: "+cr.getString(2)+ "\n");
buffer.append("Asr: "+cr.getString(3)+ "\n");
buffer.append("Magrib: "+cr.getString(2)+ "\n");
buffer.append("Isha: "+cr.getString(3)+ "\n");
}
showData("Data",buffer.toString());
}
});
//home button
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}}
//function for going back to previous activity
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == android.R.id.home)
finish();
return super.onOptionsItemSelected(item);
}
public void InsertingData()
{
if(cb1.isChecked())
{
vcb1 = 1;
}
else
{
vcb1 = 0;
}
if(cb2.isChecked())
{
vcb2 = 1;
cb2.setChecked(true);
}
else
{
vcb2 = 0;
}
if(cb3.isChecked())
{
vcb3 = 1;
cb3.setChecked(true);
}
else
{
vcb3 = 0;
}
if(cb4.isChecked())
{
vcb4 = 1;
cb4.setChecked(true);
}
else
{
vcb4 = 0;
}
if(cb5.isChecked())
{
vcb5 = 1;
cb5.setChecked(true);
}
else
{
vcb5 = 0;
}
boolean result = mydb.InsertData(B2.getText().toString(),Integer.toString(vcb1),Integer.toString(vcb2),Integer.toString(vcb3),Integer.toString(vcb4),Integer.toString(vcb5));
if(result == true)
{
Toast.makeText(NamazCounterActivity.this, "Prayer Saved",Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(NamazCounterActivity.this, "Some Error", Toast.LENGTH_LONG).show();
}
}
public void Updateingdata()
{
if(cb1.isChecked())
{
vcb1 = 1;
}
else
{
vcb1 = 0;
}
if(cb2.isChecked())
{
vcb2 = 1;
}
else
{
vcb2 = 0;
}
if(cb3.isChecked())
{
vcb3 = 1;
}
else
{
vcb3 = 0;
}
if(cb4.isChecked())
{
vcb4 = 1;
}
else
{
vcb4 = 0;
}
if(cb5.isChecked())
{
vcb5 = 1;
}
else
{
vcb5 = 0;
}
boolean res = mydb.UpdateData(B2.getText().toString(),Integer.toString(vcb1),Integer.toString(vcb2),Integer.toString(vcb3),Integer.toString(vcb4),Integer.toString(vcb5));
if(res == true)
{
Toast.makeText(NamazCounterActivity.this,"Data Updated",Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(NamazCounterActivity.this,"Data Not Updated",Toast.LENGTH_SHORT).show();
}
}
//for date ()
public void c_date()
{
date.setTime(System.currentTimeMillis()); //set to current time
B2.setText(date.toString());
SimpleDateFormat dateFormat = new SimpleDateFormat("EEEEEEEEE, MMM dd, yyyy");
B2.setText(dateFormat.format(date));
}
public void showData(String title, String message)
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(true);
builder.setTitle(title);
builder.setMessage(message);
builder.show();
}
}
Its XML file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.shakeelmughal.assanislam.NamazCounterActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/scrollView2">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<CheckBox
android:id="#+id/namaz1"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="47dp"
android:layout_marginStart="47dp"
android:layout_marginTop="50dp"
android:background="?android:attr/listChoiceIndicatorMultiple"
android:button="#null"
android:theme="#style/forCheckBox" />
<CheckBox
android:id="#+id/namaz2"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignLeft="#+id/namaz1"
android:layout_alignStart="#+id/namaz1"
android:layout_below="#+id/namaz1"
android:layout_marginTop="12dp"
android:button="#null"
android:background="?android:attr/listChoiceIndicatorMultiple"
android:theme="#style/forCheckBox" />
<CheckBox
android:id="#+id/namaz3"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignLeft="#+id/namaz2"
android:layout_alignStart="#+id/namaz2"
android:layout_below="#+id/namaz2"
android:layout_marginTop="19dp"
android:button="#null"
android:background="?android:attr/listChoiceIndicatorMultiple"
android:theme="#style/forCheckBox" />
<CheckBox
android:id="#+id/namaz4"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignLeft="#+id/namaz3"
android:layout_alignStart="#+id/namaz3"
android:layout_below="#+id/namaz3"
android:layout_marginTop="19dp"
android:button="#null"
android:background="?android:attr/listChoiceIndicatorMultiple"
android:theme="#style/forCheckBox" />
<CheckBox
android:id="#+id/namaz5"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignLeft="#+id/namaz4"
android:layout_alignStart="#+id/namaz4"
android:layout_below="#+id/namaz4"
android:layout_marginTop="11dp"
android:button="#null"
android:background="?android:attr/listChoiceIndicatorMultiple"
android:theme="#style/forCheckBox" />
<TextView
android:id="#+id/textView20"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/namaz1"
android:layout_alignBottom="#+id/namaz1"
android:layout_marginLeft="41dp"
android:layout_marginStart="41dp"
android:layout_toEndOf="#+id/result"
android:layout_toRightOf="#+id/result"
android:text="نمازِ فجر"
android:textColor="#000"
android:textSize="20sp" />
<TextView
android:id="#+id/textView21"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="#+id/textView20"
android:layout_alignRight="#+id/textView20"
android:layout_alignTop="#+id/namaz2"
android:layout_marginTop="14dp"
android:text=" نمازِ ظہر / جمعہ"
android:textColor="#000"
android:textSize="20sp" />
<TextView
android:id="#+id/textView22"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="#+id/textView21"
android:layout_alignRight="#+id/textView21"
android:layout_alignTop="#+id/namaz3"
android:layout_marginTop="11dp"
android:text="نمازِ عصر"
android:textColor="#000"
android:textSize="20sp" />
<TextView
android:id="#+id/textView23"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/namaz4"
android:layout_alignBottom="#+id/namaz4"
android:layout_alignEnd="#+id/textView21"
android:layout_alignRight="#+id/textView21"
android:text="نمازِ مغرب"
android:textColor="#000"
android:textSize="20sp" />
<TextView
android:id="#+id/textView24"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="#+id/textView23"
android:layout_alignRight="#+id/textView23"
android:layout_alignTop="#+id/namaz5"
android:layout_marginTop="12dp"
android:text="نمازِ عشاء"
android:textColor="#000"
android:textSize="20sp"/>
<Button
android:id="#+id/result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textView24"
android:layout_centerHorizontal="true"
android:text="Save" />
<Button
android:id="#+id/dateee"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textView20"
android:layout_centerHorizontal="true" />
<Button
android:id="#+id/sumr"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/result"
android:layout_centerHorizontal="true"
android:layout_marginTop="13dp"
android:text="View Summery" />
</RelativeLayout>
</ScrollView>
</RelativeLayout>
There could be many ways to do that, some of them are :
1. By using a File
2. By using shared preferences
I will recommend that latter one, a great implementation could be found by
Save CheckBox State to SharedPreferences File in Android

What should i do to move to another activity when only special conditions are met

I am making a quiz app. I want the exit page to be displayed when the next button is pressed after last question has been answered. I have a activity_questions.xml and a activity_exit.xml. The xml for activity_questions.xml is :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.crystal.questions">
<TextView
android:id="#+id/text3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="29dp"
android:fontFamily="sans-serif-thin"
android:padding="10dp"
android:text=""
android:textColor="#440027"
android:textSize="30dp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<EditText
android:id="#+id/edit2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/text3"
android:layout_margin="30dp"
android:background="#9775AA"
android:hint="Answer"
android:inputType="text"
android:padding="10dp"
android:textSize="20dip" />
<LinearLayout
android:id="#+id/ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/edit2"
android:gravity="center"
android:orientation="horizontal">
<Button
android:id="#+id/answer"
style="#style/Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:layout_weight="1"
android:onClick="onAnswerClick"
android:padding="2dp"
android:text="Okay" />
<Button
style="#style/Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:layout_weight="1"
android:onClick="onHintClick"
android:padding="2dp"
android:text="Hint" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingBottom="5dp"
android:orientation="vertical"
android:layout_marginTop="26dp"
android:layout_below="#+id/ll"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
<ImageView
android:id="#+id/tickcross"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_below="#+id/ll"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:src="#drawable/wierdtick" />
<TextView
android:id="#+id/correctornot"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/tickcross"
android:layout_centerHorizontal="true"
android:layout_marginTop="15dp"
android:text="Correct!"
android:textColor="#440027"
android:textSize="30dp" />
<Button
android:id="#+id/nextbutton"
style="#style/Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="Next"
android:onClick="onNextClick"
/>
</LinearLayout>
</RelativeLayout>
And the java is:
package com.example.android.crystal;
import android.app.Activity;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.Random;
public class questions extends AppCompatActivity {
Random r = new Random();
private boolean done;
private int QuestionNo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_questions);
findViewById(R.id.tickcross).setVisibility(View.INVISIBLE);
findViewById(R.id.correctornot).setVisibility(View.INVISIBLE);
findViewById(R.id.nextbutton).setVisibility(View.INVISIBLE);
String[] questions = getResources().getStringArray(R.array.Questions);
TextView t = (TextView) findViewById(R.id.text3);
t.setText(questions[QuestionNo]);
}
public void onFinishClick(View view){
Intent intent = new Intent(this, exit.class);
startActivity(intent);
}
public static void hideKeyboardFrom(Activity activity) {
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}
public void answersubmitted() {
findViewById(R.id.tickcross).setVisibility(View.VISIBLE);
TranslateAnimation animation = new TranslateAnimation(0, 0, 2000, 0);
animation.setDuration(1000);
animation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
findViewById(R.id.tickcross).startAnimation(animation);
findViewById(R.id.correctornot).setVisibility(View.VISIBLE);
findViewById(R.id.nextbutton).setVisibility(View.VISIBLE);
}
public void onHintClick(View view) {
String[] hints = getResources().getStringArray(R.array.Hints);
Toast toasty = Toast.makeText(getApplicationContext(), hints[QuestionNo], Toast.LENGTH_SHORT);
toasty.show();
}
public void onAnswerClick(View view) {
if (done == false) {
hideKeyboardFrom(this);
String answer = ((EditText) findViewById(R.id.edit2)).getText().toString();
String[] answers = getResources().getStringArray(R.array.Answers);
String correctAnswer = answers[QuestionNo];
correctAnswer = correctAnswer.toUpperCase();
answer = answer.toUpperCase();
if (answer.equals(correctAnswer)) {
TextView t = (TextView) findViewById(R.id.correctornot);
t.setText("CORRECT!");
ImageView i = (ImageView) findViewById(R.id.tickcross);
i.setImageDrawable(getDrawable(R.drawable.wierdtick));
answersubmitted();
} else {
TextView t = (TextView) findViewById(R.id.correctornot);
t.setText("Correct Answer: " + correctAnswer);
ImageView i = (ImageView) findViewById(R.id.tickcross);
i.setImageDrawable(getDrawable(R.drawable.weirdcross));
answersubmitted();
}
done = true;
}
}
public void onNextClick(View view){
if (done){
String[] questions = getResources().getStringArray(R.array.Questions);
if (QuestionNo < (questions.length - 1)) {
QuestionNo += 1;
TextView t = (TextView) findViewById(R.id.text3);
t.setText(questions[QuestionNo]);
findViewById(R.id.tickcross).setVisibility(View.INVISIBLE);
findViewById(R.id.correctornot).setVisibility(View.INVISIBLE);
findViewById(R.id.nextbutton).setVisibility(View.INVISIBLE);
EditText et = (EditText) findViewById(R.id.edit2);
et.setText("");
done = false;
}
else {
onFinishClick();
}
}
}
}
But the onFinishClick() gives an error
Thanks in advance for your help
What should i do to move to another activity when only special conditions are met
Basically, an if-statement and an Intent.
Raw code with no variables added:
if(condition(s)){
Intent i = new Intent(this, TargetActivity.class);
//Put arguments into the intent if you need them...
startActivity(i);
}
You can put it in a thread, in an onClickListener, anywhere and any way you want to execute the code.
As to the error you are receiving, I cannot help you with that until you supply the stacktrace from Logcat
You can do like this:
mNextBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (mQuestionCount < questionList.size()){
// set next question
} else {
// call finish
}
}
});

Validations in SignUp page (Android system)

I'm trying to create a Sign Up page for my Android system. I need to check validations for it like email_id already exists ,password should contain more than eight characters ,mobile number field should contain maximum 10 digits .How can I do it?? This is my code..I use java rest webservices and Mysql database
Sign Up.java
package com.example.locationapp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.http.entity.StringEntity;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
#SuppressWarnings("deprecation")
public class SignUp extends Activity {
EditText et_name, et_email, et_password, et_conf_password, et_number;
Button signup;
private Context context;
private ProgressDialog pDialog;
private CheckInternet checkNet;
private Pattern pattern;
private Matcher matcher;
private String EMAIL_PATTERN, name, email, password, conf_password, number,
toastMessage;
private boolean emailValidity, internet_status;
private final String TAG_RESPONSE_CODE = "resp_code";
ServiceHandle jsonParser = new ServiceHandle();
private String url = "http://172.30.54.89:8080/LocationBasedFramework/SignUp/RegisterUser";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sign_up);
context = SignUp.this;
et_name = (EditText) findViewById(R.id.nameEditText);
et_email = (EditText) findViewById(R.id.emailEditText);
et_password = (EditText) findViewById(R.id.passwordEditText);
et_conf_password = (EditText) findViewById(R.id.conf_passwordEditText);
et_number = (EditText) findViewById(R.id.numberEditText);
signup = (Button) findViewById(R.id.signUpbutton);
checkNet = new CheckInternet();
EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*#"
+ "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
pattern = Pattern.compile(EMAIL_PATTERN);
pDialog = new ProgressDialog(SignUp.this);
pDialog.setMessage("New User...");
signup.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// CheckInternet
name = et_name.getText().toString();
email = et_email.getText().toString();
password = et_password.getText().toString();
conf_password = et_conf_password.getText().toString();
number = et_number.getText().toString();
if (email.equals("")) {
toastMessage = "Email field cannot be empty";
et_email.requestFocus(1);
} else {
emailValidity = validate(email);
if (!emailValidity) {
toastMessage = "Invalid E_mail id";
et_email.setText("");
checkNet.ToastMessage(toastMessage,
getApplicationContext());
System.out.println("onclick 3.5");
et_email.requestFocus(1);
} else {
System.out.println("-------onClick4-------");
if (password.equals("")) {
toastMessage = "Password field cannot be empty";
checkNet.ToastMessage(toastMessage, context);
et_conf_password.setText("");
et_password.requestFocus(1);
} else {
if (conf_password.equals("")) {
toastMessage = "Please confirm your password";
checkNet.ToastMessage(toastMessage, context);
et_conf_password.requestFocus(1);
} else {
if (name.equals("")) {
toastMessage = "Plaese enter your name";
checkNet.ToastMessage(toastMessage, context);
et_name.requestFocus(1);
} else {
if (number.equals("")) {
toastMessage = "Mobile No field cannot be empty";
checkNet.ToastMessage(toastMessage,
context);
et_number.requestFocus(1);
} else {
System.out
.println("-------onClick8-------");
internet_status = checkNet
.isInternetOn(context);
if (internet_status == true) {
System.out
.println("-------onClick9-------");
new CreateUser().execute();
} else {
System.out
.println("-------onClick10-------");
checkNet.ifNoInternet(context);
}
}
}
}
}
}
}
}
});
}
public boolean validate(String email) {
CharSequence hex = null;
matcher = pattern.matcher(email);
return matcher.matches();
}
class CreateUser extends AsyncTask<String, String, String> {
StringEntity se = null;
JSONObject json;
String jsonStr = "";
Boolean failure = false;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog.show();
}
protected String doInBackground(String... params) {
try {
json = new JSONObject();
json.put("name", name);
json.put("email_id", email);
json.put("password", password);
json.put("mob_num", number);
se = new StringEntity(json.toString());
System.out.println("--after se--");
String method = "post";
// int response_flag = 1;
ServiceHandle sh = new ServiceHandle();
internet_status = checkNet
.isInternetOn(getApplicationContext());
System.out.println("--internet--" + internet_status);
if (internet_status == true) {
jsonStr = sh.makeServiceCall(url, method, se);
} else {
checkNet.ifNoInternet(context);
}
if (jsonStr != null) {
json = new JSONObject(jsonStr);
int resp_code = json.getInt(TAG_RESPONSE_CODE);
if (resp_code == 0) {
name = json.getString("TAG_Name");
email = json.getString("TAG_Email");
password = json.getString("TAG_Password");
conf_password = json.getString("TAG_confPassword");
number = json.getString("TAG_Number");
}
} else {
;
}
}
catch (Exception e) {
}
return null;
}
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
pDialog.cancel();
int response_flag = 0;
if (response_flag == 0) {
int resp_code = 0;
if (resp_code == 0) {
SharedPreferences pref = getApplicationContext()
.getSharedPreferences("userData", MODE_PRIVATE);
Editor editor = pref.edit();
editor.clear();
editor.commit();
editor.putString("name", name);
editor.putString("e_mail", email);
editor.putString("password", password);
editor.putString("conf_password", conf_password);
editor.putString("number", number);
editor.commit();
Intent intent = new Intent(SignUp.this, ViewMap.class);
startActivity(intent);
finish();
}
}
} catch (Exception e) {
}
}
}
}
This is the xml for SignUp.java .
activity_sign_up.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.locationapp.SignUp" >
<TextView
android:id="#+id/NametextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:gravity="center"
android:text="Name"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/emailtextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:gravity="center"
android:text="Email-id"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/passwordtextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="150dp"
android:gravity="center"
android:text="Password"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/conf_passwordtextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="200dp"
android:gravity="center"
android:text="Confirm Password"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/numbertextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="250dp"
android:gravity="center"
android:text="Mobile"
android:textAppearance="?android:attr/textAppearanceLarge" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent" />
<EditText
android:id="#+id/nameEditText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/NametextView"
android:layout_alignBottom="#+id/NametextView"
android:layout_alignParentRight="true"
android:layout_toRightOf="#+id/passwordtextView"
android:background="#FFFFFF"
android:ems="10" />
<EditText
android:id="#+id/emailEditText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/emailtextView"
android:layout_alignBottom="#+id/emailtextView"
android:layout_alignParentRight="true"
android:layout_toRightOf="#+id/passwordtextView"
android:background="#FFFFFF"
android:ems="10" />
<EditText
android:id="#+id/passwordEditText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/passwordtextView"
android:layout_alignBottom="#+id/passwordtextView"
android:layout_alignParentRight="true"
android:layout_toRightOf="#+id/passwordtextView"
android:background="#FFFFFF"
android:ems="10"
android:inputType="textPassword" />
<EditText
android:id="#+id/conf_passwordEditText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/conf_passwordtextView"
android:layout_alignBottom="#+id/passwordtextView"
android:layout_alignParentRight="true"
android:layout_toRightOf="#+id/conf_passwordtextView"
android:background="#FFFFFF"
android:ems="10"
android:inputType="textPassword"/>
<EditText
android:id="#+id/numberEditText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/numbertextView"
android:layout_alignBottom="#+id/numbertextView"
android:layout_alignParentRight="true"
android:layout_toRightOf="#+id/passwordtextView"
android:background="#FFFFFF"
android:ems="10"
android:inputType="number" />
<Button
android:id="#+id/signUpbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/numbertextView"
android:layout_marginTop="34dp"
android:layout_toRightOf="#+id/emailtextView"
android:gravity="center"
android:text="SIGNUP" />
</RelativeLayout>
To check validations for it like email_id already exists
...Manage it form server
password should contain more than eight characters ,mobile number field should contain maximum 10 digits
Just pass password to following given mathod
private boolean isValidEmail(String email) {
String EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*#"
+ "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
Pattern pattern = Pattern.compile(EMAIL_PATTERN);
Matcher matcher = pattern.matcher(email);
return matcher.matches();
}

Categories

Resources