Visualizza post

Questa sezione ti permette di visualizzare tutti i post inviati da questo utente. N.B: puoi vedere solo i post relativi alle aree dove hai l'accesso.


Post - brax

Pagine: [1]
1
Open Source / The Italian Said
« il: 11 Luglio 2017, 19:54:56 CEST »
grazie all'aiuto ricevuto su questo forum ho pubblicato la mia prima app nel play store (a breve anche su f-droid)!
Una collezione di proverbi tradotti più o meno seriamente in inglese

repo: https://github.com/francescosoave/TIS_android (per chi avesse voglia ci sono delle cose che non sono riuscito a implementare e sono nei todo del readme :D )
play store: https://play.google.com/store/apps/details?id=italian.said.fran.theitaliansaid
mio sito: francescosoave.com

2
Gestione dei dati / Re:inserire dati in db prima di avviare app
« il: 07 Luglio 2017, 18:48:43 CEST »
ok ho trisolto il discorso del path..a quanto pare funziona ma ho un'errore quando cerco di prelevare i dati.

Codice: [Seleziona]
public class DatabaseHandler extends SQLiteOpenHelper {
   
    private static final String DATABASE_NAME = "TIS_DB.db";
    private static final int DATABASE_VERSION = 1;
    private static final String TABLE_NAME = "table1";
    private static final String COL_0 = "Id";
    private static final String COL_1 = "one";
    private static final String COL_2 = "two";
    private final Context context;
   
    public DatabaseHandler(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        this.context = context;
    }
   
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" + COL_0 + " INTEGER PRIMARY KEY, " + COL_1 + " TEXT, " + COL_2 + " TEXT" + ")");
        db.execSQL("CREATE TABLE IF NOT EXISTS Fav (" + COL_0 + " INTEGER PRIMARY KEY, " + COL_1 + " TEXT, " + COL_2 + " TEXT" + ")");

        insertData();
    }
   
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(db);
    }
   
    private boolean insertData() {
        SQLiteDatabase db = this.getWritableDatabase();
   
        AssetManager mgr = this.context.getAssets();
        FileReader csv = null;
        String [] files = null;
   
        try {
            files = mgr.list("csv");
        } catch (IOException e) {
            e.printStackTrace();
        }
   
        try {
            csv = new FileReader(files[0]);
        } catch (IOException e) {
            e.printStackTrace();
        }
   
        BufferedReader buffer = new BufferedReader(csv);
        String line = "";
        String columns = "Id, one, two";
        String str1 = "INSERT INTO " + TABLE_NAME + " (" + columns + ") VALUES (";
        String str2 = ");";
   
        db.beginTransaction();
   
        try {
            while ((line = buffer.readLine()) != null) {
                StringBuilder sb = new StringBuilder(str1);
                String[] str = line.split(",");
                sb.append("'" + str[0] + "',");
                sb.append(str[1] + "',");
                sb.append(str[2] + "'");
                sb.append(str2);
                db.execSQL(sb.toString());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        db.setTransactionSuccessful();
        db.endTransaction();
       
        return true;
    }
   
    public Cursor getData() {
        SQLiteDatabase db = this.getWritableDatabase();
        String query = "SELECT * FROM " + TABLE_NAME;
        Cursor data = db.rawQuery(query, null);
        return data;
    }


l'errore di tipo getDatabased called recursively

Codice: [Seleziona]
FATAL EXCEPTION: main
                                                                                  Process: italian.said.fran.theitaliansaid, PID: 23803
                                                                                  java.lang.RuntimeException: Unable to start activity ComponentInfo{italian.said.fran.theitaliansaid/italian.said.fran.theitaliansaid.FavActivity}: java.lang.IllegalStateException: getDatabase called recursively
                                                                                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2728)
                                                                                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2814)
                                                                                      at android.app.ActivityThread.-wrap12(ActivityThread.java)
                                                                                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1527)
                                                                                      at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                      at android.os.Looper.loop(Looper.java:154)
                                                                                      at android.app.ActivityThread.main(ActivityThread.java:6290)
                                                                                      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.IllegalStateException: getDatabase called recursively
                                                                                      at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:203)
                                                                                      at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
                                                                                      at italian.said.fran.theitaliansaid.DatabaseHandler.insertData(DatabaseHandler.java:72)
                                                                                      at italian.said.fran.theitaliansaid.DatabaseHandler.onCreate(DatabaseHandler.java:46)
                                                                                      at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:251)
                                                                                      at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
                                                                                      at italian.said.fran.theitaliansaid.DatabaseHandler.getFav(DatabaseHandler.java:150)
                                                                                      at italian.said.fran.theitaliansaid.FavActivity.onCreate(FavActivity.java:28)
                                                                                      at android.app.Activity.performCreate(Activity.java:6760)
                                                                                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1134)
                                                                                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2681)
                                                                                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2814) 
                                                                                      at android.app.ActivityThread.-wrap12(ActivityThread.java) 
                                                                                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1527) 
                                                                                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                                      at android.os.Looper.loop(Looper.java:154) 
                                                                                      at android.app.ActivityThread.main(ActivityThread.java:6290) 
                                                                                      at java.lang.reflect.Method.invoke(Native Method)

