Extern databas, ger inga error bara crashar.

Diskussion i 'Frågor, support och diskussion' startad av rödgladan, 21 sept 2012.

  1. rödgladan

    rödgladan Infant Droid Medlem

    Blev medlem:
    21 sept 2012
    Inlägg:
    2
    Mottagna gillanden:
    0

    MINA ENHETER

    Hej (Ny här)!
    Jag försöker att använda mig av en extern databas (/data/data/com.example.test/databases/database.db) för att sedan kopiera över informationen från denna till appens.
    Jag tror felet ligger under SpeciesDbAdapter, men i så fall vad bör ändras och varför får jag INGET error i LogCat? För fel är det ju bevisligen, då den bara crashar.

    Under onCreate i Main-klassen
    Kod:
    private SpeciesDbAdapter dbHelper;
    dbHelper = new SpeciesDbAdapter(this);
        	
            try {
    			dbHelper.createDatabase();
    			dbHelper.open();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}  
    
    Då kallar jag på detta under SpeciesDbAdapter
    Kod:
    public class SpeciesDbAdapter extends SQLiteOpenHelper{
    		public static final String DB_SPECIE_ID = "_id";
    		public static final String DB_SCF_NAME = "scf_name";
    		public static final String DB_T_TRANS = "translated";
    		
    		private static String DB_PATH = "/data/data/com.example.test/databases/";
    		private static final String DB_NAME = "database.db";
    				
    		public static String LANGUAGE = Locale.getDefault().getLanguage();
    
    		private static SQLiteDatabase mDb;
    		
    		
    		private static final int DB_VERSION = 12;
    		
    		private final Context mCtx;
    		
    		
    		
    		public SpeciesDbAdapter(Context context) {
    		    super(context, DB_NAME, null, DB_VERSION);
    		    this.mCtx = context;
    		}
    		public void createDatabase() throws IOException {
    			boolean dbExist = checkDataBase();
    			if(dbExist) {
    				//do nothing - database already exist
    			} else {
    				//By calling this method and empty database will be created into the default system path
    				//of your application so we are gonna be able to overwrite that database with our database.
    				this.getReadableDatabase();
    				
    				try {
    					copyDataBase();
    				} catch(IOException e) {
    					throw new Error("Error copying database");
    				}
    			}
    		}
    		private boolean checkDataBase(){
    			SQLiteDatabase checkDB = null;
    			
    			try {
    				String myPath = DB_PATH + DB_NAME;
    				checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
    			} catch (SQLiteException e) {
    				
    			}
    			
    			if(checkDB != null) {
    				checkDB.close();
    			}
    			
    			return checkDB != null ? true : false;
    		}
    		private void copyDataBase() throws IOException {
    			//Open your local db as the input stream
    			InputStream myInput = mCtx.getAssets().open(DB_NAME);
    			
    			// Path to the just created empty db
    			String outFileName = DB_PATH + DB_NAME;
    			
    			// Open the empty db as the output stream
    			OutputStream myOutput = new FileOutputStream(outFileName);
    			
    			//transfer bytes from the inputfile to the outputfile
    			byte[] buffer = new byte[1024];
    			int length;
    			while((length = myInput.read(buffer))>0) {
    				myOutput.write(buffer, 0, length);
    			}
    			
    			// Close the streams
    			myOutput.flush();
    			myOutput.close();
    			myInput.close();
    		}
    		@Override
    		public void onCreate(SQLiteDatabase db) {
    			
    		}
    		@Override
    		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    		    onCreate(db);
    		}
    
    		
    		//Open the database
    		public void open() throws SQLException {
    			String myPath = DB_PATH + DB_NAME;
    			mDb = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
    		}
    		//Close the connection
    		public void close() {
    		    if (mDb != null) {
    		        mDb.close();
    		    }
    		}
    		public Cursor fetchAllSpecies() {
    			Cursor mCursor = mDb.rawQuery("select * from species s inner join translations t on s._id=t._id AND t.lang = '"+ LANGUAGE +"'", null);
    			Log.e("QUERY", "select * from species s inner join translations t on s._id=t._id AND t.lang = '"+ LANGUAGE +"'");
    		    if (mCursor != null) {
    		        mCursor.moveToFirst();
    		    }
    		    return mCursor;
    		}
    		public Cursor filterSpecies(String inputText) throws SQLException {
    			  Cursor mCursor = null;
    			  if (inputText == null  ||  inputText.length () == 0)  {
    				  mCursor = mDb.rawQuery("select * from species s inner join translations t on s._id=t._id AND t.lang = '"+ LANGUAGE +"'", null);
    			  }
    			  else {
    				  mCursor = mDb.rawQuery("select * from species s, translations t WHERE (t.lang = '"+ LANGUAGE +"' AND t.translated LIKE '%"+ inputText +"%') OR s.scf_name LIKE '%"+ inputText + "%'", null);
    			  }
    			  if (mCursor != null) {
    			   mCursor.moveToFirst();
    			  }
    			  return mCursor;
    		}
    }
     
  2. e7andy

    e7andy Professional Droid Hedersmedlem

    Blev medlem:
    14 okt 2009
    Inlägg:
    2 349
    Mottagna gillanden:
    835
    Telefon:
    Huawei P10 Plus

    MINA ENHETER

    Telefon:
    Huawei P10 Plus
    Telefon 2:
    Nexus 5
    Telefon 3:
    ADP1
    Övrigt:
    LG G Watch R, ChromeCast
    Spontant så tänkte jag på permissions, dvs. du måste ha lagt till READ_EXTERNAL_STORAGE, men bara om du kör Jelly Bean.
    Om det inte är permission-problem så tycker jag du ska debugga och stega dig till vilken metod det smäller på. Då får du tips på vad det handlar om och var man ska börja leta.

    Lägg även in bättre felhantering. Du har bland annat en tom catch och en catch där du kastar ett Error men utan att fånga det.
    Lägg breakpoints i alla catchar så ser du var fel uppstår.
     
    Last edited: 21 sept 2012
  3. Buzz

    Buzz Android Apprentice Medlem

    Blev medlem:
    14 maj 2010
    Inlägg:
    4 990
    Mottagna gillanden:
    2 258

    MINA ENHETER

    Om din telefon kör Android 4.1 och du använder en app LogCat så tror jag felet är där. Logcat-apparna fungerar inte i 4.1 utan du måste använda "adb logcat" på datorn.
     
  4. rödgladan

    rödgladan Infant Droid Medlem

    Blev medlem:
    21 sept 2012
    Inlägg:
    2
    Mottagna gillanden:
    0

    MINA ENHETER

    Testar i äldre version, samt så kör jag LogCat via emulator.
    Har någon koll på hur man ska göra en sådan här metod, att kopiera en databas (externt) till appens? För tanken är att min kommer innehålla en hel del värden...
     
  5. e7andy

    e7andy Professional Droid Hedersmedlem

    Blev medlem:
    14 okt 2009
    Inlägg:
    2 349
    Mottagna gillanden:
    835
    Telefon:
    Huawei P10 Plus

    MINA ENHETER

    Telefon:
    Huawei P10 Plus
    Telefon 2:
    Nexus 5
    Telefon 3:
    ADP1
    Övrigt:
    LG G Watch R, ChromeCast
    Jag hittade exemplet du har utgått ifrån:
    http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/
    Har du lagt din databasfil på rätt ställe, dvs. i assets-foldern?
    Kör debuggern och stega dig genom koden så bör du se direkt var det smäller.

    Vad menar du med en extern databas? I exemplet så ligger databasen i apk:n. Det är så du menar?
    Jag tycker nog att exemplet är en bra lösning om man vill göra på det sättet.
    En annan metod som många använder är att databasen laddas ner från en server första gången som användaren startar applikationen. Fördelen är att apk:n går snabbt att ladda hem. Nackdelen är att det kan ta tid att starta appen första gången.