Search code examples
androidandroid-sqlite

Database applications crashing


Currently creating an app that copies an sql database from assets and then allows me to query search it by year, movie name and show all results in a text view. Getting a fatal error that just crashes the application instantly and not sure what to do.. Included the lines that give me the error under the code.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.artis.sqldatabase.MainActivity">

<TableRow
    android:id="@+id/MainTable"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/ApplicationView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="Robin Williams Filmography"
        android:textColor="@android:color/black"
        android:textSize="18sp" />
</TableRow>

<TableRow
    android:id="@+id/SearchTable"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_below="@+id/MainTable">

    <EditText
        android:id="@+id/YearEdit"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="Year"
        android:inputType="number" />

    <EditText
        android:id="@+id/MovieEdit"
        android:layout_width="283dp"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="Movie Name"
        android:inputType="textPersonName" />
</TableRow>

<TableRow
    android:id="@+id/ButtonTable"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_below="@+id/SearchTable">

    <Button
        android:id="@+id/YearButton"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:text="Search By Year" />

    <Button
        android:id="@+id/MovieButton"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:text="Search By Movie" />

    <Button
        android:id="@+id/AllButton"
        android:layout_width="84dp"
        android:layout_height="wrap_content"
        android:text="All" />
</TableRow>

<TableRow
    android:id="@+id/ResultTable"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_below="@+id/ButtonTable" >

    <TextView
        android:id="@+id/ResultView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />
</TableRow>

</RelativeLayout>

MainActivity.java

    package com.example.artis.sqldatabase;

    import android.app.Activity;
    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;

    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;

public class MainActivity extends Activity
{
private static final String DATABASE_PATH =
        "/data/data/com.example.artis.sqldatabase/databases/";
private static final String DATABASE_PATH2 =
        "/data/data/com.example.artis.sqldatabase/databases";

private static final String DATABASE_NAME = "ActorsFilmography.db";
private static final String LOG_TAG = "FILMOGRAPHY_DB";
Context ctx;

OpenDatabase sqh;
SQLiteDatabase sqdb;

Button YearButton;
Button MovieButton;
Button AllButton;
EditText YearEdit;
EditText MovieEdit;
TextView ResultView;


@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    setUpDatabase();
    InitDataBase();
    SetupControls();
}

public void SetupControls()
{
    YearEdit = (EditText)findViewById(R.id.YearEdit);
    MovieEdit = (EditText)findViewById(R.id.MovieEdit);
    ResultView = (TextView)findViewById(R.id.ResultView);
    YearButton = (Button)findViewById(R.id.YearButton);
    MovieButton = (Button)findViewById(R.id.MovieButton);
    AllButton = (Button)findViewById(R.id.AllButton);

    AllButton.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View view)
        {
            ResultView.setText("");
            ResultView.setText(sqh.DisplayRecords(sqdb));
        }
    });

    YearButton.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            ResultView.setText("");
            ResultView.setText(sqh.DisplayRecordsBasedOnYear(sqdb, ResultView.getText().toString()));
        }
    });

    MovieButton.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            ResultView.setText("");
            ResultView.setText(sqh.DisplayRecordsBasedOnMovie(sqdb, ResultView.getText().toString()));
        }
    });
}


public void InitDataBase()
{
    sqh = new OpenDatabase(this);
    sqdb = sqh.getWritableDatabase();
}

public void setUpDatabase()
{
    ctx = this.getBaseContext();
    try
    {
        CopyDataBaseFromAsset();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}

public void CopyDataBaseFromAsset() throws IOException
{
    InputStream in = ctx.getAssets().open(DATABASE_NAME);
    Log.w( LOG_TAG , "Starting copying...");
    String outputFileName = DATABASE_PATH + DATABASE_NAME;
    File databaseFolder = new File( DATABASE_PATH2 );

    if ( !databaseFolder.exists() )
    {
        databaseFolder.mkdir();

        OutputStream out = new FileOutputStream(outputFileName);
        byte[] buffer = new byte[1024];
        int length;
        while ( (length = in.read(buffer)) > 0 )
        {
            out.write(buffer,0,length);
        }
        out.flush();
        out.close();
        in.close();
        Log.w(LOG_TAG, "Completed.");
        }
    }
}

