checkbox validation by clicking button - Android Software Development

Hi to all,
I am new to android, I got problem with checkbox validation in android. When i click a button i should able to validate the checkbox, if it is checked i have to start new activity, if it is not checked i have to display error message as checkbox not checked.
Following is my code:
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListe ner;
public class PreferenceMain extends Activity implements OnCheckedChangeListener {
CheckBox c1;
Context ctxt;
Button prefBtn;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
c1 = (CheckBox) findViewById(R.id.check1);
prefBtn = (Button) findViewById(R.id.button);
prefBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Log.d("Debug", "Button Clicked");
perform();
}
});
}
public void perform(){
if (c1.isChecked()){
Intent result = new Intent(getBaseContext(), Result.class);
startActivity(result);
}
else
//Should display alert to check the check box
}
}
Please help me, I am vexed with this issue almost for four days....
Thanks in advance
Regards,
Ugandhar

Don't use getBaseContext(), use 'this'. Your activity is a Context.

Related

[Q] Help Just getting the hour into a variable

I just need to get the current hour so right now its 2:07 i just want to get the 2 and set the text to a text view. heres my current code but it keeps force closing -_-
Code:
import java.util.Calendar;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class main extends Activity {
Calendar dateAndTime = Calendar.getInstance();
private TextView timeHour;
private int hour;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
timeHour = (TextView) findViewById(R.id.textView1);
hour = dateAndTime.get(Calendar.HOUR);
timeHour.setText(hour);
}
}
SetText() requires a string. You're passing an int. Try:
Code:
timeHour.setText( String.valueOf(hour));
That worked!
Thank you that worked very well

Help me in web service access