3
Gestione dei dati / Re:inserire dati in db prima di avviare app
« il: 06 Luglio 2017, 15:07:41 CEST »
ottimo!

solo altre due domande relative ai db..dove lo metto il file db esterno? in quale cartella? e soprattutto (ci ho perso le ore ieri sera senza capire come si faccia davvero): come recupero i path relativi dei file nelle cartelle (tipo il mio file db esterno)? in giro ho letto almeno 5-6 risposte tutte diverse, a domande sui path  :D

grazie!! ho capito piu cose qui oggi che in una settimana di tutorial XD

4
Gestione dei dati / Re:inserire dati in db prima di avviare app
« il: 06 Luglio 2017, 14:31:24 CEST »
ok grazie..credo di aver capito in generale ma ho ancora un dubbio sulla SharedPreferences di cui non avevo mai sentito parlare.

dunque:
- app parte per la prima volta, crea il db locale copiando dal db esterno, salva la version (1) nelle SP
- app parte per la seconda volta. Devo fare il confronto di versione (se e uguale ignora e usa il db locale, altrimenti aggiorna il db). Ma su cosa lo faccio il confronto? Al momento la versione del db in uso e scritta solo nelle SP. Dove prendo il secondo valore per fare il confronto? Devo, ogni volta che rilascio una nuova versione del file db esterno, modificare la variabile
Codice: [Seleziona]
private static final int DATABASE_VERSION = 1; ?

5
Gestione dei dati / Re:inserire dati in db prima di avviare app
« il: 06 Luglio 2017, 12:25:32 CEST »
grazie, ho sbagliato terminologia (automaticamente era riferito al fatto che mi basta solo sostituire il fil db vecchio con quello nuovo), si avevo gia visto l'articolo per usare db esterni, ma non ho proceduto perche volevo capire prima quale fosse il modus operandi migliore o piu comune :)

adesso pero mi hai confuso con le ultime due righe :D ieri sera mentre smanettavo e facevo tentativi mi sono scontrato con il fatto del dover riscrivere il db.
(Per chiarezza quando dico "db esterno" mi riferisco a quello che creo io esternamente, "db locale" a quello dentro l'app in cui copiare quello esterno)

In particolare:
- il db locale dev'essere aggiornato SOLO quando quello esterno viene aggiornato. Non avrebbe senso che ogni volta che apro l'app copio lo stesso file .db nello stesso db locale. Il problema che avevo ieri notte era il "come" capire se il db esterno fosse stato aggiornato (cioe diverso, con piu righe - ne verranno sempre e solo aggiunte, mai tolte - ) rispetto a quello locale e se lo fosse, ri-eseguirne la copia in quello locale

- sono un po' confuso con l'upgrade..avevo capito che viene triggerato quando cambia il db locale, cioe specificando la versione ma non riesco a immaginare bene il flow dell'operazione. Correggimi se sbaglio:

1) la mia app e pubblicata, ha il suo db esterno che alla prima esecuzione (e solo in quella) e stato copiato nel db interno, version = 1
2) quando rilascio l'update con il nuovo db esterno (che avra le stesse row del vecchio piu altre row nuove) devo settare la versione = 2 (cioe hardcoded?) cosi:

Codice: [Seleziona]
public DatabaseHandler(Context context) {
        super(context, DATABASE_NAME, null, 2);
        this.context = context;
    }


e lui automaticamente mi chiama il onUpgrade (che cancella il db locale vecchio e richiama onCreate per copiare il nuovo db esterno).

e giusto questo percorso? Inoltre, nel onUpgrade al momento ho solo un drop table. devo fare anche drop database oppure basta cambiare la versione e automaticamente viene "sovrascritto"?

grazie!!!

B.

ps: scusa ma ho la tastiera senza lettere accentate :/

6
Gestione dei dati / Re:inserire dati in db prima di avviare app
« il: 06 Luglio 2017, 11:08:47 CEST »
ciao e grazie,