OpenDatabase.java

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class OpenDatabase extends SQLiteOpenHelper
{
private static final String DATABASE_NAME = "src/main/ActorsFilmography.db";

private static final int DATABASE_VERSION = 1;

public static final String TABLE_NAME = "Filmography";

OpenDatabase(Context context)
{
    super( context, DATABASE_NAME, null, DATABASE_VERSION );
}

@Override
public void onCreate(SQLiteDatabase db)
{
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
}

public String DisplayRecords(SQLiteDatabase sqdb)
{
    String str = "";

    Cursor c = sqdb.rawQuery("SELECT * FROM Filmography", null);
    if (c != null)
    {
        if (c.moveToFirst())
        {
            do
            {
                String id = c.getString(0);
                str = str + id + ",";
                String Year = c.getString(1);
                str = str + Year + ",";
                String FilmTitle = c.getString(4);
                str = str + FilmTitle + "\n";
                Log.w("FILMOGRAPHY", "ID = " + id + " Songtitle = " + Year + " Movie Title = " + FilmTitle);
            } while (c.moveToNext());
        }
    }
    c.close();
    return str;
}

public String DisplayRecordsBasedOnYear(SQLiteDatabase sqdb, String searchYear)
{
    String str = "";

    Cursor c = sqdb.rawQuery("SELECT * FROM Filmography WHERE YEAR = '" + searchYear + "';", null);
    if (c != null)
    {
        if (c.moveToFirst())
        {
            do
            {
                String id = c.getString(0);
                str = str + id + ",";
                String Year = c.getString(1);
                str = str + Year + ",";
                String FilmTitle = c.getString(4);
                str = str + FilmTitle + "\n";
                Log.w("FILMOGRAPHY", "ID = " + id + " Songtitle = " + Year + " Movie Title = " + FilmTitle);
            } while (c.moveToNext());
        }
        else
        {
            str = "No records found";
        }
    }
    c.close();
    return str;
}

public String DisplayRecordsBasedOnMovie(SQLiteDatabase sqdb, String searchFilmTitle)
{
    String str = "";

    Cursor c = sqdb.rawQuery("SELECT * FROM Filmography WHERE MOVIE = '" + searchFilmTitle + "';", null);
    if (c != null)
    {
        if (c.moveToFirst())
        {
            do
            {
                String id = c.getString(0);
                str = str + id + ",";
                String Year = c.getString(1);
                str = str + Year + ",";
                String FilmTitle = c.getString(4);
                str = str + FilmTitle + "\n";
                Log.w("FILMOGRAPHY", "ID = " + id + " Songtitle = " + Year + " Movie Title = " + FilmTitle);
            } while (c.moveToNext());
        }
        else
        {
            str = "No records found";
        }
    }
    c.close();
    return str;
    }
}

My current errors that im getting are in MainActivity.java 48th and 96th line. which are:

InitDataBase(); and sqdb = sqh.getWritableDatabase();

application just crashes.. logcat:

12-01 22:11:33.806 3784-3784/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.artis.sqldatabase, PID: 3784
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.artis.sqldatabase/com.example.artis.sqldatabase.MainActivity}: java.lang.IllegalArgumentException: File src/main/ActorsFilmography.db contains a path separator
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.IllegalArgumentException: File src/main/ActorsFilmography.db contains a path separator
at android.app.ContextImpl.makeFilename(ContextImpl.java:2165)
at android.app.ContextImpl.getDatabasePath(ContextImpl.java:695)
at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:644)
at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:289)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
at com.example.artis.sqldatabase.MainActivity.InitDataBase(MainActivity.java:96)
at com.example.artis.sqldatabase.MainActivity.onCreate(MainActivity.java:48)
at android.app.Activity.performCreate(Activity.java:6679)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 
at android.app.ActivityThread.-wrap12(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6119) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

Solution

  • The problem is your DB name.
    You declared:

    private static final String DATABASE_NAME = "src/main/ActorsFilmography.db";
    

    This contains a path separator (i.e. '/'). This is not allowed.
    If you change it to ActorsFilmography it'll probably fix this problem (without the .db because it'll already set the extension as .db since it's a database).