THIS IS MY CLIENT SIDE ANDROID APP
package com.example.project10;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.StrictMode;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.SoapFault;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.AndroidHttpTransport;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity {
private static final String SOAP_ACTION = "http://Sample/customerData";
private static final String METHOD_NAME = "customerData";
private static final String NAMESPACE = "http://Sample";
private static final String URL = "http://192.168.1.16:8080/Project10/services/Main?wsdl";
private Thread thread;
public TextView tv;
String resultArr;
public String str;
private Handler handler = new Handler();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv =(TextView)findViewById(R.id.textView1);
Thread networkThread = new Thread() {
@override
public void run() {
try {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(request);
HttpTransportSE ht = new HttpTransportSE(URL);
ht.call(SOAP_ACTION, envelope);
final SoapObject result=(SoapObject) envelope.bodyIn;
if(result!= null){
System.out.println("Response");
System.out.println("..."+result.toString());
}
str = result.toString();
System.out.println(str);
runOnUiThread (new Runnable(){
public void run() {
TextView tv;
tv = (TextView)findViewById(R.id.textView1);//Text view id is textView1
tv.setText(str);
}
});
}
catch (Exception e) {
e.printStackTrace();
}
}
};
networkThread.start();
}
WEB SERVICE code:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.apache.http.HttpEntity;
import org.apache.http.util.EntityUtils;
import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader.Array;
public class SampleMain {
public String customerData(){
String customerInfo = "";
String first="";
int a=12;
StringBuffer sb = new StringBuffer();
try{
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection con = DriverManager.getConnection("jdbc:sqlserver://D9-2-PC:1433;user=sa;password=123;database=ADB");
Statement sta = con.createStatement();
String Sql = "select * from [app] where postname='name'";
ResultSet result = sta.executeQuery(Sql);
System.out.println(result);
while(result.next()){
String id = result.getString("post_id");
String firstName = result.getString("postname");
String lastName = result.getString("comments");
sb.append("ID: " + id + ", First Name: " + firstName
customerInfo = customerInfo + result.getString("appname");
System.out.println("First: " + customerInfo);
}
}
catch(Exception exc){
System.out.println(exc.getMessage());
}
first=customerInfo;
System.out.println(customerInfo);
System.out.println(sb.toString());
return sb.toString();
}
I AM GETTING THIS "anytype{}" in emulator
help me
Could you please put it into
Code:
tags? That makes it much easier to read. :)
thank you for replay,
now i changed my post.
please replay me , i need your help to solve this help me

[Q] how to display the selected value of listview in the textview?

dear all,
Greetings from Rony.
this is my first Query as i newly joined this forum. & quite impressed by the great work being done here, and quite intelligent and experienced persons here about everything in Android.
I am working with Eclipse & my 2 queries are as follows.
1 > how to display the selected value of listview in the textview as shown in "pix 1" ( attached)
i am attaching an image "pix 1" , a drawing representation what exactly i want to ask.
i am adding my code too for the reference.
---------------------------------------------------------------------------------
2> how to open a new tabpager when the confirm button is click? as shown in "pix 2" (attached)
i am putting here my same code for the reference.
---------------------------------------------------------------------------------
please some one can figure out where i am going wrong about my code or any method i have adopted wrong.
Thanks in advance..
-Rony
------------------------------------------
FOLLOWING IS MY CODE
------------------------------------------
// This is my ListView Fragment
package com.example.tabs;
import java.io.FileOutputStream;
import java.io.IOException;
import java.iutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import com.example.tabs.R.color;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
public class ShopFragment extends Fragment implements View.OnClickListener{
//private int mActivatedPosition = ListView.INVALID_POSITION;
ListView LV;
ArrayList<String> arraylist;
Button confirm;
private String[] Shops = new String [] {
"A shop",
"B shop",
"C shop",
"D shop",
"E shop",
"M shop",
"N shop",
"O shop",
"P shop",
"Q shop",
"R shop",
"S shop",
"T shop",
"U shop",
"V shop",
"W shop",
"X shop",
"Y shop",
"S shop",
"F shop",
"G shop",
"H shop",
"I shop",
"Z shop",
"K shop",
"L shop"
};
@override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(false);
View rootView = inflater.inflate(R.layout.listview_fragment, container, false);
LV = (ListView)rootView.findViewById(R.id.listView1);
LV.setFocusableInTouchMode(true);
LV.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
//LV.setSelection(1);
ArrayAdapter<String> adapter;
arraylist = new ArrayList<String>();
for(int i=0;i<Shops.length;i++){
arraylist.add(Shops);
Arrays.sort(Shops);
}
adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_activated_1,
android.R.id.text1, Shops);
LV.setFastScrollEnabled(true);
LV.setAdapter(adapter);
LV.setOnItemClickListener(new OnItemClickListener() {
@override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
LV.setItemChecked(position, true);
setHasOptionsMenu(true);
}
});
return rootView;
}
@override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.activity_next, menu);
super.onCreateOptionsMenu(menu,inflater);
// MenuItem item = menu.findItem(R.id.next);
//item.setVisible(false);
}
@override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.next:
// confirm action
Confirm();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/**
* Launching new activity
* */
private void Confirm() {
setHasOptionsMenu(true);
}
@override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
/////////////////////////////////////////
this is the second fragment where the selected listview item to be called
package com.example.tabs;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class ListFragment extends Fragment {
private TextView txt1;
@override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.list_fragment, container, false);
setHasOptionsMenu(true);
txt1 = (TextView)rootView.findViewById(R.id.textView1);
return rootView;
}
}
no reply yet.. please help me..!
rony dcosta said:
dear all,
Greetings from Rony.
this is my first Query as i newly joined this forum. & quite impressed by the great work being done here, and quite intelligent and experienced persons here about everything in Android.
I am working with Eclipse & my 2 queries are as follows.
1 > how to display the selected value of listview in the textview as shown in "pix 1" ( attached)
i am attaching an image "pix 1" , a drawing representation what exactly i want to ask.
i am adding my code too for the reference.
---------------------------------------------------------------------------------
2> how to open a new tabpager when the confirm button is click? as shown in "pix 2" (attached)
i am putting here my same code for the reference.
---------------------------------------------------------------------------------
please some one can figure out where i am going wrong about my code or any method i have adopted wrong.
Thanks in advance..
-Rony
------------------------------------------
FOLLOWING IS MY CODE
------------------------------------------
// This is my ListView Fragment
package com.example.tabs;
import java.io.FileOutputStream;
import java.io.IOException;
import java.iutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import com.example.tabs.R.color;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
public class ShopFragment extends Fragment implements View.OnClickListener{
//private int mActivatedPosition = ListView.INVALID_POSITION;
ListView LV;
ArrayList<String> arraylist;
Button confirm;
private String[] Shops = new String [] {
"A shop",
"B shop",
"C shop",
"D shop",
"E shop",
"M shop",
"N shop",
"O shop",
"P shop",
"Q shop",
"R shop",
"S shop",
"T shop",
"U shop",
"V shop",
"W shop",
"X shop",
"Y shop",
"S shop",
"F shop",
"G shop",
"H shop",
"I shop",
"Z shop",
"K shop",
"L shop"
};
@override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(false);
View rootView = inflater.inflate(R.layout.listview_fragment, container, false);
LV = (ListView)rootView.findViewById(R.id.listView1);
LV.setFocusableInTouchMode(true);
LV.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
//LV.setSelection(1);
ArrayAdapter<String> adapter;
arraylist = new ArrayList<String>();
for(int i=0;i<Shops.length;i++){
arraylist.add(Shops);
Arrays.sort(Shops);
}
adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_activated_1,
android.R.id.text1, Shops);
LV.setFastScrollEnabled(true);
LV.setAdapter(adapter);
LV.setOnItemClickListener(new OnItemClickListener() {
@override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
LV.setItemChecked(position, true);
setHasOptionsMenu(true);
}
});
return rootView;
}
@override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.activity_next, menu);
super.onCreateOptionsMenu(menu,inflater);
// MenuItem item = menu.findItem(R.id.next);
//item.setVisible(false);
}
@override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.next:
// confirm action
Confirm();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/**
* Launching new activity
* */
private void Confirm() {
setHasOptionsMenu(true);
}
@override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
/////////////////////////////////////////
this is the second fragment where the selected listview item to be called
package com.example.tabs;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class ListFragment extends Fragment {
private TextView txt1;
@override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.list_fragment, container, false);
setHasOptionsMenu(true);
txt1 = (TextView)rootView.findViewById(R.id.textView1);
return rootView;
}
}
Click to expand...
Click to collapse
please help me... i have got no reply yet.. friends.....
A
Hi there
For the first question try:
Code:
tv1.setText(lv.getText().toSTring());
This works for me.
~LoXeras

