i tried to clear all data from the table inside my database, it was successfull, but the only problems is, everytime i pressed the clear button, it does clear all data but after that the application shows it has stopped
which part did i go wrong? below is my coding from my database:
public boolean deleteRow(long id) {
SQLiteDatabase db = helper.getWritableDatabase();
String where = data.UID + "=" + id;
return db.delete(data.TABLE_NAME, where, null) != 0;
}
public void DeleteAll(){
Cursor c = readEntry();
long id = c.getColumnIndexOrThrow(data.UID);
if (c.moveToFirst()) {
do {
deleteRow(c.getLong((int) id));
} while (c.moveToNext());
}
c.close();
return;
}
and code from the other java:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.showbmi);
initializeApp();
}
private void initializeApp(){
weightinputid = (EditText) findViewById(R.id.weightid);
heightinputid = (EditText) findViewById(R.id.heightid);
buttonBMI = (Button) findViewById(R.id.buttonBMI);
BMIfinal= (TextView) findViewById(R.id.BMIfinal);
BMIStatus = (TextView) findViewById(R.id.BMIstatus);
save = (Button) findViewById(R.id.button);
detail = (Button)findViewById(R.id.button1);
bb = (Button)findViewById(R.id.bb);
table_layout = (TableLayout) findViewById(R.id.tableLayout1);
data = new fitnessdatabase(this);
BuildTable();
bb.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
data.DeleteAll();
new MyAsync().execute();
}
});
private class MyAsync extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
table_layout.removeAllViews();
PD = new ProgressDialog(Showbmi.this);
PD.setTitle("Please Wait..");
PD.setMessage("Loading...");
PD.setCancelable(false);
PD.show();
}
#Override
protected Void doInBackground(Void... params) {
String weight = weightinputid.getText().toString();
String bmi = BMIfinal.getText().toString();
String status = BMIStatus.getText().toString();
String date1 = mDateText.getText().toString();
// inserting data
data.open();
// sqlcon.insertData(firstname, lastname);
long id = data.insertData(weight, bmi, status, date1);
BuildTable();
return null;
}
}
the error from the logcat as shown below:
java.util.concurrent.FutureTask.setException(FutureTask.java:219)
at java.util.concurrent.FutureTask.run(FutureTask.java:239)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.NullPointerException
at com.example.adiehabs.fitnessku.Showbmi$MyAsync.doInBackground(Showbmi.java:188)
at com.example.adiehabs.fitnessku.Showbmi$MyAsync.doInBackground(Showbmi.java:169)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask.run(FutureTask.java:234)
When you try data.Open() it hits an uninitialised variable as you've initalised it in a private void. Change it to public or put all that code into your created bundle. As the UI controls will also be null.
edit your updated with logcat confirms this. In the do in background.
Caused by: java.lang.NullPointerException
at com.example.adiehabs.fitnessku.Showbmi$MyAsync.doInBackground(Showbmi.java:188)
private void initializeApp(){
if (c.moveToFirst()) {
do {
deleteRow(c.getLong((int) id));
} while (c.moveToNext());
}
I would use:
Move the cursor to first and only move it if it's not gone past the last item.
c.moveToFirst();
while(!c.isAfterLast()) {
deleteRow(c.getLong((int) id));
c.moveToNext();
}
}
The other thing:
Have you declared these variables in your main scope table_layout, PD?
The app not responding is often from a nullpointer exception.
Delete all table rows
public boolean deleteTable(){
return mSQLiteDatabase.delete(DataBaseHelper.TABLE, null, null) > 0;
}
Related
I have this application the app bring data from database and store it in a list view then every record have a history i want when i click on the record in the ListView to show me the history of that record. for now i made it when i click on a record then click find id button it will give me the id of the record then i will click History to clear this ListView and showing the history of this record on the same ListView.
Screen Shot for the app1 ,
Screen Shot for the app2
Any one Can help me, my app run but when i want to show the history it don't pass this (if) i don't know why
#Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
if(integer == 1){
ArrayAdapter<String > adapter= new ArrayAdapter<String>(c,android.R.layout.simple_list_item_1, patients );
lv.setAdapter(null);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Snackbar.make(view,patients.get(i), Snackbar.LENGTH_SHORT).show();
}
});
}else{
Toast.makeText(c,"Unable to parse data", Toast.LENGTH_SHORT).show();
}
progressDialog.dismiss();
}
the PHP side
<?php
$host='127.0.0.1';
$username='root';
$password='';
$database='app';
$con =mysqli_connect($host, $username, $password, $database) or die ('unable to connect');
if (mysqli_connect_error($con))
{
echo "Failed to connect to Database ".mysqli_connect_error();
}
$patientID = $_GET['patientID'];
$query= mysqli_query($con, "SELECT * FROM history where
patientID='$patientID' ");
if ($query)
{
while ($row = mysqli_fetch_array($query))
{
$flag[]= $row;
}
print(json_encode($flag));
}
mysqli_close($con);
?>
HistoryDownloader Java Class
public class HistoryDownloader extends AsyncTask<Void, Integer, String> {
Context c;
String address;
ListView lv;
ProgressDialog progressDialog;
public HistoryDownloader(Context c, String address, ListView lv) {
this.c = c;
this.address = address;
this.lv = lv;
}
//Before the job start
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog= new ProgressDialog(c);
progressDialog.setTitle("Fetch Data");
progressDialog.setMessage("Fetching data .... Please wait ");
progressDialog.show();
}
#Override
protected String doInBackground(Void... strings) {
String data= downloadData();
return data;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
progressDialog.dismiss();
if (s != null){
HistoryParser h= new HistoryParser(c,lv,s);
h.execute();
}else{
Toast.makeText(c, "Unable to download data ", Toast.LENGTH_SHORT).show();
}
}
private String downloadData(){
//connect and get a stream
InputStream is= null;
String line =null;
try{
URL url = new URL(address);
HttpURLConnection con= (HttpURLConnection) url.openConnection();
is =new BufferedInputStream( con.getInputStream());
BufferedReader br= new BufferedReader(new InputStreamReader(is));
StringBuffer sb= new StringBuffer() ;
if(br !=null){
while((line=br.readLine()) !=null){
sb.append(line+"\n");
}
}
else{
return null;
}
return sb.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
}
HistoryParser java Class
public class HistoryParser extends AsyncTask<Void, Integer, Integer> {
String lls;
Context c;
ListView lv;
String data;
ArrayList<String > patients= new ArrayList<>();
ProgressDialog progressDialog;
public HistoryParser (Context c, ListView lv, String data) {
this.c = c;
this.lv = lv;
this.data = data;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog= new ProgressDialog(c);
progressDialog.setTitle("Parser");
progressDialog.setMessage("Parsing the data ... please wait");
progressDialog.show();
}
#Override
protected Integer doInBackground(Void... voids) {
return this.histoParse();
}
#Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
if(integer == 1){
ArrayAdapter<String > adapter= new ArrayAdapter<String>(c,android.R.layout.simple_list_item_1, patients );
lv.setAdapter(null);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Snackbar.make(view,patients.get(i), Snackbar.LENGTH_SHORT).show();
}
});
}else{
Toast.makeText(c,"Unable to parse data", Toast.LENGTH_SHORT).show();
}
progressDialog.dismiss();
}
// parse the reciv
private int histoParse (){
try {
//adding the data to json aray first
JSONArray js= new JSONArray(data);
//create json object to hold a singel item
JSONObject jo= null;
patients.clear();
// loop the array
for(int i=0 ;i<js.length();i++){
jo= js.getJSONObject(i);
//retriving the name
//TODO: write the strring depend on the column name in the database
// write the strring depend on the column name in the database
String case1=jo.getString("case1");
/* String case2=jo.getString("case2");
String case3=jo.getString("Case3");
String case4=jo.getString("Case4");
String case5=jo.getString("Case5");
String case6=jo.getString("Case6");
String case7=jo.getString("Case7");
String case8=jo.getString("Case8");
String case9=jo.getString("Case9");
String case10=jo.getString("Case10");
String trt1=jo.getString("trt1");
String trt2=jo.getString("trt2");
String trt3=jo.getString("trt3");
String trt4=jo.getString("trt4");
String trt5=jo.getString("trt5");
String trt6=jo.getString("trt6");
String trt7=jo.getString("trt7");
String trt8=jo.getString("trt8");
String trt9=jo.getString("trt9");
String trt10=jo.getString("trt10");
//add it to our array list
patients.add("Patient History");
patients.add("");
patients.add("Cases");
patients.add("");
*/ patients.add(case1);
/* patients.add(case2);
players.add(case3);
players.add(case4);
players.add(case5);
players.add(case6);
players.add(case7);
players.add(case8);
players.add(case9);
players.add(case10);
players.add("");
players.add("Treatments");
players.add("");
players.add(trt1);
players.add(trt2);
players.add(trt3);
players.add(trt4);
players.add(trt5);
players.add(trt6);
players.add(trt7);
players.add(trt8);
players.add(trt9);
players.add(trt10);
*/
}
return 1;
} catch (JSONException e) {
e.printStackTrace();
}
return 0;
}
}
Main Class Java
public class MainActivity extends AppCompatActivity {
Context context;
String url="http://10.0.2.2/Android/Fetch.php";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final TextView textView= (TextView) findViewById(R.id.textView);
final ListView lv=(ListView) findViewById(R.id.lv);
final Downloader d= new Downloader(this,url,lv);
String urlHistory="http://10.0.2.2/Android/History.php?patientID="+textView.getText().toString().trim();
final HistoryDownloader dd= new HistoryDownloader(this,urlHistory,lv);
final Button btn= (Button ) findViewById(R.id.button);
final Button btn2=(Button) findViewById(R.id.button2);
btn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
lv.setAdapter(null);
//String kk=textView.getText().toString().trim();
dd.execute();
if(textView.getText() != ""){
}else{
}
}
});
i did not use Transmitting Network Data Volley thats why im getting :)
I am using okhttp for network requests and responses.I have searched alot on the web and also on github about this issue but i did not get any clean solution, I don't know what is wrong in the code. I am getting NullPointerException when i click on Btn_Proceed. The code is provided and also the stacktrace. Thank you.
07-28 02:11:18.407 16167-17029/com.donateblood.blooddonation E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.donateblood.blooddonation, PID: 16167
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:864)
Caused by: java.lang.NullPointerException
at okhttp3.HttpUrl.canonicalize(HttpUrl.java:1853)
at okhttp3.FormBody$Builder.add(FormBody.java:110)
at com.donateblood.blooddonation.UploadImage$AddUserAsync.doInBackground(UploadImage.java:203)
at com.donateblood.blooddonation.UploadImage$AddUserAsync.doInBackground(UploadImage.java:173)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:864)
public class UploadImage extends AppCompatActivity {
#InjectView(R.id.imageView) ImageView ImageUpload;
#InjectView(R.id.upload) Button Btn_Upload;
#InjectView(R.id.proceed) Button Btn_Proceed;
EditText code;
public ProgressDialog pDialog;
public String bloodgroup,name,password,number,email,age,ID;
public String encodedPhotoString=null;
GPSTracker gps; public Bitmap myimage=null;
public JSONObject json =null;
public double latitude;
public double longitude;
#Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try{
setContentView(R.layout.uploadimage);
ButterKnife.inject(this);
}catch (OutOfMemoryError e){
Toast.makeText(getBaseContext(), "Sorry,Something went wrong", Toast.LENGTH_SHORT).show();
}
code = (EditText) findViewById(R.id.code);
myimage = CroppingActivity.finalImage;
CheckImage();
// Upload image ====================================
Btn_Upload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), CroppingActivity.class);
startActivity(intent);
UploadImage.this.finish();
}
});
Btn_Proceed.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(code.length()==0){
Toast.makeText(getBaseContext(), "Enter verification code", Toast.LENGTH_LONG).show();
}
else {
Prcoess();
}
}
});
}
public void CheckImage(){
if(myimage!=null){
Uri uri = getImageUri(myimage);
String url = getRealPathFromURI(uri);
File file = new File(url);
Glide.with(UploadImage.this).load(file).asBitmap().diskCacheStrategy( DiskCacheStrategy.NONE ).skipMemoryCache( true ).override(300,300)
.transform(new CenterCrop(UploadImage.this),new CustomCenterCrop(UploadImage.this)).into(ImageUpload);
}else {
encodedPhotoString= null;
}
}
#Override
public void onDestroy() {
super.onDestroy();
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
public String getRealPathFromURI(Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = UploadImage.this.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
public Uri getImageUri( Bitmap inImage) {
String path = MediaStore.Images.Media.insertImage(UploadImage.this.getContentResolver(), inImage, "Title", null);
return Uri.parse(path);
}
// Processing and adding user to database from here ====================================
public void Prcoess(){
String userentered=code.getText().toString();
String sentcode = SignupActivity.Code;
setPhoto();
if(userentered.equals(sentcode) && encodedPhotoString!=null ){
new AddUserAsync().execute();
}
else {
Toast.makeText(getBaseContext(), "Oopps...Sorry...Upload Again", Toast.LENGTH_LONG).show();
}
}
public void setPhoto() {
// resize the image to store to database
myimage= getResizedBitmap(myimage,400,400);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
myimage.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] byte_arr = stream.toByteArray();
encodedPhotoString = Base64.encodeToString(byte_arr, 0);
Log.e("photo string ", encodedPhotoString);
}
public class AddUserAsync extends AsyncTask<Void,Void,Void> {
JSONObject json = null;
String fromServer = "";
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(UploadImage.this);
pDialog.setMessage("Creating Account...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... voids) {
GetUserDetails();
GenerateGCMID();
email= email.trim().toLowerCase();
//HashMap<String ,String> userDetails = new HashMap<>();
latitude = GPSTracker.getLatitude();
longitude = GPSTracker.getLongitude();
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(50, TimeUnit.SECONDS)
.writeTimeout(50, TimeUnit.SECONDS)
.readTimeout(50, TimeUnit.SECONDS)
.build();
FormBody.Builder formBuilder = new FormBody.Builder() // Null pointer exception is thrown here
.add("ID",ID)
.add("Name",name)
.add("email",email)
.add("password",password)
.add("age",age)
.add("number",number)
.add("bloodgroup",bloodgroup)
.add("lat",latitude+"")
.add("longi",longitude+"")
.add("image",encodedPhotoString);
RequestBody formBody = formBuilder.build();
Request request = new Request.Builder()
.url("http://faceblood.website/blood_app/Adduser.php")
.post(formBody)
.build();
try {
Response response = client.newCall(request).execute();
String res = response.body().string();
json = new JSONObject(res);
fromServer = json.getString("added");
Log.e("stringtest",json.getString("added"));
// Do something with the response.
} catch (IOException e) {
Log.e("stringtest IO",e.toString());
e.printStackTrace();
} catch (JSONException e) {
Log.e("stringtest JSON",e.toString());
e.printStackTrace();
}
//json = new HttpCall().postForJSON("http://faceblood.website/blood_app/Adduser.php",userDetails);
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
pDialog.dismiss();
Log.e("fromServer",fromServer);
if(fromServer.equals("addeduser")){
Toast.makeText(getBaseContext(), "Created Successfully", Toast.LENGTH_LONG).show();
onSignupSuccess();
}else {
Toast.makeText(getBaseContext(), "Network problem. Click again", Toast.LENGTH_LONG).show();
}
}
}
public void GenerateGCMID(){
GCMClientManager pushClientManager = new GCMClientManager(this, "921544902369");
pushClientManager.registerIfNeeded(new GCMClientManager.RegistrationCompletedHandler() {
#Override
public void onSuccess(String registrationId, boolean isNewRegistration) {
ID = registrationId;
Log.e("reg",ID);
}
#Override
public void onFailure(String ex) {
super.onFailure(ex);
}
});
}
// Go to another activity on success ====================================
public void onSignupSuccess() {
// stop the service we got the latitude and longitude now
myimage.recycle();
myimage = null;
ImageUpload.setImageResource(0);
stopService(new Intent(this, GPSTracker.class));
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
startActivity(intent);
finish();
}
// fetch user details ====================================
public void GetUserDetails(){
bloodgroup = SignupActivity.bloodgroup.toString();
name = SignupActivity.name.toString();
email = SignupActivity.email.toString();
password = SignupActivity.password.toString();
number = SignupActivity.number.toString();
age = SignupActivity.age.toString();
}
// Resize the image ====================================
public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth)
{
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
}
Hint
at okhttp3.FormBody$Builder.add(FormBody.java:110)
at ...UploadImage$AddUserAsync.doInBackground(UploadImage.java:203)
You have added a null value to the Form here (at line 203)
FormBody.Builder formBuilder = new FormBody.Builder()
.add("ID",ID)
.add("Name",name)
.add("email",email)
.add("password",password)
.add("age",age)
.add("number",number)
.add("bloodgroup",bloodgroup)
.add("lat",latitude+"")
.add("longi",longitude+"")
.add("image",encodedPhotoString);
Which I am guessing starts from either here, where you are doing another asynchronous request.
public void GenerateGCMID(){
GCMClientManager pushClientManager = new GCMClientManager(this, "921544902369");
pushClientManager.registerIfNeeded(new GCMClientManager.RegistrationCompletedHandler() {
#Override
public void onSuccess(String registrationId, boolean isNewRegistration) {
ID = registrationId;
Log.e("reg",ID);
}
#Override
public void onFailure(String ex) {
super.onFailure(ex);
}
});
}
Or here because static values are not how you pass data between Activities. You cannot "reach" for a EditText value from the current Activity to a different one.
// fetch user details ====================================
public void GetUserDetails(){
bloodgroup = SignupActivity.bloodgroup.toString();
name = SignupActivity.name.toString();
email = SignupActivity.email.toString();
password = SignupActivity.password.toString();
number = SignupActivity.number.toString();
age = SignupActivity.age.toString();
}
You can refer to How do I pass data between Activities
I have created an app that is connected to a remote database. The items in the database are displayed through a spinner in my MainActivity class. I want to display the selected item in a separate class(Map.java) and XML page(map.xml), So I used this code in Map.java to try get the selected item and display it:
Spinner mySpinner = (Spinner)findViewById(R.id.spinFood);
String text = mySpinner.getSelectedItem().toString();
EditText e = (EditText) findViewById (R.id.editText1);
e.setText(text);
To display this value I created an EditText in my map.xml file:
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="text"
android:text="#string/text"
android:id="#+id/editText1"
android:layout_alignBottom="#+id/textView"
android:layout_toRightOf="#+id/textView"
android:layout_alignRight="#+id/imageView"
android:layout_alignEnd="#+id/imageView" />
The android:input_type="text" is a string value I created:
<string name="text"> %s </string>
But whenever I open the map page my app crashes. Could someone please tell me where I am going wrong?
Here all of my code for MainActivity and Map.java
MainActivity
package com.example.cillin.infoandroidhivespinnermysql;
import java.util.ArrayList;
..
public class MainActivity extends Activity implements OnItemSelectedListener {
private Button btnAddNewCategory;
private TextView txtCategory;
public Spinner spinnerFood;
// array list for spinner adapter
private ArrayList<Category> categoriesList;
ProgressDialog pDialog;
// API urls
// Url to create new category
private String URL_NEW_CATEGORY = "http://192.168.1.4/food_api/new_category.php";
// Url to get all categories
private String URL_CATEGORIES = "http://192.168.1.4/food_api/get_categories.php";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnAddNewCategory = (Button) findViewById(R.id.btnAddNewCategory);
spinnerFood = (Spinner) findViewById(R.id.spinFood);
txtCategory = (TextView) findViewById(R.id.txtCategory);
categoriesList = new ArrayList<Category>();
// spinner item select listener
spinnerFood.setOnItemSelectedListener(this);
// Add new category click event
btnAddNewCategory.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (txtCategory.getText().toString().trim().length() > 0) {
// new category name
String newCategory = txtCategory.getText().toString();
// Call Async task to create new category
new AddNewCategory().execute(newCategory);
} else {
Toast.makeText(getApplicationContext(),
"Please enter category name", Toast.LENGTH_SHORT)
.show();
}
}
});
new GetCategories().execute();
}
/**
* Adding spinner data
* */
private void populateSpinner() {
List<String> lables = new ArrayList<String>();
txtCategory.setText("");
for (int i = 0; i < categoriesList.size(); i++) {
lables.add(categoriesList.get(i).getName());
}
// Creating adapter for spinner
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, lables);
// Drop down layout style - list view with radio button
spinnerAdapter
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// attaching data adapter to spinner
spinnerFood.setAdapter(spinnerAdapter);
//spinnerValue = spinnerFood.getSelectedItem().toString();
}
/**
* Async task to get all food categories
* */
private class GetCategories extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Fetching food categories..");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
ServiceHandler jsonParser = new ServiceHandler();
String json = jsonParser.makeServiceCall(URL_CATEGORIES, ServiceHandler.GET);
Log.e("Response: ", "> " + json);
if (json != null) {
try {
JSONObject jsonObj = new JSONObject(json);
if (jsonObj != null) {
JSONArray categories = jsonObj
.getJSONArray("categories");
for (int i = 0; i < categories.length(); i++) {
JSONObject catObj = (JSONObject) categories.get(i);
Category cat = new Category(catObj.getInt("id"),
catObj.getString("name"));
categoriesList.add(cat);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("JSON Data", "Didn't receive any data from server!");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (pDialog.isShowing())
pDialog.dismiss();
populateSpinner();
}
}
/**
* Async task to create a new food category
* */
private class AddNewCategory extends AsyncTask<String, Void, Void> {
boolean isNewCategoryCreated = false;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Creating new category..");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(String... arg) {
String newCategory = arg[0];
// Preparing post params
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("name", newCategory));
ServiceHandler serviceClient = new ServiceHandler();
String json = serviceClient.makeServiceCall(URL_NEW_CATEGORY,
ServiceHandler.POST, params);
Log.d("Create Response: ", "> " + json);
if (json != null) {
try {
JSONObject jsonObj = new JSONObject(json);
boolean error = jsonObj.getBoolean("error");
// checking for error node in json
if (!error) {
// new category created successfully
isNewCategoryCreated = true;
} else {
Log.e("Create Category Error: ", "> " + jsonObj.getString("message"));
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("JSON Data", "Didn't receive any data from server!");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (pDialog.isShowing())
pDialog.dismiss();
if (isNewCategoryCreated) {
runOnUiThread(new Runnable() {
#Override
public void run() {
// fetching all categories
new GetCategories().execute();
}
});
}
}
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position,
long id) {
Toast.makeText(
getApplicationContext(),
parent.getItemAtPosition(position).toString() + " Selected" ,
Toast.LENGTH_LONG).show();
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
}
}
Map.java
package com.example.cillin.infoandroidhivespinnermysql;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
public class Map extends Activity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//This page layout is located in the menu XML file
//SetContentView links a Java file, to its XML file for the layout
setContentView(R.layout.map);
/*TextView.setText(spinnerValue);
TextView spinv = (TextView)findViewById(R.id.textView2);
spinv.setText(getspin());
spinv = getspin();*/
Spinner mySpinner = (Spinner)findViewById(R.id.spinFood);
String text = mySpinner.getSelectedItem().toString();
EditText e = (EditText) findViewById (R.id.editText1);
e.setText(text);
Button mainm = (Button)findViewById(R.id.mainmenu);
mainm.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//This button is linked to the map page
Intent i = new Intent(Map.this, MainMenu.class);
//Activating the intent
startActivity(i);
}
});
}
}
Any help would be much appreciated!!
Here are the errors in my logcat when is crashes:
E/DatabaseUtils﹕ Writing exception to parcel
java.lang.SecurityException: Permission Denial: get/set setting for user asks to run as user -2 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL
at com.android.server.am.ActivityManagerService.handleIncomingUser(ActivityManagerService.java:14643)
at android.app.ActivityManager.handleIncomingUser(ActivityManager.java:2469)
at com.android.providers.settings.SettingsProvider.call(SettingsProvider.java:688)
at android.content.ContentProvider$Transport.call(ContentProvider.java:325)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:275)
at android.os.Binder.execTransact(Binder.java:404)
E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.cillin.infoandroidhivespinnermysql, PID: 14691
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.cillin.infoandroidhivespinnermysql/com.example.cillin.infoandroidhivespinnermysql.Map}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2305)
at
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2363)
at android.app.ActivityThread.access$900(ActivityThread.java:161)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1265)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5356)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.example.cillin.infoandroidhivespinnermysql.Map.onCreate(Map.java:34)
at android.app.Activity.performCreate(Activity.java:5426)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2269)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2363)
at android.app.ActivityThread.access$900(ActivityThread.java:161)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1265)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5356)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(Native Method)
I'm guessing that you're getting a NullPointerException in your Map.class
Spinner mySpinner = (Spinner)findViewById(R.id.spinFood);
String text = mySpinner.getSelectedItem().toString();
EditText e = (EditText) findViewById (R.id.editText1);
e.setText(text);
You get a reference to Spinner, then you try to get the selected item and then convert that item to a string. As far as I can tell you haven't actually added any items to the spinner. My guess is that you are trying to access an object in the spinner and since it doesn't exist it returns null. Then you try to call a method on the null object and get an NPE.
This is just a guess. A stacktrace is very helpful in trying to diagnose this.
Where I think you're going wrong is that you populate the spinner in MainActivity and then expect to be able to select an item from that spinner from a different activity. This isn't how it works. Map.class won't be able to reference anything in MainActivity.class. You could try passing the object from MainActivity.class to Map.class or use a different method of passing data, but trying to reference data in MainAcitivity.class from Map.class won't work.
Edit:
If you just want to pass a String from MainActivity.class to Map.class you can add the string as an 'extra' to the intent that you use to start Map.class.
In your MainActivity.class code. When the item from the spinner is selected, create an intent and set the string as an extra using the putExtra() method. You will need to supply a key that basically tags the extra so you can identify it in the receiving activity and the string you want to send.
Intent intent = new Intent(this, Map.class);
intent.putExtra("KEY_SPINNER_STRING", variableRepresentingString);
startActivity(intent);
In the Map.class activity, in the onCreate() method you will need to receive the intent, check for the extra, then unpack the extra. Then you will have the String.
onCreate(Bundle savedInstanceState) {
String spinnerString;
if (getIntent() != null && getIntent().getExtras() != null) {
Bundle bundle = getIntent().getExtras();
if (bundle.getString("KEY_SPINNER_STRING") != null) {
spinnerString = bundle.getString("KEY_SPINNER_STRING");
}
}
}
If everything is done correctly the String will be passed from MainActivity.class and received by Map.class
I have a ListView in AcitivityA that is populated using a custom SimpleCursorAdapter called RecipeAdapter. The adapter holds data from SQLite
There is a EditText view at the top of the ListView, that filters the listview as the user searches for a recipe. When a user clicks on a item in the filtered ListView, ActivityB starts.
This all works perfectly. However when the user presses the backbutton to resume ActivityB, I get the following error.
java.lang.RuntimeException: Unable to resume activity {ttj.android.quorn/ttj.android.quorn.RecipeActivity}:
java.lang.IllegalStateException: trying to requery an already closed cursor android.database.sqlite.SQLiteCursor#418ae5d8
To fix this problem, I modified the onResume() from:
...
c = db.getCursor();
adapter.changeCursor(c);
to
....
Cursor cursor = db.getCursor();
adapter.changeCursor(cursor);
I then get the following exception. In the Logcat, the problem arises with the getId() method in DBHelper. I have added c.moveToFirst() in this method, but this still doesn't solve the problem.
FATAL EXCEPTION: main
android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 70
at android.database.AbstractCursor.checkPosition(AbstractCursor.java:400)
at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
at ttj.android.quorn.DBHelper.getId(DBHelper.java:224)
at ttj.android.quorn.RecipeActivity$RecipeHolder.populateFrom(RecipeActivity.java:650)
at ttj.android.quorn.RecipeActivity$RecipeAdapter.bindView(RecipeActivity.java:572)
at android.support.v4.widget.CursorAdapter.getView(CursorAdapter.java:256)
at android.widget.AbsListView.obtainView(AbsListView.java:2214)
at android.widget.ListView.makeAndAddView(ListView.java:1774)
at android.widget.ListView.fillDown(ListView.java:672)
at android.widget.ListView.fillFromTop(ListView.java:732)
at android.widget.ListView.layoutChildren(ListView.java:1611)
at android.widget.AbsListView.onLayout(AbsListView.java:2044)
at android.view.View.layout(View.java:11418)
at android.view.ViewGroup.layout(ViewGroup.java:4224)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1399)
at android.view.View.layout(View.java:11418)
at android.view.ViewGroup.layout(ViewGroup.java:4224)
at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
at android.view.View.layout(View.java:11418)
at android.view.ViewGroup.layout(ViewGroup.java:4224)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1399)
at android.view.View.layout(View.java:11418)
at android.view.ViewGroup.layout(ViewGroup.java:4224)
at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
at android.view.View.layout(View.java:11418)
at android.view.ViewGroup.layout(ViewGroup.java:4224)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1628)
at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2585)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4507)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
at dalvik.system.NativeStart.main(Native Method)
Can anyone help me with my problem?
Here is my code:
In the onCreate, the cursor populate the ListView using c.getCursor and when the user filters the ListView via the EditText, the c.getFilterCursor is used.
public class RecipeActivity extends SherlockListActivity {
private DBHelper db = null;
private Cursor c = null;
private RecipeAdapter adapter = null;
ListView listContent;
private EditText filterText = null;
#SuppressWarnings("deprecation")
#Override
public void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
setContentView(R.layout.filter_list);
filterText = (EditText) findViewById(R.id.search_box);
filterText.addTextChangedListener(filterTextWatcher);
ListView listContent = getListView();
db = new DBHelper(this);
db.createDataBase();
db.openDataBase();
c = db.getCursor();
adapter = new RecipeAdapter(c);
listContent.setAdapter(adapter);
adapter.setFilterQueryProvider(new FilterQueryProvider() {
public Cursor runQuery(CharSequence constraint) {
// Search for states whose names begin with the specified letters.
c = db.getFilterCursor(constraint);
return c;
}
});
startManagingCursor(c);
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
filterText.removeTextChangedListener(filterTextWatcher);
db.close();
}
#SuppressWarnings("deprecation")
#Override
protected void onResume() {
super.onResume();
Cursor cursor = db.getCursor();
adapter.changeCursor(cursor);
}
#Override
protected void onPause() {
super.onPause();
adapter.notifyDataSetInvalidated();
adapter.changeCursor(null);
}
private TextWatcher filterTextWatcher = new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void onTextChanged(CharSequence s, int start, int before,
int count) {
adapter.getFilter().filter(s);
}
};
RecipeAdapter inner class
class RecipeAdapter extends CursorAdapter {
#SuppressWarnings("deprecation")
public RecipeAdapter(Cursor c) {
super(RecipeActivity.this, c);
}
public void bindView(View row, Context arg1, Cursor arg2) {
RecipeHolder holder = (RecipeHolder) row.getTag();
holder.populateFrom(c, db);
}
public View newView(Context arg0, Cursor arg1, ViewGroup arg2) {
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.reciperow, arg2, false);
RecipeHolder holder = new RecipeHolder(row);
row.setTag(holder);
return (row);
}
static class RecipeHolder {
public TextView id = null;
private TextView name = null;
private TextView desc = null;
private TextView preptime = null;
private TextView cooktime = null;
private TextView serves = null;
private TextView calories = null;
private TextView fat = null;
private TextView fav = null;
RecipeHolder(View row) {
id = (TextView) row.findViewById(R.id.id);
name = (TextView) row.findViewById(R.id.recipe);
desc = (TextView) row.findViewById(R.id.desc);
preptime = (TextView) row.findViewById(R.id.preptime);
cooktime = (TextView) row.findViewById(R.id.cooktime);
serves = (TextView) row.findViewById(R.id.serving);
calories = (TextView) row.findViewById(R.id.calories);
fat = (TextView) row.findViewById(R.id.fat);
fav = (TextView) row.findViewById(R.id.fav);
}
void populateFrom(Cursor c, DBHelper r) {
id.setText(r.getId(c));
name.setText(r.getRecipe(c));
name.setTextColor(Color.parseColor("#CCf27c22"));
desc.setText(r.getDesc(c));
preptime.setText(r.getPrepTime(c) + ". ");
cooktime.setText(r.getCookTime(c) + " mins");
serves.setText(r.getServes(c));
calories.setText(r.getCalories(c));
fat.setText(r.getFat(c));
fav.setText(r.getFav(c));
DBHelper class
public Cursor getCursor() {
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setTables(DATABASE_TABLE);
String[] columns = new String[] { KEY_ROWID, RECIPE, DESC, PREPTIME,
COOKTIME, SERVES, CALORIES, FAT, CATEGORY, FAV };
Cursor myCursor = queryBuilder.query(myDataBase, columns, null, null,
null, null, RECIPE + " ASC");
return myCursor;
}
public Cursor getFilterCursor(CharSequence constraint) {
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setTables(DATABASE_TABLE);
String[] columns = new String[] { KEY_ROWID, RECIPE, DESC, PREPTIME,
COOKTIME, SERVES, CALORIES, FAT, CATEGORY, FAV };
if (constraint == null || constraint.length() == 0) {
// Return the full list
return queryBuilder.query(myDataBase, columns, null, null, null,
null, RECIPE + " ASC");
} else {
String value = "%" + constraint.toString() + "%";
return myDataBase.query(DATABASE_TABLE, columns, "RECIPE like ? ",
new String[] { value }, null, null, null);
}
}
public String getId(Cursor c) {
c.moveToFirst();
return (c.getString(0));
}
public String getRecipe(Cursor c) {
return (c.getString(1));
}
public String getDesc(Cursor c) {
return (c.getString(2));
}
public String getPrepTime(Cursor c) {
return (c.getString(3));
}
public String getCookTime(Cursor c) {
return (c.getString(4));
}
public String getServes(Cursor c) {
return (c.getString(5));
}
public String getCalories(Cursor c) {
return (c.getString(6));
}
public String getFat(Cursor c) {
return (c.getString(7));
}
public String getCategory(Cursor c) {
return (c.getString(8));
}
public String getFav(Cursor c) {
return (c.getString(9));
}
#SuppressWarnings("deprecation")
Bad. You should get rid of the deprecation instead of hiding that :)
startManagingCursor(c);
Don't do that. That may have caused the requery on the already closed cursor. Simply remove that line.
adapter.setFilterQueryProvider(new FilterQueryProvider() {
public Cursor runQuery(CharSequence constraint) {
// Search for states whose names begin with the specified letters.
c = db.getFilterCursor(constraint);
return c;
}
});
Don't overwrite your c here. Just return db.getFilterCursor(constraint); is what this should do.
Other things that may have a positive effect
#SuppressWarnings("deprecation")
public RecipeAdapter(Cursor c) {
super(RecipeActivity.this, c);
}
public RecipeAdapter(Cursor c) {
// no requeries and no observer required if you change the cursor yourself
super(RecipeActivity.this, c, 0)
}
Next one:
adapter.notifyDataSetInvalidated();
adapter.changeCursor(null);
// change to
adapter.changeCursor(null);
adapter.notifyDataSetChanged(); // maybe without this
As far as I understand the documentation notifyDataSetInvalidated() means that the data can't be valid afterwards ("Once invoked this adapter is no longer valid and should not report further data set changes.") and you need to create a new Adapter instance. Not sure though. Just doing notifyDataSetChanged() works fine. It might even be the case that doing adapter.changeCursor() will already implicitly do the change notification.
P.S.: c.MoveToFirst() is not required. The CursorAdapter will move the cursor to the required position.
You renamed your variable, as indicated here
....
Cursor cursor = db.getCursor();
adapter.changeCursor(cursor);
correct? But right after that you specify that you tried
c.moveToFirst()
So maybe you should set
c = cursor;
So that the rest of your code works?
I'm calling the object here.
public class TestDetails extends ListActivity {
protected TextView testNameText;
protected SQLiteDatabase db;
protected TextView testvalueText;
protected List<TestAction> actions;
protected TestItemAdapter adapter;
protected int testId;
protected int categoryId;
#Override
//adds options menu
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.list_search: onSearchRequested();
break;
}
return true;
}
//end of add options menu
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_details);
// Get the intent, verify the action and get the query
db = (new DatabaseHelper(this)).getWritableDatabase();
Intent intent1 = getIntent();
SimpleSearch SSearch = new SimpleSearch();
if (Intent.ACTION_SEARCH.equals(intent1.getAction())) {
String query = intent1.getStringExtra(SearchManager.QUERY);
SSearch.testSearch(query);
}
testId = getIntent().getIntExtra("EMPLOYEE_ID", 0);
SQLiteDatabase db = (new DatabaseHelper(this)).getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT emp._id, emp.firstName, emp.lastName, emp.title, emp.officePhone, emp.cellPhone, emp.email, emp.managerId, mgr.firstName managerFirstName, mgr.lastName managerLastName FROM employee emp LEFT OUTER JOIN employee mgr ON emp.managerId = mgr._id WHERE emp._id = ?",
new String[]{""+testId});
if (cursor.getCount() == 1)
{
cursor.moveToFirst();
testNameText = (TextView) findViewById(R.id.employeeName);
testNameText.setText(cursor.getString(cursor.getColumnIndex("firstName")) + " " + cursor.getString(cursor.getColumnIndex("lastName")));
actions = new ArrayList<TestAction>();
String officePhone = cursor.getString(cursor.getColumnIndex("officePhone"));
if (officePhone != null) {
actions.add(new TestAction("Call office", officePhone, TestAction.ACTION_CALL));
}
String cellPhone = cursor.getString(cursor.getColumnIndex("cellPhone"));
if (cellPhone != null) {
actions.add(new TestAction("Call mobile", cellPhone, TestAction.ACTION_CALL));
actions.add(new TestAction("SMS", cellPhone, TestAction.ACTION_SMS));
}
String email = cursor.getString(cursor.getColumnIndex("email"));
if (email != null) {
actions.add(new TestAction("Email", email, TestAction.ACTION_EMAIL));
}
categoryId = cursor.getInt(cursor.getColumnIndex("managerId"));
if (categoryId>0) {
actions.add(new TestAction("View manager", cursor.getString(cursor.getColumnIndex("managerFirstName")) + " " + cursor.getString(cursor.getColumnIndex("managerLastName")), TestAction.ACTION_VIEW));
}
cursor = db.rawQuery("SELECT count(*) FROM employee WHERE managerId = ?",
new String[]{""+testId});
cursor.moveToFirst();
int count = cursor.getInt(0);
if (count>0) {
actions.add(new TestAction("View direct reports", "(" + count + ")", TestAction.ACTION_REPORTS));
}
adapter = new TestItemAdapter();
setListAdapter(adapter);
}
}
class TestItemAdapter extends ArrayAdapter<TestAction> {
TestItemAdapter() {
super(TestDetails.this, R.layout.action_list_item, actions);
}
#Override
public boolean areAllItemsEnabled() {
return false;
}
public boolean isEnabled(int position) {
return false;
}
public View getView(int position, View convertView, ViewGroup parent) {
TestAction action = actions.get(position);
LayoutInflater inflater = getLayoutInflater();
View view = inflater.inflate(R.layout.action_list_item, parent, false);
TextView label = (TextView) view.findViewById(R.id.label);
label.setText(action.getLabel());
TextView data = (TextView) view.findViewById(R.id.data);
data.setText(action.getData());
return view;
}
}
}
This is the class from which I'm calling the object.(part of the class)
public class SimpleSearch extends ListActivity {
protected SQLiteDatabase db;
protected Cursor cursor;
protected ListAdapter adapter;
protected String query;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
db = (new DatabaseHelper(this)).getWritableDatabase();
// Get the intent, verify the action and get the query
Intent intent = getIntent();
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
testSearch(query);
}
else TestListAll();
}
But I'm getting a force close on running the application. Stack trace shows the error to be in SSearch.testSearch(query); statement. What am I missing here?
Stack trace:
app_vercode:1
device_model:umts_jordan
build_version:1.11.18
condition:1
processName:com.simple.search
pid:3529
uid:10063
tag:null
shortMsg:java.lang.NullPointerException
longMsg:java.lang.NullPointerException: Unable to start activity ComponentInfo{com.simple.search/com.simple.search.TestDetails}: java.lang.NullPointerException
stackTrace:java.lang.RuntimeException: Unable to start activity ComponentInfo{com.simple.search/com.simple.search.TestDetails}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1664)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1680)
at android.app.ActivityThread.access$1500(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3703)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.simple.search.SimpleSearch.testSearch(SimpleSearch.java:68)
at com.simple.search.TestDetails.onCreate(TestDetails.java:59)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1628)
... 11 more
Most likely the line
String query = intent1.getStringExtra(SearchManager.QUERY);
Is assigning a null value to query - are you sure the correct extra is there? I usually get extras in this manner:
public static final String TAG = "MyActivity";
public static final String DATA_KEY = "DataKey";
public static final String MY_CUSTOM_ACTION = "MyCustomSearchAction";
public void onCreate(Bundle savedInstanceState) {
Intent intent1 = getIntent();
SimpleSearch SSearch = new SimpleSearch();
if (intent1.getAction().equals(MY_CUSTOM_ACTION)
&& intent1.hasExtra(SearchManager.QUERY)
&& intent.hasExtra(DATA_KEY)) {
String query = intent1.getStringExtra(SearchManager.QUERY);
DataObject data = intent1.getParcelableExtra(DATA_KEY);
if (query != null && data != null)
SSearch.testSearch(query, data);
else {
//invalid query
Log.d(TAG,"Activity started with invalid query data - closing");
this.finish();
return;
}
} else {
//Invalid Intent
Log.d(TAG,"Activity started with invalid intent - closing");
this.finish();
return;
}
}
A data object can look like this:
public class DataObject implements Parcelable {
public String someData;
public String someMoreData;
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(someData);
dest.writeString(someMoreDate);
}
//Constructor for parceler
public DataObject(Parcel src) {
someData = src.readString();
someMoreData = src.readString();
}
public static final Parcelable.Creator<DataObject> CREATOR =
new Parcelable.Creator<DataObject>() {
public DataObject createFromParcel(Parcel in) {
return new DataObject(in);
}
public DataObject[] newArray(int size) {
return new DataObject[size];
}
};
}
To start your activity just go:
DataObject data = new DataObject();
data.someData = "test";
data.someMoreData = "test2";
Intent intent = new Intnent(this, MyActivity.class);
intent.setAction(MyActivity.MY_CUSTOM_ACTION);
intent.putExtra(MyActivity.DATA_KEY,data);
intent.putExtra(SearchManager.QUERY, "Query");
startActivity(intent);