si, il db sara sempre solo in lettura. Ok quindi ricapitolando:

1) creo il mio db con i dati esternamente e lo metto fra gli assets
2) ad ogni startup dell'app faccio una query da cui tiro fuori tutti i dati dalla tabella e li metto nel mio cursor.
3) quando gli update dell'app saranno pronti (cioe ci saranno nuovi dati nel db) mi bastera aggiornare il mio file db e quando un'utente scarica l'update, il vecchio file .db verra sovrascritto da quello nuovo (questo succede in automatico giusto?)

una volta che ho il mio cursor contenente tutte le mie rows, posso sceglierne una a caso ad ogni swipe giusto? ho visto degli esempi con rand ma non ho capito se si possa specificare il seed ecc. Non vorrei che ogni volta che l'app si avvia i rand fossero sempre nello stesso ordine.

grazie!!

B.

7
Gestione dei dati / inserire dati in db prima di avviare app
« il: 05 Luglio 2017, 21:01:24 CEST »
Ciao, scusate per il titolo ma non saprei esattamente cosa scrivere. Il mio quesito non riguarda codice direttamente ma è più sul procedimento.
In pratica ho un app con un proprio database di dati che vengono mostrati all'utenti. E' tutto in locale, niente cloud ecc.
Al momento ho nella mia classe database_helper il metodo insert data per inserire dati però in realtà a me serve che quando l'app parta, il db sia già pieno. Inoltre durante i vari upgrade che farò all'app in futuro avrò bisogno di cambiare i dati contenuti nel db aggiungendo delle righe.
Qual'è il modo corretto per farlo considerando che ogni row è composta di 3 campi?


Le mie idee:

1) - creare un file .db sqlite "a mano" come file resource  e caricarlo ad ogni avvio dell'app
2) un file txt o csv e poi copiare i file nel db solo la prima volta che l'app viene avviata (cioè quando viene creato il db in locale) e quando il csv viene modificato (cioè faccio l'update dell'app)

Un'altra domanda leggermente diversa. L'app funziona in modo che ad ogni swipe mostra un dato preso da una riga scelta a random (il funzionamento è visivamente simile a Tinder ecc). Considerato che in tutto avrò circa 600 (max 1000 forse in futuro) righe nella tabella, mi conviene estrarre tutto con un'unica query all'avvio, memorizzare in un array (o un altro csv temporaneo?) e da questo prelevare ad ogni swipe, oppure mi conviene fare una query unica per ogni swipe?

grazie!

B.

edit: aggiunto dettagli

8
Activity, Fragment e Intent / Re:screen widget, intent e main activity
« il: 10 Giugno 2017, 02:16:35 CEST »
giusto, l'avevo messo mentre cercavo di capire la causa degli errori e l'ho dimenticato.
Dunque, sto cercando di fare il mio widget..ho trovato pochissimi tutorial che vadano al di là della semplice generazione del widget. Seguendo un tutorial che sembra fare una cosa simile a quello che serve a me, ho il codice seguente che non funziona (il widget non viene neanche più mostrato "Couldn't add widget"). Sto ancora cercando di capire cosa stia facendo effettivamente il codice. Se hai suggerimenti o qualche esempio da suggerire ne sarei felice :)

Codice: [Seleziona]
public class Widget extends AppWidgetProvider {
   
    public MyClass myObject;   
    private static final String SYNC_CLICKED = "WidgetImageClick";
   
    public int widBtnInsertData() {
        myObject.insertData();
        return myObject.getValue();
    }
   
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
 
        RemoteViews views;
        ComponentName componentName;
       
        views = new RemoteViews(context.getPackageName(), R.layout.widget);
        componentName = new ComponentName(context, Widget.class);
       
        views.setTextViewText(R.id.widBtnRst, String.valueOf(widBtnInsertData()));
   
        views.setOnClickPendingIntent(R.id.widBtnIns, getPendingSelfIntent(context, SYNC_CLICKED));
        appWidgetManager.updateAppWidget(componentName, views);
    }
   
    protected PendingIntent getPendingSelfIntent(Context context, String action){
       
        Intent intent = new Intent(context, getClass());
        intent.setAction(action);       
        return PendingIntent.getBroadcast(context, 0, intent, 0);
    }
   
    @Override
    public void onReceive(Context context, Intent intent){
        super.onReceive(context, intent);
   
        if(SYNC_CLICKED.equals(intent.getAction())){
            RemoteViews views;
            ComponentName componentName;
            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
           
            views = new RemoteViews(context.getPackageName(), R.layout.widget);
            componentName = new ComponentName(context, Widget.class);
   
            views.setTextViewText(R.id.widBtnRst, String.valueOf(widBtnInsertData()));

            appWidgetManager.updateAppWidget(componentName, views);
        }
    }
}