Street view orientation

Hi im quite new in android programming and i have the problem with street view. All panoramas looking to north, but i need that they look to custom directions. So there is the code, and i hope someone can help me to finish that code
Code:
package com.example.projektas2;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.OnStreetViewPanoramaReadyCallback;
import com.google.android.gms.maps.StreetViewPanorama;
import com.google.android.gms.maps.StreetViewPanoramaFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.StreetViewPanoramaCamera;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.google.android.gms.maps.model.LatLng;
public class Abuva extends FragmentActivity
implements OnStreetViewPanoramaReadyCallback, View.OnClickListener {
Button button2;
Button button1;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// remove title
requestWindowFeature(Window.FEATURE_NO_TITLE);
// getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
// WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_center_p);
StreetViewPanoramaFragment streetViewPanoramaFragment =
(StreetViewPanoramaFragment) getFragmentManager()
.findFragmentById(R.id.streetviewpanorama);
streetViewPanoramaFragment.getStreetViewPanoramaAsync(this);
button2 = (Button) findViewById(R.id.button2);
button1 = (Button) findViewById(R.id.button1);
button2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
finish();
}
});
button1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent myintent2 = new Intent(Abuva.this,Abuvamap.class);
startActivity(myintent2);
}
});
}
@Override
public void onStreetViewPanoramaReady(StreetViewPanorama panorama) {
panorama.setPosition(new LatLng(55.497273,25.625704));
}
@Override
public void onClick(View v) {
}
}

Socket in android service

