Autore Topic: Classe con utility comuni....non funziona :-(  (Letto 1249 volte)

Offline Vytek

  • Translate Team
  • Utente junior
  • **
  • Post: 125
  • Respect: +6
    • Mostra profilo
  • Dispositivo Android:
    Samsung S5
  • Sistema operativo:
    Windows 8.1
Classe con utility comuni....non funziona :-(
« il: 12 Giugno 2010, 11:12:56 CEST »
0
Salve a tutti,
sto cercando di realizzare una classe che possa contenere tutte le funzioni di utility più utili ed utilizzate. Tuttavia ho seri problemi nella compilazione che non riesco a risolvere. Ho fatto una semplice raccolta nulla di più, ma non funziona soprattutto le funzioni relative al controllo se c'e' il collegamento internet :-(

Ho ovvimente messo nel mio AndroidManifest.xml i seguenti permessi:

Codice (XML): [Seleziona]
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>

Che ne dite?? Non riesco a capire prechè non si compili? Mancano degli import?

Un saluto e grazie di tutto...

P.S. Dimenticavo le fonti molto utili:

Android Snippets: Check if the network is available
Android Tips for Developers: Checking Network Availability
Android Snippets: have Internet?

Codice (Java): [Seleziona]
package com.google.android.almanac;

import java.util.Calendar;
import java.util.GregorianCalendar;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;

public class AlmanacUtility {
       
        //La scheda è presente
        public static boolean isSdPresent() {
            return android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
        }
       
        //Calcolo età
        public int getAge (int _year, int _month, int _day) {
               
                GregorianCalendar cal = new GregorianCalendar();
                int y, m, d, a;        

                y = cal.get(Calendar.YEAR);
                m = cal.get(Calendar.MONTH);
                d = cal.get(Calendar.DAY_OF_MONTH);
                cal.set(_year, _month, _day);
                a = y - cal.get(Calendar.YEAR);
                if ((m < cal.get(Calendar.MONTH))
                                || ((m == cal.get(Calendar.MONTH)) && (d < cal
                                                .get(Calendar.DAY_OF_MONTH)))) {
                        --a;
                }      
                if(a < 0)
                        throw new IllegalArgumentException("Age < 0");
                return a;
        }
       
        public StringBuffer SDKVersionInfo() {
                StringBuffer buf = new StringBuffer();
            buf.append("VERSION.RELEASE {"+Build.VERSION.RELEASE+"}");
            buf.append("\nVERSION.INCREMENTAL {"+Build.VERSION.INCREMENTAL
        +"}");
            buf.append("\nVERSION.SDK {"+Build.VERSION.SDK+"}");
            buf.append("\nBOARD {"+Build.BOARD+"}");
            buf.append("\nBRAND {"+Build.BRAND+"}");
            buf.append("\nDEVICE {"+Build.DEVICE+"}");
            buf.append("\nFINGERPRINT {"+Build.FINGERPRINT+"}");
            buf.append("\nHOST {"+Build.HOST+"}");
            buf.append("\nID {"+Build.ID+"}");
            return buf;
        }
       
        public boolean isNetworkAvailable() {
                   Context context = getApplicationContext();
                   ConnectivityManager connectivity = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
                   if (connectivity == null) {
                      boitealerte(this.getString(R.string.alert),"getSystemService rend null");
                   } else {
                      NetworkInfo[] info = connectivity.getAllNetworkInfo();
                      if (info != null) {
                         for (int i = 0; i < info.length; i++) {
                            if (info[i].getState() == NetworkInfo.State.CONNECTED) {
                               return true;
                            }
                         }
                      }
                   }
                   return false;
        }
       
        /*
        *@return boolean return true if the application can access the internet
        */

        private boolean haveInternet(){
                NetworkInfo info=(NetworkInfo)((ConnectivityManager)parent.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
                if(info==null || !info.isConnected()){
                        return false;
                }
                if(info.isRoaming()){
                        //here is the roaming option you can change it if you want to disable internet while roaming, just return false
                        return true;
                }
                return true;
        }


}
« Ultima modifica: 12 Giugno 2010, 12:00:52 CEST da Vytek »

Offline blackgin

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 1387
  • Respect: +164
    • Google+
    • blackgins
    • blackginsoft
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Nexus
  • Sistema operativo:
    Mac OSX 10.8
Re:Classe con utility comuni....non funziona :-(
« Risposta #1 il: 12 Giugno 2010, 21:09:25 CEST »
+1
Cosí a caldo ti direi di controllare le resources e xml vari. Di solito i problemi sono lá se eclipse non ne evidenzia
Postate il LogCat LogCat LogCat LogCat LogCat

Offline 7h38ugg3r

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 1200
  • Respect: +133
    • riccardofischetti
    • th38ugg3r
    • @7h38ugg3r
    • Mostra profilo
  • Dispositivo Android:
    Galaxy-S GT I-9000/ ASUS Eee Pad Transformer
  • Play Store ID:
    Riccardo Fischetti
  • Sistema operativo:
    OS X Lion / Linux Mint 11 (Katya)
Re:Classe con utility comuni....non funziona :-(
« Risposta #2 il: 14 Giugno 2010, 10:17:12 CEST »
0
Potresti farci capire meglio quali sono i problemi di compilazione che ti segnala eclipse?
Potrebbero essere un punto di partenza.
7h38ugg3r<=>thebugger
Non conosci Java? Allora sei nel posto sbagliato!

http://www.androidpatterns.com/

Offline Vytek

  • Translate Team
  • Utente junior
  • **
  • Post: 125
  • Respect: +6
    • Mostra profilo
  • Dispositivo Android:
    Samsung S5
  • Sistema operativo:
    Windows 8.1
Re:Classe con utility comuni....non funziona :-(
« Risposta #3 il: 14 Giugno 2010, 10:34:23 CEST »
0
Si scusate sono stato poco esaustivo.
Mi vengono segnalati problemi su:

Context context = getApplicationContext();

Il metodo "getApplicationContext();" non viene riconosciuto. (Come mai?) Ho fatto una nuova funzione in cui passo il Context, credo sia più corretta. Stasera vi mando la nuova versione, così mi dite se sto concettualmente andando nella direzione giusta.

Analogo errore in:
NetworkInfo info=(NetworkInfo)((ConnectivityManager)parent.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();

"parent" non viene riconosciuto.

Credo di aver fatto degli errori concettuali.

Grazie dell'aiuto.
Un saluto...

Offline 7h38ugg3r

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 1200
  • Respect: +133
    • riccardofischetti
    • th38ugg3r
    • @7h38ugg3r
    • Mostra profilo
  • Dispositivo Android:
    Galaxy-S GT I-9000/ ASUS Eee Pad Transformer
  • Play Store ID:
    Riccardo Fischetti
  • Sistema operativo:
    OS X Lion / Linux Mint 11 (Katya)
Re:Classe con utility comuni....non funziona :-(
« Risposta #4 il: 14 Giugno 2010, 12:14:48 CEST »
+1
A occhio, la getApplicationContext() non viene riconosciuta perché la tua classe non la definisce e non avendone estesa una con una possibile implementazione, è normale che ti dia errori.
Passare il context può essere una soluzione.

Per quanto riguarda il secondo, ovvero la ricerca del parent, dovresti vedere da quale esempio hai preso il tuo codice, perché sicuramente la classe dalla quale hai preso spunto dichiara un oggetto di qualche tipo chiamandolo parent. Devi solo capire che oggetto è e, se possibile, instanziarne uno tu stesso.

Fammi sapere come va.
7h38ugg3r<=>thebugger
Non conosci Java? Allora sei nel posto sbagliato!

http://www.androidpatterns.com/

Offline Vytek

  • Translate Team
  • Utente junior
  • **
  • Post: 125
  • Respect: +6
    • Mostra profilo
  • Dispositivo Android:
    Samsung S5
  • Sistema operativo:
    Windows 8.1
Re:Classe con utility comuni....non funziona :-(
« Risposta #5 il: 14 Giugno 2010, 22:06:00 CEST »
0
Rimetto di seguito il codice che ho modificato eliminando i Context e lasciando che siano passati dal chiamante.
Che dite occupo troppa memoria ad utilizzare tutte chiamate "static"? In generale vi sembra corretto soprattutto la funzione che controlla se si ha qualche tipo di network attivo? Che ve ne pare?

Un saluto e scusate il ritardo...

Codice (Java): [Seleziona]
package com.google.android.almanac;

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;

import android.content.Context;
import android.location.Location;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.util.Log;

public class AlmanacUtility {
       
        //La scheda SD è presente?
        /*
        *@return boolean return true if the application can access the SDCARD on phone
        */

        //Modify from: [url=http://www.androidsnippets.org/snippets/10/]Android Snippets: Check if SD card is present[/url]
        public static boolean isSdPresent() {
            return android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
        }
       
        //Calcolo età
        /*
        *@return int return age from date (year, month, day)
        */

        //http://www.androidsnippets.org/snippets/179/
        public static int getAge (int _year, int _month, int _day) {   
                GregorianCalendar cal = new GregorianCalendar();
                int y, m, d, a;        

                y = cal.get(Calendar.YEAR);
                m = cal.get(Calendar.MONTH);
                d = cal.get(Calendar.DAY_OF_MONTH);
                cal.set(_year, _month, _day);
                a = y - cal.get(Calendar.YEAR);
                if ((m < cal.get(Calendar.MONTH))
                                || ((m == cal.get(Calendar.MONTH)) && (d < cal
                                                .get(Calendar.DAY_OF_MONTH)))) {
                        --a;
                }      
                if(a < 0)
                        throw new IllegalArgumentException("Age < 0");
                return a;
        }
       
        /*
        *@return string with all SDK Info
        */

        //Modify from: [url=http://www.androidsnippets.org/snippets/190/]Android Snippets: Get the phone SDK version [/url]
        public static StringBuffer SDKVersionInfo() {
                StringBuffer buf = new StringBuffer();
            buf.append("VERSION.RELEASE {"+Build.VERSION.RELEASE+"}");
            buf.append("\nVERSION.INCREMENTAL {"+Build.VERSION.INCREMENTAL+"}");
            buf.append("\nVERSION.SDK {"+Build.VERSION.SDK+"}");
            buf.append("\nBOARD {"+Build.BOARD+"}");
            buf.append("\nBRAND {"+Build.BRAND+"}");
            buf.append("\nDEVICE {"+Build.DEVICE+"}");
            buf.append("\nFINGERPRINT {"+Build.FINGERPRINT+"}");
            buf.append("\nHOST {"+Build.HOST+"}");
            buf.append("\nID {"+Build.ID+"}");
            return buf;
        }
       
        /*
        *@return boolean return true if the application can access the network
        */

        //Modify from: [url=http://www.androidsnippets.org/snippets/78/]Android Snippets: Check if the network is available[/url]
        public static boolean isNetworkAvailable(Context context) {
                   //Remember on: Context context = getApplicationContext();
                   ConnectivityManager connectivity = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
                   if (connectivity == null) {
                      Log.e("AlmanacUtility:Error", "getSystemService rend null");
                   } else {
                      NetworkInfo[] info = connectivity.getAllNetworkInfo();
                      if (info != null) {
                         for (int i = 0; i < info.length; i++) {
                            if (info[i].getState() == NetworkInfo.State.CONNECTED) {
                               return true;
                            }
                         }
                      }
                   }
                   return false;
        }
       
        /*
        *@return boolean return true if the application can access the internet
        */

        //TO DO: Da rivedere questa funzione...
        //Modify from: [url=http://www.androidsnippets.org/snippets/131/]Android Snippets: have Internet?[/url]
        public static boolean haveInternet(Context context){
                NetworkInfo info=(NetworkInfo)((ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
                if(info==null || !info.isConnected()){
                        return false;
                }
                if(info.isRoaming()){
                        //here is the roaming option you can change it if you want to disable internet while roaming, just return false
                        return true;
                }
                return true;
        }
       
        /*
        *@return double[] return the GPS Long, Lat of last location
        */

        //TO DO: Da rivedere questa funzione...(forse inutile se GPS spento :-(
        //Modify from: [url=http://www.androidsnippets.org/snippets/21/]Android Snippets: Get the phone's last known location using LocationManager[/url]
        public static double[] getGPS(Context context) {
                LocationManager lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);  
                // This fetches a list of available location providers
                List<String> providers = lm.getProviders(true);

                /* Loop over the array backwards, and if you get an accurate location, then break out the loop*/
                Location l = null;
               
                for (int i=providers.size()-1; i>=0; i--) {
                        l = lm.getLastKnownLocation(providers.get(i));
                        if (l != null) break;
                }
               
                double[] gps = new double[2];
                if (l != null) {
                        gps[0] = l.getLatitude();
                        gps[1] = l.getLongitude();
                }
                return gps;
        }
       
}

Offline Agafi

  • Utente normale
  • ***
  • Post: 173
  • Respect: +10
    • svetlana-tomasevschi-perini
    • agafist
    • Mostra profilo
  • Dispositivo Android:
    SE Xperia Neo,LG Optimus One,Asus EEE Pad Transformer,HTC Magic Vodafone
  • Play Store ID:
    Agafi
  • Sistema operativo:
    Win7
Re:Classe con utility comuni....non funziona :-(
« Risposta #6 il: 15 Giugno 2010, 09:04:26 CEST »
+2
Prova ad utilizzare il pattern Singleton per implementare la classe (i Java di solito le classi "all static" si implemntano così per dare una parvenza di ObjetcOriented...

ecco uno paccato di esempio di Singleton
Codice (Java): [Seleziona]
public class AlmanacUtility {
      private static AlmanacUtility instance=null;
      ....
      private AlmanacUtility(){
           super();
      }
      ...
      public static final AlmanacUtility getInstance(){
            if (instance==null){
                instance=new AlmanacUtility();
            }
            return instance;
      }
      ...
      //a questo punto puoi togliere a tutti gli altri metodi l'attribuyto static
}

Quando qualcuno la richiamerà userà la seguente firma:

Codice (Java): [Seleziona]
  AlmanacUtility alamanc=AlmanacUtility.getInstance();
  alamanc.isSdPresent();



 
« Ultima modifica: 26 Agosto 2010, 10:24:13 CEST da JD, Reason: private static AlmanacUtility instance=null; »

Offline Vytek

  • Translate Team
  • Utente junior
  • **
  • Post: 125
  • Respect: +6
    • Mostra profilo
  • Dispositivo Android:
    Samsung S5
  • Sistema operativo:
    Windows 8.1
Re:Classe con utility comuni....non funziona :-(
« Risposta #7 il: 15 Giugno 2010, 15:09:23 CEST »
0
Ottimo grazie!!

Mi sembra un'ottima idea, riscrivo la classe come mi hai detto e ci aggiungo altre funzioni che ho trovato. Mi sembra una classe utile che possa essere riutilizzata in altri progetti. Comunque la mi applicazione sarà open source quindi quando avrò finito trovate tutto nel repository. Appena finita riposto il tutto così mi dici se ho capito bene e magari qualcuno la troverà utile e potrà segnalare altre funzioni da inserire.

Un saluto e grazie mille dei consigli....

Offline JD

  • Amministratore
  • Utente storico
  • *****
  • Post: 1600
  • Respect: +232
    • leinardi
    • Mostra profilo
  • Dispositivo Android:
    LG Nexus 5
  • Sistema operativo:
    L'ultima Ubuntu
Re:Classe con utility comuni....non funziona :-(
« Risposta #8 il: 26 Agosto 2010, 10:19:58 CEST »
0
Codice (Java): [Seleziona]
private AlmanacUtility instance=null;
Ma non dovrebbe essere static?

http://it.wikipedia.org/wiki/Singleton#Esempio:_Java
È stata trovata una soluzione al tuo problema?
Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato ;).
E se hai aperto tu il thread marcalo come risolto cliccando !

Offline Agafi

  • Utente normale
  • ***
  • Post: 173
  • Respect: +10
    • svetlana-tomasevschi-perini
    • agafist
    • Mostra profilo
  • Dispositivo Android:
    SE Xperia Neo,LG Optimus One,Asus EEE Pad Transformer,HTC Magic Vodafone
  • Play Store ID:
    Agafi
  • Sistema operativo:
    Win7
Re:Classe con utility comuni....non funziona :-(
« Risposta #9 il: 26 Agosto 2010, 10:23:01 CEST »
0
si mi era sfuggito lo static scrivendo il pezzo di codice al volo ;-)

Offline MarcoDuff

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 1073
  • Respect: +202
    • Google+
    • marcoduff
    • Mostra profilo
    • MarcoDuff's Blog
  • Dispositivo Android:
    Samsung Galaxy Nexus
  • Play Store ID:
    MarcoDuff
  • Sistema operativo:
    Windows 7
Re:Classe con utility comuni....non funziona :-(
« Risposta #10 il: 26 Agosto 2010, 11:27:22 CEST »
+1
E' da parecchio che noto in questo forum la creazione errata del Singleton, fino ad adesso non sono intervenuto perché non capivo se era un semplice errore di distrazione o una conoscenza errata dell'oggetto. Finalmente ho avuto la risposta, la seconda!

Ho le solite conferme:
  • Tutto quello che c'è scritto su wikipedia è da prendere con le pinze;
  • I testi in inglese sono sempre superiori a quelli in italiano (e di molto!).

La definizione di un Singleton fatta in questo modo:
Codice (Java): [Seleziona]
public class AlmanacUtility {
      private static AlmanacUtility instance=null;

      private AlmanacUtility(){
           super();
      }

      public static final AlmanacUtility getInstance(){
            if (instance==null){
                instance=new AlmanacUtility();
            }
            return instance;
      }
}

è estremamente errata! Questo non è un Singleton e può creare errori estremamente gravi e difficili da individuare.

Mentre la definizione di Singleton data su wikipedia (italia):
Codice (Java): [Seleziona]
public class MioSingolo {
    private static MioSingolo istanza = null;
 
    private MioSingolo() {}
 
    public static synchronized MioSingolo getMioSingolo() {
        if (istanza == null)
            istanza = new MioSingolo();
        return istanza;
    }
}

è (quasi) un Singleton, ma è prestazionalmente scadente.

La definizione di Singleton data su wikipedia (inglese) è invece (la prima delle tre proposte):
Codice (Java): [Seleziona]
 public class Singleton {
   private static final Singleton INSTANCE = new Singleton();
 
   // Private constructor prevents instantiation from other classes
   private Singleton() {}
 
   public static Singleton getInstance() {
      return INSTANCE;
   }
   public Object clone() throws CloneNotSupportedException {
      throw new CloneNotSupportedException();
   }
 }
ovvero la più performante e precisa.

Esaminiamo le differenze tra i tre codici.

Il primo non garantisce che l'oggetto sia un Singleton. Il metodo getInstance non è synchronized, quindi in applicazioni multi-thread può accadere alla prima richiesta del Singleton (e vi assicuro che accade) che due thread arrivano in contemporanea alla riga di codice "if (instance==null)". Per tutti e due i thread l'espressione restituisce "true" e quindi tutti e due i thread passano alla riga successiva "instance=new AlmanacUtility();" creando effettivamente due istanze diverse della classe. Che quindi non è un Singleton.

Il secondo codice (tralasciando il fatto che non usa il formalismo standard), non è affetto dal problema del primo codice visto che dichiara il metodo "getMioSingolo" (ovvero il metodo convenzionalmente chiamato "getInstance") synchronized. In caso di applicazioni multi-thread, infatti, uno dei due è costretto ad attendere "fuori" dal metodo l'esecuzione dell'altro, solo dopo può entrare ed in quel caso troverebbe la variabile singleton assegnata (diversa da null) restituendo l'unico singleton possibile. Non dichiarando però la variabile "istanza" final, questa può essere di nuovo assegnata a null (all'interno della classe singleton stessa), quindi al prossimo "getMioSingolo" verrebbe instanziato un nuovo Singleton! Vero è che cambia per tutti quello che lo utilizzano, ma anche questo caso è al limite della definizione di Singleton stesso. Inoltre, utilizzando un metodo synchronized, prestazionalmente perde tantissimo.

Il terzo codice non è affetto da nessuno dei precedenti problemi. L'istanza del singleton è delegata al ClassLoader che per definizione è un Singleton gestito dalla macchina virtuale, quindi si ha la sicurezza che viene istanziato uno ed una sola volta. La variabile è final, quindi una volta assegnata non è possibile cambiarla. Non usa metodi synchronized, quindi prestazionalmente è perfetta. In aggiunta ha la chicca dell'override del metodo "clone()" che andando sempre in CloneNotSupportedException fa capire a tutti che la classe non è clonabile (essendo un Singleton, per l'appunto!).

Lo so che sembrano stupide finezze o esagerazioni, ma se chiamiamo una cosa Singleton... Singleton deve essere!  :-P

Offline Miciux

  • Nuovo arrivato
  • *
  • Post: 15
  • Respect: +2
    • Miciux
    • Mostra profilo
    • Miciux's Weblog
  • Dispositivo Android:
    Acer Liquid E
  • Sistema operativo:
    Ubuntu 10.04, Windows 7
Re:Classe con utility comuni....non funziona :-(
« Risposta #11 il: 26 Agosto 2010, 12:21:17 CEST »
0
E' da parecchio che noto in questo forum la creazione errata del Singleton, fino ad adesso non sono intervenuto perché non capivo se era un semplice errore di distrazione o una conoscenza errata dell'oggetto. Finalmente ho avuto la risposta, la seconda!
...
cut
...

Quoto in toto MarcoDuff.

Aggiungerei poi che i Singleton rappresentano una soluzione pratica ma "pericolosa", e solitamente sono indice di un'architettura scarsamente strutturata. Io personalmente li uso solo quando indispensabile, ad esempio quando devo utilizzare un canale di comunicazione utilizzato in troppi posti all'interno dell'applicazione o un manager.
Visita il mio blog: Miciux's Weblog
Ma il codice sorgente per una ricetta?