9
Activity, Fragment e Intent / Re:screen widget, intent e main activity
« il: 07 Giugno 2017, 22:31:06 CEST »
grazie ancora per l'aiuto. errore mio che non ho incluso tutto il codice. Sto passando il context alla mia classe (dal Main Activity). Per ora lascerei stare i service perchè rischio di incasinarmi ancora di più :D

questo è il mio costruttore

Codice: [Seleziona]
public class MyClass extends AppCompatActivity {
   
    private int value;
    private Context context;
   
    public MyClass (Context context){
        this.context = context;
        value = 0;
    }

e nella MainAcitvity

Codice: [Seleziona]
public class MainActivity extends AppCompatActivity {

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

        myObject = new MyClass(MainActivity.this);

grazie! :)

Post unito: 07 Giugno 2017, 23:04:24 CEST
ok, non avevo chiamato il metodo sul context. Perfetto ora funziona! Grazie mille intanto! Ora provo a fare lo stesso con il widget!
Grazie!!! :)

10
Activity, Fragment e Intent / Re:screen widget, intent e main activity
« il: 07 Giugno 2017, 12:35:39 CEST »
giusto, mi ero confuso. Ok ho scritto la mia classe e di base funziona ma ho un problema con la scrittura su file (quando lo stesso codice era nel main activity funzionava) e non sono sicuro se il problema sia il context o altro.

questo è l'errore

grazie! :)

Codice: [Seleziona]
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.FileOutputStream android.content.Context.openFileOutput(java.lang.String, int)' on a null object reference
                                                                               at android.content.ContextWrapper.openFileOutput(ContextWrapper.java:193)
                                                                               at com.example.fran.textfile.Counter.writeData(Counter.java:76)
                                                                               at com.example.fran.textfile.Counter.insertData(Counter.java:39)
                                                                               at com.example.fran.textfile.MainActivity.btnInsertData(MainActivity.java:31)
                                                                               at java.lang.reflect.Method.invoke(Native Method) 

nella mia classe custom, questo è il mio metodo per scrivere sul file

Codice: [Seleziona]
public void writeData(int value) {
        try {
            FileOutputStream file = null;
           
            try {
                file = openFileOutput("Data.txt", MODE_PRIVATE);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            OutputStreamWriter outputFile = new OutputStreamWriter(file);
           
            try {
                outputFile.write(String.valueOf(value));
            } catch (IOException e) {
                e.printStackTrace();
            }
           
            try {
                outputFile.flush(); //secure all bytes are written to the file
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                outputFile.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
           
            //Toast.makeText(context, "Successfully saved!", Toast.LENGTH_SHORT).show();
        } catch (IOError e) {
            //Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }

11
Activity, Fragment e Intent / Re:screen widget, intent e main activity
« il: 07 Giugno 2017, 00:29:50 CEST »
ciao e grazie! Effettivamente ha senso..un'altra domanda..nella widgetactivity la chiamata ai metodi della mia classe la metto nel onUpdate?

12
Activity, Fragment e Intent / screen widget, intent e main activity
« il: 06 Giugno 2017, 01:00:37 CEST »
ciao, sto sviluppando la mia prima app (editare un file txt). la main activity funziona correttamente e quello che mi interessa fare ora è aggiungere un widget da mettere sullo schermo. Seguendo tutorial ecc ho creato la activity per il widget (con un paio di buttons) ed è funzionante.
Quello che non riesco a capire è come usare i buttons del widget per interagire con la main activity (quindi editare il file di testo) SENZA aprire l'app. In pratica vorrei capire se, dal widget, posso chiamare un metodo della main activity senza che parta tutta l'app.

Ho visto qualche tutorial sugli intent ma nessuno che:
1) abbia il widget nella home
2) non faccia partire tutta l'altra activity

Immagino che essendo l'application semplice potrei forse riscrivere direttamente i metodi della main all'interno del widget e andando a modificare lo stesso file, ma vorrei prima capire qual'è il metodo corretto per proseguire

grazie :)

13
Stanza di Benvenuto / Buonasera
« il: 06 Giugno 2017, 00:54:34 CEST »
Buonasera, sono novizio di android (ma non in altri linguaggi) e sto scrivendo la mia prima app  :-)

ciao,

brax

Pagine: [1]