So I need to make a service that connects to a server with Socket, and when it recieves certain string, it sends a notification.
This is what i tried to make:
Code:
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
public class SmokeChecker extends Service {
[user=439709]@override[/user]
public int onStartCommand(Intent intent, int flags, int startId) throws Exception {
Socket SOCK = new Socket("localhost",444);
PrintStream PS = new PrintStream(SOCK.getOutputStream());
PS.println("Hello from client: " + Build.MANUFACTURER + " " + Build.MODEL);
InputStreamReader IR = new InputStreamReader(SOCK.getInputStream());
BufferedReader BR = new BufferedReader(IR);
String MESSAGE = BR.readLine();
if(MESSAGE.equals("s")) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setContentText("Fire alert, smoke detected!")
.setContentTitle("Attention!");
NotificationManager manager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(0, builder.build()); //notification
}
if(MESSAGE.equals("g")) {
NotificationCompat.Builder builder2 = new NotificationCompat.Builder(this)
.setContentText("Fire alert, gas detected!")
.setContentTitle("Attention!");
NotificationManager manager2 = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
manager2.notify(0, builder2.build()); //notification
}
return START_STICKY;
}
[user=439709]@override[/user]
public IBinder onBind(Intent intent){
return null;
}
[user=439709]@override[/user]
public void onCreate(){
super.onCreate();
}
[user=439709]@override[/user]
public void onDestroy(){
super.onDestroy();
Toast.makeText(this, "Lost connection to server.", Toast.LENGTH_LONG).show();
}
}
Is this right way to do it? I get an error with throws Exception part.
Or should I do it in onBind method?
I'm really new to both services and networking...
Maro18 said:
So I need to make a service that connects to a server with Socket, and when it recieves certain string, it sends a notification.
This is what i tried to make:
Code:
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
public class SmokeChecker extends Service {
[user=439709]@override[/user]
public int onStartCommand(Intent intent, int flags, int startId) throws Exception {
Socket SOCK = new Socket("localhost",444);
PrintStream PS = new PrintStream(SOCK.getOutputStream());
PS.println("Hello from client: " + Build.MANUFACTURER + " " + Build.MODEL);
InputStreamReader IR = new InputStreamReader(SOCK.getInputStream());
BufferedReader BR = new BufferedReader(IR);
String MESSAGE = BR.readLine();
if(MESSAGE.equals("s")) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setContentText("Fire alert, smoke detected!")
.setContentTitle("Attention!");
NotificationManager manager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(0, builder.build()); //notification
}
if(MESSAGE.equals("g")) {
NotificationCompat.Builder builder2 = new NotificationCompat.Builder(this)
.setContentText("Fire alert, gas detected!")
.setContentTitle("Attention!");
NotificationManager manager2 = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
manager2.notify(0, builder2.build()); //notification
}
return START_STICKY;
}
[user=439709]@override[/user]
public IBinder onBind(Intent intent){
return null;
}
[user=439709]@override[/user]
public void onCreate(){
super.onCreate();
}
[user=439709]@override[/user]
public void onDestroy(){
super.onDestroy();
Toast.makeText(this, "Lost connection to server.", Toast.LENGTH_LONG).show();
}
}
Is this right way to do it? I get an error with throws Exception part.
Or should I do it in onBind method?
I'm really new to both services and networking...
Click to expand...
Click to collapse
i don't know if that's the problem , but i would suggest removing "throws exception" and surround the code with try/catch ( just for testing ).
Are you trying to connect to a server , or someone else to connect to android device ? it looks like the second one, but anyway you should use the internal ip ( assuming you are on the same network ) or external ip of the server( if you are not testing in local network) and not localhost
The server just sends some data to my device and then notification should pop.
The block socket will block your code in onStartCommand. You need to create a thread in onStartCommand and write the communication code in this thread.
You need to create thread by calling
Code:
socketThread = new Thread(socketRunnable);
socketThread.start();
Where socketRunnable is
Code:
socketRunnable = new Runnable() {
public void run() {
// your socket code
}
};
As your notification operate with UI, you need to execute it on UI thread.
You can use Handler class for it.

Categories

Resources