all day long I've been searching the root cause of the following error. I there anyone who can help me with this issue?
Using:
Android Studio 4.1.1 / Java
My goal:
I have a sqlite database created with DB Browser (recipe.db3) in my assets folder: Assets > recipe.db3. This database shall be copied to app database folder in the SplashActivity.java if the database does not exist yet (basically once in app lifetime).
Once created, I want to access this database and show its content (only title) in the RecycleViewer in RecipesFragment.java.
My issue:
I receive a NullPointerException when I try to show my RecyclerView - basically when I run this.getReadableDatabase() in my DataBaseHelper.java. It seems like I cannot even access my database. Even if I do not copy my baking.db3 file to /data/data/com.android.baking/databases/ but create the database programmatically I receive the same error.
Does anyone have a clue where the error lies?
Thanks!
Kornelius
Logcat output
I/database: TABLE_RECIPES created
TABLE_US created
...............
D/EGL_emulation: eglMakeCurrent: 0xb31050c0: ver 2 0 (tinfo 0xb3103660)
I/art: Do partial code cache collection, code=55KB, data=59KB
After code cache collection, code=54KB, data=58KB
Increasing code cache capacity to 256KB
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.android.baking, PID: 9878
androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment com.android.baking.ui.recipes.RecipesFragment: calling Fragment constructor caused an exception
at androidx.fragment.app.Fragment.instantiate(Fragment.java:566)
at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57)
at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:390)
at androidx.navigation.fragment.FragmentNavigator.instantiateFragment(FragmentNavigator.java:132)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:162)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:58)
at androidx.navigation.NavController.navigate(NavController.java:1059)
at androidx.navigation.NavController.navigate(NavController.java:944)
at androidx.navigation.NavController.navigate(NavController.java:877)
at androidx.navigation.ui.NavigationUI.onNavDestinationSelected(NavigationUI.java:97)
at androidx.navigation.ui.NavigationUI$5.onNavigationItemSelected(NavigationUI.java:531)
at com.google.android.material.bottomnavigation.BottomNavigationView$1.onMenuItemSelected(BottomNavigationView.java:243)
at androidx.appcompat.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:834)
at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)
at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:985)
at com.google.android.material.bottomnavigation.BottomNavigationMenuView$1.onClick(BottomNavigationMenuView.java:127)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22265)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
at androidx.fragment.app.Fragment.instantiate(Fragment.java:548)
at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57)
at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:390)
at androidx.navigation.fragment.FragmentNavigator.instantiateFragment(FragmentNavigator.java:132)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:162)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:58)
at androidx.navigation.NavController.navigate(NavController.java:1059)
at androidx.navigation.NavController.navigate(NavController.java:944)
at androidx.navigation.NavController.navigate(NavController.java:877)
at androidx.navigation.ui.NavigationUI.onNavDestinationSelected(NavigationUI.java:97)
at androidx.navigation.ui.NavigationUI$5.onNavigationItemSelected(NavigationUI.java:531)
at com.google.android.material.bottomnavigation.BottomNavigationView$1.onMenuItemSelected(BottomNavigationView.java:243)
at androidx.appcompat.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:834)
at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)
at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:985)
at com.google.android.material.bottomnavigation.BottomNavigationMenuView$1.onClick(BottomNavigationMenuView.java:127)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22265)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase android.content.Context.openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase$CursorFactory, android.database.DatabaseErrorHandler)' on a null object reference
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223)
at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187)
at com.android.baking.DataBaseHelper.<init>(DataBaseHelper.java:64)
at com.android.baking.ui.recipes.RecipesFragment.<init>(RecipesFragment.java:37)
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
at androidx.fragment.app.Fragment.instantiate(Fragment.java:548)
at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57)
at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:390)
at androidx.navigation.fragment.FragmentNavigator.instantiateFragment(FragmentNavigator.java:132)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:162)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:58)
at androidx.navigation.NavController.navigate(NavController.java:1059)
at androidx.navigation.NavController.navigate(NavController.java:944)
at androidx.navigation.NavController.navigate(NavController.java:877)
at androidx.navigation.ui.NavigationUI.onNavDestinationSelected(NavigationUI.java:97)
at androidx.navigation.ui.NavigationUI$5.onNavigationItemSelected(NavigationUI.java:531)
at com.google.android.material.bottomnavigation.BottomNavigationView$1.onMenuItemSelected(BottomNavigationView.java:243)
at androidx.appcompat.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:834)
at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)
at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:985)
at com.google.android.material.bottomnavigation.BottomNavigationMenuView$1.onClick(BottomNavigationMenuView.java:127)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22265)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
DataBaseHelper.java:
package com.android.baking;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.ContactsContract;
import android.util.Log;
import com.android.baking.ui.adapter.RecipeAdapter;
import com.android.baking.ui.models.RecipeModel;
import com.android.baking.ui.models.UserSpecificModel;
import java.util.ArrayList;
import androidx.annotation.Nullable;
public class DataBaseHelper extends SQLiteOpenHelper {
private static final int DB_VERSION = 1;
public static String DB_NAME = "recipe.db3";
//ITEMS IN TABLE: RECIPES
public static final String TABLE_RECIPES = "RECIPES";
public static final String RECIPE_RECIPE = "RECIPE";
public static final String RECIPE_ID = "ID";
public static final String RECIPE_SOURCE = "SOURCE";
public static final String RECIPE_TITLE = "TITLE";
...............
public static final String RECIPE_ZERO_DOUGH = "ZERO_DOUGH";
public static final String RECIPE_IMAGE_1 = "IMAGE_1";
public static final String RECIPE_IMAGE_2 = "IMAGE_2";
//ITEMS IN TABLE: USER_SPECIFIC
public static final String TABLE_USER_SPECIFIC = "USER_SPECIFIC";
public static final String US_ID = "ID";
public static final String US_URL = "URL";
public static final String US_NOTES = "NOTES";
public static final String US_IS_FAVORITE = "IS_FAVORITE";
public Context context;
public DataBaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
this.context = context;
this.getReadableDatabase();
}
#Override
public void onCreate(SQLiteDatabase db) {
//CREATE RECIPES TABLE
String createTableStatement = "CREATE TABLE " + TABLE_RECIPES + " (" + RECIPE_ID + " INTEGER PRIMARY KEY " +
"AUTOINCREMENT, " + RECIPE_SOURCE + " TEXT, " + RECIPE_TITLE + " TEXT, " + RECIPE_URL + " TEXT, " + RECIPE_DATE + " TEXT, " + RECIPE_IMGLINKS + " TEXT, " + RECIPE_DESCRIPTION + " TEXT, " + RECIPE_INGREDIENTS + " TEXT, " + RECIPE_RECIPE + " TEXT, " + RECIPE_PREPTIME_TOTAL + " TEXT, " + RECIPE_PREPTIME_BAKETIME + " TEXT, " + RECIPE_MATCOST + " TEXT, " + RECIPE_OVERNIGHT + " INTEGER, " + RECIPE_FULL_GRAIN + " INTEGER, " + RECIPE_NO_KNEAD + " INTEGER, " + RECIPE_PASTRY_TYPE + " TEXT, " + RECIPE_DOUGHS + " TEXT, " + RECIPE_TASTE + " TEXT, " + RECIPE_PORES + " TEXT, " + RECIPE_FORM + " TEXT, " + RECIPE_ZERO_DOUGH + " TEXT, " + RECIPE_IMAGE_1 + " BLOB, " + RECIPE_IMAGE_2 + " BLOB)";
db.execSQL(createTableStatement);
Log.i("database", "TABLE_RECIPES created");
//CREATE USER_SPECIFIC TABLE
createTableStatement =
"CREATE TABLE " + TABLE_USER_SPECIFIC + " (" + US_ID + " INTEGER PRIMARY KEY, " + US_URL + " TEXT, " +
US_NOTES + " TEXT, " + US_IS_FAVORITE + " INTEGER)";
db.execSQL(createTableStatement);
Log.i("database", "TABLE_US created");
}
public boolean addOneUS(UserSpecificModel userSpecificModel){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(US_URL, userSpecificModel.getUrl());
cv.put(US_NOTES, userSpecificModel.getNote());
cv.put(US_IS_FAVORITE, userSpecificModel.getIs_favorite());
long insert = db.insert(TABLE_USER_SPECIFIC,null, cv);
if (insert == -1) {
return false;
} else {
return true;
}
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
/*SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("DROP TABLE IF EXISTS " + TABLE_RECIPES);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_USER_SPECIFIC);
onCreate(db);*/
}
public ArrayList<RecipeModel> getAllRecipes() {
ArrayList<RecipeModel> results = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
//String where = " where " + ContentDBManager.KEY_id + " = ? ";
Cursor cursor =
db.rawQuery("SELECT * FROM " + TABLE_RECIPES + " ORDER BY " + RECIPE_TITLE + " DESC", null);
if (cursor != null && cursor.getCount() > 0) {
try {
if (cursor.moveToFirst()) {
do {
RecipeModel recipeModel = new RecipeModel();
recipeModel.setId(cursor.getInt(0));
recipeModel.setSource(cursor.getString(1));
recipeModel.setUrl(cursor.getString(2));
recipeModel.setDate(cursor.getString(3));
recipeModel.setImglinks(cursor.getString(4));
recipeModel.setDescription(cursor.getString(5));
recipeModel.setIngredients(cursor.getString(6));
recipeModel.setRecipe(cursor.getString(7));
recipeModel.setPreptime_total(cursor.getString(8));
recipeModel.setPreptime_baketime(cursor.getString(9));
recipeModel.setMatcost(cursor.getString(10));
recipeModel.setOvernight(cursor.getInt(11));
recipeModel.setFull_grain(cursor.getInt(12));
recipeModel.setNo_knead(cursor.getInt(13));
recipeModel.setPastry_type(cursor.getString(14));
recipeModel.setDoughs(cursor.getString(15));
recipeModel.setTaste(cursor.getString(16));
recipeModel.setPores(cursor.getString(17));
recipeModel.setForm(cursor.getString(18));
recipeModel.setZero_dough(cursor.getString(19));
results.add(recipeModel);
} while (cursor.moveToNext());
}
}catch (Exception e){
e.printStackTrace();
}finally {
if (!cursor.isClosed()){
cursor.close();
}
}
} else {
if (cursor != null) {
Log.i("Database",
"Cursor is Null!");
cursor.close();
}
} // to free up memory of cursor
return results;
}
}
SplashActivity.java:
package com.android.baking.ui;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.SQLException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.Menu;
import com.android.baking.DataBaseHelper;
import com.android.baking.MainActivity;
import com.android.baking.R;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
public class SplashActivity extends MainActivity {
private static boolean splashLoaded = false;
private static String DB_PATH;
private static String DB_NAME;
private static final int SPLASH_TIME = 1000;
public final int WRITE_PERMISSION_REQUEST_CODE = 1110;
private final String[] NEEDED_PERMISSIONS = new String[]{
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!checkPermissions(NEEDED_PERMISSIONS)){
ActivityCompat.requestPermissions(SplashActivity.this, NEEDED_PERMISSIONS, WRITE_PERMISSION_REQUEST_CODE);
}else {
BackgroundTask backgroundTask = new BackgroundTask();
backgroundTask.execute();
}
if (!splashLoaded) {
setContentView(R.layout.splash_screen);
int secondsDelayed = 3;
new Handler().postDelayed(new Runnable() {
public void run() {
startActivity(new Intent(SplashActivity.this, MainActivity.class));
finish();
}
}, secondsDelayed * SPLASH_TIME);
splashLoaded = true;
} else {
Intent goToMainActivity = new Intent(SplashActivity.this, MainActivity.class);
goToMainActivity.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(goToMainActivity);
finish();
}
//copy database from assets to database folder if it does not exist
//see also: https://stackoverflow.com/questions/18805874/copy-database-from-assets-to-databases-folder/18806587
if (!doesDatabaseExist(this, DataBaseHelper.DB_NAME)){
DB_PATH = getApplicationInfo().dataDir + "/databases/";
DB_NAME = DataBaseHelper.DB_NAME;
copyDataBase(DB_NAME, DB_PATH);
}
}
private static boolean doesDatabaseExist(Context context, String dbName) {
File dbFile = context.getDatabasePath(dbName);
return dbFile.exists();
}
private void copyDataBase(String dbName, String dbPath)
{
Log.i("Database",
"New database is being copied to device!");
byte[] buffer = new byte[1024];
OutputStream myOutput = null;
int length;
// Open your local db as the input stream
InputStream myInput = null;
try
{
myInput = getApplicationContext().getAssets().open(dbName);
// transfer bytes from the inputfile to the
// outputfile
myOutput = new FileOutputStream(dbPath + dbName);
while((length = myInput.read(buffer)) > 0)
{
myOutput.write(buffer, 0, length);
}
myOutput.close();
myOutput.flush();
myInput.close();
Log.i("Database",
"New database has been copied to device!");
}
catch(IOException e)
{
e.printStackTrace();
}
}
// to get FaceFeature and FaceIdFeature.
private boolean checkPermissions(String[] neededPermissions) {
if (neededPermissions == null || neededPermissions.length == 0) {
return true;
}
boolean allGranted = true;
for (String neededPermission : neededPermissions) {
allGranted &= ContextCompat.checkSelfPermission(getApplicationContext(), neededPermission) == PackageManager.PERMISSION_GRANTED;
}
return allGranted;
}
private class BackgroundTask extends AsyncTask {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Object doInBackground(Object[] objects) {
try {
Thread.sleep(SPLASH_TIME);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Object[] values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case WRITE_PERMISSION_REQUEST_CODE:
if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
BackgroundTask backgroundTask = new BackgroundTask();
backgroundTask.execute();
}
break;
default:
break;
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == WRITE_PERMISSION_REQUEST_CODE && resultCode == RESULT_OK) {
BackgroundTask backgroundTask = new BackgroundTask();
backgroundTask.execute();
}
}
}
RecipeAdapter.java:
package com.android.baking.ui.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.android.baking.R;
import com.android.baking.ui.listeners.RecipeItemClickListener;
import com.android.baking.ui.models.RecipeModel;
import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
// Create the basic adapter extending from RecyclerView.Adapter
// Note that we specify the custom ViewHolder which gives us access to our views
// see: https://stackoverflow.com/questions/40584424/simple-android-recyclerview-example
public class RecipeAdapter extends
RecyclerView.Adapter<RecipeAdapter.ViewHolder> {
private Context recipeContext;
private ArrayList<RecipeModel> recipeList = new ArrayList<>();
private ArrayList<RecipeModel> recipeSearchList = new ArrayList<>();
private RecipeItemClickListener recipeListener;
public RecipeAdapter(Context context, ArrayList<RecipeModel> recipeContentList, RecipeItemClickListener listener) {
this.recipeContext = context;
this.recipeListener = listener;
this.recipeList.addAll(recipeContentList);
recipeSearchList.addAll(recipeList);
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(recipeContext).inflate(R.layout.item_recycler_view_recipes, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
final RecipeModel recipeModel = recipeList.get(position);
holder.tv_title.setText(recipeModel.getTitle());
}
#Override
public int getItemCount() {
return recipeList.size();
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder {
TextView tv_title;
public ViewHolder(View itemView) {
//ToDo: hier weitermachen
super(itemView);
tv_title = itemView.findViewById(R.id.item_title);
}
}
}
RecipeFragment.java:
package com.android.baking.ui.recipes;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.android.baking.DataBaseHelper;
import com.android.baking.MainActivity;
import com.android.baking.R;
import com.android.baking.ui.adapter.RecipeAdapter;
import com.android.baking.ui.listeners.RecipeItemClickListener;
import com.android.baking.ui.models.RecipeModel;
import java.util.ArrayList;
public class RecipesFragment extends Fragment {
private RecipesViewModel recipesViewModel;
private ArrayList<RecipeModel> recipeList = new ArrayList<>();
private static RecipesFragment mInstance;
DataBaseHelper dataBaseHelper = new DataBaseHelper(getContext());
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
recipesViewModel = new ViewModelProvider(this).get(RecipesViewModel.class);
View root = inflater.inflate(R.layout.fragment_recipes, container, false);
RecyclerView rec_recipes = root.findViewById(R.id.recipes_recycler_view);
rec_recipes.setLayoutManager(new LinearLayoutManager(getContext()));
recipeList = dataBaseHelper.getAllRecipes();
RecipeAdapter recipeAdapter = new RecipeAdapter(getContext(), recipeList, new RecipeItemClickListener() {
#Override
public void OnItemClicked(RecipeModel recipeModel) {
Toast.makeText(getContext(), "You clicked " + recipeModel.getTitle(), Toast.LENGTH_SHORT).show();
}
});
rec_recipes.setAdapter(recipeAdapter);
return root;
}
}
In RecipieFragment.DataBaseHelper, calling getContext() here it may be returning you a null, hence the NPE. Try creating the DataBaseHelper in onCreateView() instead.
Related
Another problem with my application in Android Studio. I try to add data in "SQLite", the code seems correct from my pov, considering that I'm at the beginning with programming java. It seems that something is wrong, does not show me the message "Added successfuly" and 'setText=" "' doesn't work.
Main java file - "MainFragment"
package com.example.licenta23;
import android.Manifest;
import android.app.Activity;
import android.app.AppComponentFactory;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
public class MainFragment extends Fragment {
EditText actv1, edtModel, actv2, actv3, actv4, edtFabricatie, edtPret;
Button btnChoose, btnAdd, btnList;
ImageView imageView3;
final int REQUEST_CODE_GALLERY = 999;
public static SQLiteHelper sqLiteHelper;
private List<MarcaItem> marcaList;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
init(view);
fillMarcaList();
AutoCompleteTextView editText = view.findViewById(R.id.actv1);
AutoCompleteMarcaAdapter adapter = new AutoCompleteMarcaAdapter(getActivity(), marcaList);
editText.setAdapter(adapter);
AutoCompleteTextView editText2 = view.findViewById(R.id.actv2);
ArrayAdapter<String> adapter2 = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, CAROSERIE);
editText2.setAdapter(adapter2);
AutoCompleteTextView editText3 = view.findViewById(R.id.actv3);
ArrayAdapter<String> adapter3 = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, COMBUSTIBIL);
editText3.setAdapter(adapter3);
AutoCompleteTextView editText4 = view.findViewById(R.id.actv4);
ArrayAdapter<String> adapter4 = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, CULOARE);
editText4.setAdapter(adapter4);
return view;
}
private void fillMarcaList() {
...
sqLiteHelper = new SQLiteHelper(getActivity(), "CarDB.sqlite", null, 1);
sqLiteHelper.queryData("CREATE TABLE IF NOT EXISTS CAR (Id INTEGER PRIMARY KEY AUTOINCREMENT, alegemarca VARCHAR, model VARCHAR, caroserie VARCHAR, combustibil VARCHAR, culoare VARCHAR, fabricatie VARCHAR, pret VARCHAR, image BLOG)");
btnChoose.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String[] permissions = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE};
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
return;
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(getActivity(), permission) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(permissions, REQUEST_CODE_GALLERY); // triggers onRequestPermissionsResult() each time a permission is granted in 'permissions'
} else {
Toast.makeText(getActivity(), "Permission Already Granted", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, REQUEST_CODE_GALLERY);
}
}
}
});
btnAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try{
sqLiteHelper.insertData(
actv1.getText().toString().trim(),
edtModel.getText().toString().trim(),
actv2.getText().toString().trim(),
actv3.getText().toString().trim(),
actv4.getText().toString().trim(),
edtFabricatie.getText().toString().trim(),
edtPret.getText().toString().trim(),
imageViewToByte(imageView3)
);
Toast.makeText(getActivity().getApplicationContext(), "Added successfully!", Toast.LENGTH_SHORT).show();
actv1.setText("");
edtModel.setText("");
actv2.setText("");
actv3.setText("");
actv4.setText("");
edtFabricatie.setText("");
edtPret.setText("");
imageView3.setImageResource(R.mipmap.ic_launcher);
}
catch (Exception e){
e.printStackTrace();
}
}
});
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == REQUEST_CODE_GALLERY) {
if(grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, REQUEST_CODE_GALLERY);
}
else {
Toast.makeText(getContext(), "You don't have permission to acces file location!", Toast.LENGTH_SHORT).show();
}
return;
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
#Override
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
if(requestCode == REQUEST_CODE_GALLERY && resultCode == Activity.RESULT_OK && data != null) {
Uri uri = data.getData();
try {
InputStream inputStream = getActivity().getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
imageView3.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
private void init(View view){
actv1 = (EditText) view.findViewById(R.id.actv1);
edtModel = (EditText) view.findViewById(R.id.edtModel);
actv2 = (EditText) view.findViewById(R.id.actv2);
actv3 = (EditText) view.findViewById(R.id.actv3);
actv4 = (EditText) view.findViewById(R.id.actv4);
edtFabricatie = (EditText) view.findViewById(R.id.edtFabricatie);
edtPret = (EditText) view.findViewById(R.id.edtPret);
btnChoose = (Button) view.findViewById(R.id.btnChoose);
btnAdd = (Button) view.findViewById(R.id.btnAdd);
btnList = (Button) view.findViewById(R.id.btnList);
imageView3 = (ImageView) view.findViewById(R.id.imageView3);
}
public static byte[] imageViewToByte(ImageView image) {
Bitmap bitmap = ((BitmapDrawable) image.getDrawable()).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
return byteArray;
}
}
SQLiteHelper :
package com.example.licenta23;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;
import androidx.annotation.Nullable;
public class SQLiteHelper extends SQLiteOpenHelper {
public SQLiteHelper(#Nullable Context context, #Nullable String name, #Nullable SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
public void queryData(String sql){
SQLiteDatabase database = getWritableDatabase();
database.execSQL(sql);
}
public void insertData(String alegemarca, String model, String caroserie, String combustibil, String culoare, String fabricatie, String pret, byte[] image) {
SQLiteDatabase database = getWritableDatabase();
String sql = "INSERT INTO CAR VALUES (NULL, ?, ?, ?, ?, ?, ?, ?)";
SQLiteStatement statement = database.compileStatement(sql);
statement.clearBindings();
statement.bindString(1, alegemarca);
statement.bindString(2, model);
statement.bindString(3, caroserie);
statement.bindString(4, combustibil);
statement.bindString(5, culoare);
statement.bindString(6, fabricatie);
statement.bindString(7, pret);
statement.bindBlob(8, image);
statement.executeInsert();
}
public Cursor getData(String sql){
SQLiteDatabase database = getReadableDatabase();
return database.rawQuery(sql, null);
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
Thanks!
From the look of it you should use database.prepareStatement statement.bindString just like in this tutorial
SQLiteStatement statement = database.prepareStatement(sql);
statement.clearBindings();
statement.setString(1, alegemarca);
statement.setString(2, model);
statement.setString(3, caroserie);
statement.setString(4, combustibil);
statement.setString(5, culoare);
statement.setString(6, fabricatie);
statement.setString(7, pret);
statement.setBytes(8, readFile(image));
statement.executeInsert();
PS: Note that I've changed your bindBlob to setBytes as it is said here
Try this one.this is my code.you replace according to your requirements
package com.softarena.alarmapplication.Database;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.softarena.alarmapplication.Models.AlarmModel;
import com.softarena.alarmapplication.Models.DaysModel;
import com.softarena.alarmapplication.Models.Fvt_dest_model;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
public class MainDatabase extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "alarmapp.db";
public static final int DATABASE_VERSION = 5;
public static final String TABLE_ALARM = "Alarm";
public static final String TABLE_DAYS = "weekDays";
public static final String TABLE_FVT_DEST = "fvt_destination";
public static final String COLUMN_ID = "id";
public static final String COLUMN_ALARM_TIME = "alarmtime";
public static final String COLUMN_ALARM_NAME = "alarmname";
public static final String COLUMN_ALARM_TUNE = "alarmtune";
public static final String COLUMN_START_LOC = "startloc";
public static final String COLUMN_START_LOC_LatLong = "startlatlong";
public static final String COLUMN_END_LOC = "endloc";
public static final String COLUMN_END_LOC_LatLong = "endlatlong";
public static final String COLUMN_TIME_TO_REACH = "timetoreach";
public static final String COLUMN_START_COUNTRY = "startcountry";
public static final String COLUMN_END_COUNTRY = "endcountry";
public static final String COLUMN_RADIUS = "radius";
public static final String COLUMN_SNOOZE_STATUS = "status";
public static final String COLUMN_LAST_RING_DATE = "ringdate";
public static final String COLUMN_TRANSPORT_TYPE = "travel_by";
public static final String CREATE_TABLE_ALARM =
"CREATE TABLE " + TABLE_ALARM + "("
+ COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ COLUMN_ALARM_TIME + " TEXT,"
+ COLUMN_ALARM_NAME + " TEXT,"
+ COLUMN_ALARM_TUNE + " TEXT,"
+ COLUMN_START_LOC + " TEXT,"
+ COLUMN_START_LOC_LatLong + " TEXT,"
+ COLUMN_END_LOC + " TEXT,"
+ COLUMN_END_LOC_LatLong + " TEXT,"
+ COLUMN_TIME_TO_REACH + " TEXT,"
+ COLUMN_START_COUNTRY + " TEXT,"
+ COLUMN_END_COUNTRY + " TEXT,"
+ COLUMN_RADIUS + " TEXT,"
+ COLUMN_SNOOZE_STATUS + " TEXT,"
+ COLUMN_LAST_RING_DATE + " TEXT, "
+ COLUMN_TRANSPORT_TYPE + " TEXT "
+ ")";
public MainDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL(CREATE_TABLE_ALARM);
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + TABLE_ALARM);
onCreate(sqLiteDatabase);
}
public boolean adddatainalarm(String alarmTime, String alarmName, String alarmtune, String startLoc, String startlatlong, String endLoc, String endlatlong, String timetoReach, String startCountry, String endCountry, String Radius, String Status, String date,String travelby) {
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
boolean add = false;
contentValues.put(COLUMN_ALARM_TIME, alarmTime);
contentValues.put(COLUMN_ALARM_NAME, alarmName);
contentValues.put(COLUMN_ALARM_TUNE, alarmtune);
contentValues.put(COLUMN_START_LOC, startLoc);
contentValues.put(COLUMN_START_LOC_LatLong, startlatlong);
contentValues.put(COLUMN_END_LOC, endLoc);
contentValues.put(COLUMN_END_LOC_LatLong, endlatlong);
contentValues.put(COLUMN_TIME_TO_REACH, timetoReach);
contentValues.put(COLUMN_START_COUNTRY, startCountry);
contentValues.put(COLUMN_END_COUNTRY, endCountry);
contentValues.put(COLUMN_RADIUS, Radius);
contentValues.put(COLUMN_SNOOZE_STATUS, Status);
contentValues.put(COLUMN_LAST_RING_DATE, date);
contentValues.put(COLUMN_TRANSPORT_TYPE, travelby);
try {
Long result = sqLiteDatabase.insert(TABLE_ALARM, null, contentValues);
if (result == -1) {
add = false;
} else {
add = true;
Log.d("Database : ", "Data add successfully");
}
} catch (Exception e) {
Log.d("Database error : ", "" + e);
}
return add;
}
}
I can't get the data from a database.
Can you help me, please?
Error Log :
1-10091/com.example.dogruprint.dogruprint2 E/AndroidRuntime﹕ FATAL EXCEPTION: main android.database.sqlite.SQLiteException: no such table: users (code 1): , while compiling: SELECT _id, u_name, u_pass FROM
users
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native
Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:882)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:493)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteQuery.(SQLiteQuery.java:37)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314)
at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1161)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1032)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1200)
at com.example.dogruprint.dogruprint2.Database.getThat(Database.java:123)
at com.example.dogruprint.dogruprint2.siparisekle$2.onClick(siparisekle.java:113)
at android.view.View.performClick(View.java:4084)
at android.view.View$PerformClick.run(View.java:16966)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
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:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
DATABASE.java
package com.example.dogruprint.dogruprint2;
import android.app.Dialog;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;
import java.sql.SQLException;
public class Database {
public static final String KEY_ROWID = "_id";
public static final String KEY_NAME = "u_name";
public static final String KEY_PASS = "u_pass";
private static final String DB_NAME = "app";
private static final String DB_TABLE = "users";
private static final int version = 1;
private SQLiteDatabase ourDatabase;
private DBHelper ourHelper;
private Context ourContext;
private SQLiteDatabase writableDatabase;
public Database(Context context) {
ourContext = context;
}
public SQLiteDatabase getWritableDatabase() {
return writableDatabase;
}
public class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context)
{
super(context, DB_NAME, null, version);
}
#Override
public void onCreate(SQLiteDatabase db) {
/*
final String CREATE_TABLE = " CREATE TABLE " + DB_TABLE + " ( " + KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT , "
+ KEY_NAME + " VARCHAR(255) , "
+ KEY_PASS + " VARCHAR(255) ,"
;
*/
String CREATE_USERS_TABLE = "CREATE TABLE " + DB_TABLE + "(" + KEY_ROWID +
" INTEGER PRIMARY KEY," + KEY_NAME + " TEXT," + KEY_PASS + " TEXT"
+ ");";
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXIST " + DB_TABLE);
}
}
public Database open() throws SQLException {
ourHelper = new DBHelper(ourContext);
ourDatabase = ourHelper.getWritableDatabase();
return this;
}
public Database close() {
ourHelper.close();
return this;
}
public void addThat(String name, String pass) {
ContentValues cv = new ContentValues();
cv.put(KEY_NAME, name);
cv.put(KEY_PASS, pass);
ourDatabase.insert(DB_TABLE, null, cv);
}
public String getThat()
{
String[] colomns = new String[]{KEY_ROWID,KEY_NAME,KEY_PASS};
Cursor c = ourDatabase.query(DB_TABLE,colomns,null,null,null,null,null);
int İROW = c.getColumnIndex(KEY_ROWID);
int İNAME= c.getColumnIndex(KEY_NAME);
int İPASS = c.getColumnIndex(KEY_PASS);
String result = "";
for(c.moveToFirst();!c.isAfterLast();c.moveToNext())
{
result = result + "name" + c.getString(İNAME) + "pass" + c.getString(İPASS)+"\n";
}
return result;
}
}
siparisekle.java
package com.example.dogruprint.dogruprint2;
import android.app.ActionBar;
import android.app.Activity;
import android.app.Dialog;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.sql.SQLException;
import static android.R.*;
public class siparisekle extends Activity {
private AutoCompleteTextView act1, act2, act3;
private EditText edittxt1;
EditText etName,etPass;
TextView tvResult;
Button bSave;
Button bShow;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_siparisekle);
final Database db = new Database(this);
install_elements();
bSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
boolean ok = true;
String name = etName.getText().toString();
String pass = etPass.getText().toString();
try {
db.open();
db.addThat(name, pass);
tvResult.setText(name + "Eklendi");
db.close();
} catch (Exception e) {
ok = false;
e.printStackTrace();
tvResult.setText("Sorun var");
} finally {
if (ok) {
Dialog d = new Dialog(siparisekle.this);
TextView tv = new TextView(siparisekle.this);
tv.setText("BASARILI");
d.setTitle("Sonuç");
d.setContentView(tv);
d.show();
}
}
}
});
bShow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
try {
db.open();
String data = db.getThat();
tvResult.setText(data);
db.close();
} catch (SQLException e)
{
Toast.makeText(getApplicationContext(),"Çağırmada Bir Sorun Oluştu",Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
});
}
protected void install_elements()
{
etName = (EditText) findViewById(R.id.etName);
etPass= (EditText) findViewById(R.id.etPass);
tvResult= (TextView) findViewById(R.id.tvResult);
bSave= (Button) findViewById(R.id.bSave);
bShow= (Button) findViewById(R.id.bShow);
}
}
The exception message says this:
no such table: users (code 1) while compiling "SELECT _id, u_name, u_pass FROM users"
It is looking for a table called "users" in the database, but it can't find one!
Either you haven't set up your database correctly (e.g. you haven't created the tables) or the schema (e.g. table names) for your database doesn't match what the application requires.
In fact, look at your onCreate method. All it is doing is creating and throwing away a string containing some SQL. You need to execute it ....
You really need to execute your table creation:
String CREATE_USERS_TABLE = "CREATE TABLE " + DB_TABLE + "(" + KEY_ROWID +
" INTEGER PRIMARY KEY," + KEY_NAME + " TEXT," + KEY_PASS + " TEXT" + ")";
db.execSQL(CREATE_USERS_TABLE);
You also need to call your onCreate() method inside your onUpgrade() method
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
db.execSQL("DROP TABLE IF EXIST " + DB_TABLE);
onCreate(db);
}
I would like my android app to display the contents of a text file onto a virtual table when the user clicks the "List All" button. I am using an example from the developer.android website on creating a virtual table. The programme is unable to run at the moment. Below is the code I am working with and a sample of the text file.Kindly let me know where I may have gone wrong. Many thanks.
CEMMainActivity.java
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.app.ListActivity;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.SimpleCursorAdapter;
import android.os.Build;
import android.provider.ContactsContract;
public class CEMMainActivity extends ActionBarActivity {
protected static final String FTS_TABLE_CREATE = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cemmain);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
}
.add(R.id.container, new PlaceholderFragment()).commit();
}
//Action once Find button is clicked
Button findequip = (Button)findViewById(R.id.findequip);
findequip.setOnClickListener(new OnClickListener() {
public void onClick(View f) {
public void onCreate(SQLiteDatabase list) {
SQLiteDatabase mDatabase = list;
mDatabase.execSQL(FTS_TABLE_CREATE);
loadEquipmentList();
}
}
});
fragment_cemmain.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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="clinical.equipment.monitor.CEMMainActivity$PlaceholderFragment" >
.......
<Button
android:id="#+id/listallequip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/cleartext"
android:layout_toRightOf="#+id/equipid"
android:onClick="listallequip"
android:text="#string/listallequip" />
</RelativeLayout>
DatabaseOpenHelper.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import android.content.Context;
import android.content.res.Resources;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.text.TextUtils;
import android.util.Log;
public class DatabaseOpenHelper {
private static final String TAG = "ListAllEquipment";
//The columns to be included in table
public static final String COL_TYPE = "EQUIPMENT TYPE";
public static final String COL_ID = "ID";
public static final String COL_LOCATION = "LOCATION";
public static final String COL_STATUS = "STATUS";
public static final String COL_TIME = "TIME";
private static final String DATABASE_NAME = "EQUIPMENT LIST";
private static final String FTS_VIRTUAL_TABLE = "FTS";
private static final int DATABASE_VERSION = 1;
private final DatabaseOpenHelper mDatabaseOpenHelper;
public DatabaseOpenHelper(Context context) {
// TODO Auto-generated constructor stub
}
public void Listalldatabase (Context context) {
mDatabaseOpenHelper = new DatabaseOpenHelper(context);
private static class DatabaseOpenHelper extends SQLiteOpenHelper {
private final Context mHelperContext;
private SQLiteDatabase mDatabase;
private static final String FTS_TABLE_CREATE =
"CREATE VIRTUAL TABLE " + FTS_VIRTUAL_TABLE +
" USING fts3 (" +
COL_TYPE + ", " +
COL_ID + ", " + COL_LOCATION + ", " + COL_STATUS +", " + COL_TIME + ")";
DatabaseOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
mHelperContext = context;
}
// populate the virtual table
private void loadEquipmentList() {
new Thread(new Runnable() {
public void run() {
try {
loadType();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}).start();
}
private void loadType() throws IOException {
final Resources resources = mHelperContext.getResources();
InputStream inputStream = resources.openRawResource(R.raw.info_sample);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
try {
String line;
while ((line = reader.readLine()) != null) {
String[] strings = TextUtils.split(line, "-");
if (strings.length < 5) continue;
long list = addItem(strings[0].trim(), strings[1].trim(), strings[2].trim(), strings[3].trim(), strings[4].trim());
if (list < 0) {
Log.e(TAG, "unable to add word: " + strings[0].trim());
}
}
} finally {
reader.close();
}
public long addItem (String type; String id; String location; String status; String time) {
ContentValues initialValues = new ContentValues();
initialValues.put(COL_TYPE, type);
initialValues.put(COL_ID, id);
initialValues.put(COL_LOCATION, location);
initialValues.put(COL_STATUS, status);
initialValues.put(COL_TIME, time);
return mDatabase.insert(FTS_VIRTUAL_TABLE, null, initialValues);
}
}
}
#Override
public void onUpgrade(SQLiteDatabase list, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
list.execSQL("DROP TABLE IF EXISTS " + FTS_VIRTUAL_TABLE);
onCreate(list);
}
}
}
info_sample.txt
Equipment Type Equipment ID Location Status Time
Infusion Pump 1234 2 On 12:00
Hoist 3645 1 Off 13:00
Bed 2563 3 Occupied 14:00
Change this..
setContentView(R.layout.activity_cemmain);
to
setContentView(R.layout.fragment_cemmain);
because Button is in fragment_cemmain.xml so setContentView should refer fragment_cemmain.xml
and remove
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
Im creating an app where users can enter the movies they own, to show in a listview, and for random picking a movie from that list.
Now what my problem is, that when clicking on an item in the listview a new activity opens op where the item clicked is the title in a textview. So far i can get the movie from the list who is number 1 to show, but that shows it's title no matter which list item I click, how can i get the specific name depending on what item is clicked?? Thanks in advance.
My Database class:
package com.example;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class MovieDatabaseHelper {
private static final String TAG = MovieDatabaseHelper.class.getSimpleName();
// database configuration
// if you want the onUpgrade to run then change the database_version
private static final int DATABASE_VERSION = 2;
private static final String DATABASE_NAME = "mymoviedatabase.db";
// table configuration
private static final String TABLE_NAME = "movie_table"; // Table name
private static final String MOVIE_TABLE_COLUMN_ID = "_id"; // a column named "_id" is required for cursor
private static final String MOVIE_TABLE_COLUMN_TITLE = "movie_title";
private static final String MOVIE_TABLE_COLUMN_YEAR = "production_year";
private DatabaseOpenHelper openHelper;
private SQLiteDatabase database;
// this is a wrapper class. that means, from outside world, anyone will communicate with MovieDatabaseHelper,
// but under the hood actually DatabaseOpenHelper class will perform database CRUD operations
public MovieDatabaseHelper(Context aContext) {
openHelper = new DatabaseOpenHelper(aContext);
database = openHelper.getWritableDatabase();
}
public void insertData (String aMovieTitle, String aMovieYear) {
// we are using ContentValues to avoid sql format errors
ContentValues contentValues = new ContentValues();
contentValues.put(MOVIE_TABLE_COLUMN_TITLE, aMovieTitle);
contentValues.put(MOVIE_TABLE_COLUMN_YEAR, aMovieYear);
database.insert(TABLE_NAME, null, contentValues);
}
//Retrieves all the records
public Cursor getAllData () {
String buildSQL = "SELECT * FROM " + TABLE_NAME + " ORDER BY " + MOVIE_TABLE_COLUMN_TITLE + " COLLATE NOCASE";
Log.d(TAG, "getAllData SQL: " + buildSQL);
return database.rawQuery(buildSQL, null);
}
// Retrieves specific record
public String getMovieTitle()
{
Cursor c =
database.query(TABLE_NAME,
new String[] { MOVIE_TABLE_COLUMN_TITLE }, null, null, null, null, null);
if (c.moveToFirst())
return c.getString(c.getColumnIndex(MOVIE_TABLE_COLUMN_TITLE ));
else
return "Nothing";
}
// Retrieves a random entry from the Database
public String getRandomMovie()
{
Cursor c = database.query(TABLE_NAME + " ORDER BY RANDOM() LIMIT 1",
new String[] { MOVIE_TABLE_COLUMN_TITLE }, null, null, null, null, null);
if(c.moveToFirst())
return c.getString(c.getColumnIndex(MOVIE_TABLE_COLUMN_TITLE ));
else
return "nothing";
}
//Check if record exist
//---deletes a particular record---
public void delete(int _id)
{
database.delete(TABLE_NAME, MOVIE_TABLE_COLUMN_ID+"="+_id, null);
}
//---updates a record---
public boolean updateRecord(long _id, String movie_title)
{
ContentValues args = new ContentValues();
args.put(MOVIE_TABLE_COLUMN_TITLE, movie_title);
return database.update(TABLE_NAME, args, MOVIE_TABLE_COLUMN_ID + "=" + _id, null) > 0;
}
// this DatabaseOpenHelper class will actually be used to perform database related operation
private class DatabaseOpenHelper extends SQLiteOpenHelper {
public DatabaseOpenHelper(Context aContext) {
super(aContext, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
// Create your tables here
String buildSQL = "CREATE TABLE " + TABLE_NAME + "( " + MOVIE_TABLE_COLUMN_ID + " INTEGER PRIMARY KEY, " +
MOVIE_TABLE_COLUMN_TITLE + " TEXT, " + MOVIE_TABLE_COLUMN_YEAR + " TEXT )";
Log.d(TAG, "onCreate SQL: " + buildSQL);
sqLiteDatabase.execSQL(buildSQL);
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
// Database schema upgrade code goes here
String buildSQL = "DROP TABLE IF EXISTS " + TABLE_NAME;
Log.d(TAG, "onUpgrade SQL: " + buildSQL);
sqLiteDatabase.execSQL(buildSQL); // drop previous table
onCreate(sqLiteDatabase); // create the table from the beginning
}
}
}
My listview class:
package com.example;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
//import android.widget.Button;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;
public class MyActivity extends Activity {
private CustomCursorAdapter customAdapter;
private MovieDatabaseHelper databaseHelper;
private static final int ENTER_DATA_REQUEST_CODE = 1;
private ListView listView;
MediaPlayer mp;
private static final String TAG = MyActivity.class.getSimpleName();
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.dblist);
databaseHelper = new MovieDatabaseHelper(this);
final MediaPlayer mp = MediaPlayer.create(MyActivity.this, R.raw.cartoon015);
listView = (ListView) findViewById(R.id.list_data);
ImageButton okay = (ImageButton) findViewById(R.id.okay);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id ) {
Intent i = new Intent(MyActivity.this,IMDb.class);
startActivity(i);
Log.d(TAG, "clicked on item: " + position);
}
}
);
okay.setOnClickListener
(new View.OnClickListener()
{
public void onClick(View v)
{
mp.start();
mp.setVolume((float) 0.3, (float) 0.3);
Intent intent = new Intent(MyActivity.this,MovieActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
}
);
// Database query can be a time consuming task ..
// so its safe to call database query in another thread
// Handler, will handle this stuff for you <img src="http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif?m=1129645325g" alt=":)" class="wp-smiley">
new Handler().post(new Runnable() {
#Override
public void run() {
customAdapter = new CustomCursorAdapter(MyActivity.this, databaseHelper.getAllData());
listView.setAdapter(customAdapter);
}
});
}
public void onClickEnterData(View btnAdd) {
final MediaPlayer mp = MediaPlayer.create(MyActivity.this, R.raw.cartoon015);
mp.start();
mp.setVolume((float) 0.1, (float) 0.1);
startActivityForResult(new Intent(this, EnterDataActivity.class), ENTER_DATA_REQUEST_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ENTER_DATA_REQUEST_CODE && resultCode == RESULT_OK) {
databaseHelper.insertData(data.getExtras().getString("tag_movie_title"), data.getExtras().getString("tag_movie_year"));
customAdapter.changeCursor(databaseHelper.getAllData());
}
}
}
My movie detail class:
package com.example;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
public class IMDb extends Activity {
TextView Movietitle;
private MovieDatabaseHelper databaseHelper;
MediaPlayer mp;
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.imdb);
Movietitle = (TextView) findViewById(R.id.movietitle);
databaseHelper = new MovieDatabaseHelper(this);
Button delete = (Button) findViewById(R.id.delete);
Movietitle.setText( databaseHelper.getMovieTitle());
}
}
Well, there is lot of code you are asking for. But I can tell you the steps
Create a Model Class for your movie,, where you can hold the db records
Create list of Model Class and then when you click the item, you get the position of record in list.
Your movie Model class must have getter and setter functions to retrieve record details.
i got nullPointerException when trying to fetch some data from database with rawQuery.
Here's an error:
03-11 18:09:01.522: E/AndroidRuntime(2057): Uncaught handler: thread
main exiting due to uncaught exception 03-11 18:09:01.532:
E/AndroidRuntime(2057): java.lang.NullPointerException 03-11
18:09:01.532: E/AndroidRuntime(2057): at
com.math.scan.FormulaModel.setFormulaList(FormulaModel.java:27)
Look at my code:
DbHelper
package com.math.scan;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
import android.content.Context;
import android.content.res.AssetManager;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DbHelper extends SQLiteOpenHelper{
public static final String TABLE_NAME = "formulas";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_UNKNOWN = "unknown";
public static final String COLUMN_FORMULA = "formula";
public static final String COLUMN_CTG = "ctg";
private static final String DB_NAME = "formulas.db";
private static int DB_VERSION = 1;
private static final String DB_CREATE = "CREATE TABLE "+TABLE_NAME+
"("+COLUMN_ID+" integer primary key autoincrement,"
+COLUMN_UNKNOWN+" text not null,"
+COLUMN_FORMULA+" text not null,"
+COLUMN_CTG+" text not null );";
public Context mCtx;
public DbHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
this.mCtx = context;
}
#Override
public void onCreate(SQLiteDatabase database) {
database.execSQL(DB_CREATE);
// reading formulas
AssetManager asset = mCtx.getAssets();
try {
InputStream input = asset.open("formulas");
int size = input.available();
byte[] buffer = new byte[size];
input.read(buffer);
input.close();
String content = new String(buffer);
Scanner scan = new Scanner(content);
String current;
String[] f = new String[2];
String[] formula = new String[2];
while(scan.hasNextLine()) {
current = scan.nextLine();
// get category
f = current.split("!!");
formula = f[1].split(" = ");
database.execSQL("INSERT INTO `formulas` VALUES (NULL, '"+formula[0]+"', '"+formula[1]+"', '"+f[0]+"');");
Log.d("DB", "INSERT INTO `formulas` VALUES (NULL, '"+formula[0]+"', '"+formula[1]+"', '"+f[0]+"');");
}
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(DbHelper.class.getName(),
"Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
FormulaModel
package com.math.scan;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
public class FormulaModel {
private SQLiteDatabase database;
private DbHelper dbHelper;
public FormulaModel(Context context) {
dbHelper = new DbHelper(context);
}
public void open() throws SQLException {
dbHelper.getWritableDatabase();
}
public void close() {
dbHelper.close();
}
public void setFormulaList(String ctg) {
open();
// app stops working here
Cursor cursor = database.rawQuery("SELECT unknown, formula FROM formulas WHERE ctg = '"+ctg+"'", null);
int results = cursor.getCount();
cursor.moveToFirst();
Global.FormuleResult = new String[results];
Global.FormuleTable = new String[results];
for(int i = 0; i < results; i++) {
Global.FormuleTable[i] = cursor.getString(1);
Global.FormuleResult[i] = cursor.getString(0);
}
close();
}
}
This is activity, where I call setFormulaList() method in FormulaModel class.
package com.math.scan;
import net.sourceforge.jeval.EvaluationException;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class ProblemActivity extends Activity {
private EditText prob;
private Button solve;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.problem);
// text field
prob = (EditText) findViewById(R.id.problem);
// confirm btn
solve = (Button) findViewById(R.id.solve);
// check if confirm button was pressed
solve.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// get text from the field
String problem = prob.getText().toString();
// check if expression is not empty
if(problem.length() == 0) {
// string is empty!
Toast.makeText(ProblemActivity.this, getString(R.string.empty_field), Toast.LENGTH_SHORT).show();
} else {
FormulaModel f = new FormulaModel(ProblemActivity.this);
f.setFormulaList("mech");
pears.doMagic(problem);
try {
String str = Global.eval.getVariableValue(Global.UNKNOWN);
TextView answ = (TextView) findViewById(R.id.answer);
answ.setText(getString(R.string.prob_answ) + str);
} catch (EvaluationException e) {
Toast.makeText(ProblemActivity.this, getString(R.string.prob_error), Toast.LENGTH_SHORT).show();
}
}
}
});
}
}
I can't figure out what is wrong here.
Any ideas?
You have to set your database variable in open():
database = dbHelper.getWritableDatabase();