# Probleme mit custom dynamic ListView



## nickname (7. Nov 2018)

Hallo zusammen!!
Bin schon einigen Tagen an einem Problem. Bräuchte jetzt nach vielen Versuchen mal eure Hilfe!!
Ich möchte gern eine custom dynamic listView entwerfen, die bspw. nur die SSID scannt.
Wenn ich die default ListView im ArrayAdapter verwende, klappt alles ohne Problem. Ich habe nur Problem eine custom ListView anzuwenden.
Hier mal mein Code. Vielleicht hat jemand mal einen Tipp für, bin schon fertig mit den Nerven... Ich glaube es liegt an der Klasse "CustomArrayAdapter".

Das ist die Main class

```
public class MainActivity extends Activity {

    Button buttonClose;
    ListView listView;
    WifiManager wifiManager;
    List<ScanResult> listScanResult;
    String SSID;
    CustomBroadcastReceiver wifiBroadcastReceiverClass;
   
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
      
        buttonClose = ( Button ) findViewById( R.id.buttonClose );
        buttonClose.setOnClickListener( new OnClickListener() {
            @Override
            public void onClick( View view ) {
                finish();
            }
        });
      
        wifiBroadcastReceiverClass = new CustomBroadcastReceiver();
      
        listView = ( ListView ) findViewById( R.id.listView );
      
        wifiManager = (WifiManager)getApplicationContext().getSystemService( Context.WIFI_SERVICE );
      
        this.registerReceiver(wifiBroadcastReceiverClass, new IntentFilter( WifiManager.WIFI_STATE_CHANGED_ACTION ));
    }
/*****************************************************************************/
    class CustomBroadcastReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            wifiManager.startScan();
            listScanResult = wifiManager.getScanResults();
            ArrayList<String> arrayList = new ArrayList<String>();
          
            for( int x = 0; x < wifiManager.getScanResults().size(); x++ ) {
                arrayList.add(wifiManager.getScanResults().get( x ).SSID );
            }
            CustomArrayAdapter arrayAdapter = new CustomArrayAdapter(MainActivity.this);
            listView.setAdapter(arrayAdapter);      
        }  
    }
}//Ende der Klasse
```
(Hier denke ich stimmt was nicht mit dem customer Adapter nicht...)



Hier die Adapter class
(Ich bin mir sicher, dass hier ein Fehler vorliegt und zwar bei dem Kostruktor)

```
public class CustomArrayAdapter extends ArrayAdapter<CustomData>{

    Context context;
    int resource;
   
    LayoutInflater layoutInflater = ( LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
        /* Construktor */
        public CustomArrayAdapter(Context context ) {
           
            super(context, R.layout.custom_listview );
            this.context = context;
        }
        // getView()...
        @Override
        public View getView(int position, View convertView, ViewGroup parent ) {       
        View view = convertView;  
        String textSSID = getItem(position).getSSID();
       
        if( convertView == null ) {
        view = layoutInflater.inflate( R.layout.custom_listview, null );
       
            TextView ssidNameFromID = ( TextView ) view.findViewById( R.id.textViewSSID );
            ssidNameFromID.setText(textSSID);           
        } 
        return view;
    }
}
```

Hier meine Custom class

```
public class CustomData { 
    String textSSID;
  
    public CustomData( String ssid ) {
        this.textSSID = ssid;
    }
        
    public String getSSID() {
        return textSSID;
    }  
}
```

Daaaaaanke schon mal für eure Hilfe...

Gruß nickname


----------



## Robat (7. Nov 2018)

Ja mit dem Adapter ist noch nicht alles richtig. Du überschreibst den Wert der TextView nur, wenn convertView null war. Schau dir mal hier vergleichsweise den Adapter an.
Außerdem hab ich bisher noch keine Zeile gefunden, wo du dem Adapter die Liste mit den Elementen hinzufügst.


----------



## nickname (7. Nov 2018)

Hallo Robat,
vielen Dank für deine Antwort. Hab es so hinbekommen, dass mir die ssid von den Netzwerken in meiner Umgebung angezeigt werden ABER (wie immer) gibt es noch ein kleines Problem.
Hier erstmal meine Lösung für beide Klassen!

Main class (Ist nur der Ausschnitt wo ich Veränderungen vorgenommen hatte)

```
class CustomBroadcastReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            wifiManager.startScan();         
            listScanResult = wifiManager.getScanResults();         
            listCustomData = new ArrayList<CustomData>();           
            for( int x = 0; x < wifiManager.getScanResults().size(); x++ ) {
                listCustomData.add(new CustomData(wifiManager.getScanResults().get( x ).SSID));   
             
            }
            CustomArrayAdapter arrayAdapter = new CustomArrayAdapter(getApplicationContext(), R.layout.custom_listview, listCustomData);
            listView.setAdapter(arrayAdapter);       
//            Toast.makeText(MainActivity.this, "Hallo", Toast.LENGTH_SHORT).show();
        }   
    }
```

Und hier die andere Klasse

```
public class CustomArrayAdapter extends ArrayAdapter<CustomData>{

    Context context;
    int resourceLayout;
    List<CustomData> customData; 
        /* Konstruktor */
        public CustomArrayAdapter(Context context, int resourceLayout, List<CustomData> customData) {
           
            super( context, resourceLayout, customData );
       
            this.context = context;
            this.resourceLayout = resourceLayout;
            this.customData = customData;
        }
        // getView()...
        @Override
        public View getView(int position, View convertView, ViewGroup parent ) {
       
        LayoutInflater layoutInflater = ( LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = convertView;
       
        String textSSID = getItem(position).getSSID();
       
        if( convertView == null ) {
        view = layoutInflater.inflate( R.layout.custom_listview, null );
       
            TextView ssidNameFromID = ( TextView ) view.findViewById( R.id.textViewSSID );
           
            CustomData cd = customData.get( position );
           
            ssidNameFromID.setText(textSSID);
        }
        return view;
    }
}
```
Was mir erst aufgefallen, das war der weisse Adler auf weissem Hintergrund...Hatte nicht gesehen,
das die Schriftfarbe auf weiss war, wie der Hintergrund (schüttelt den kopf und macht klapps)

Mein Problem ist noch, dass ich, um neue Netzwerke scannen zu können, ich jedesmal das Programm auf
dem Handy neu starten muss, was bei dem default layout eigentlich immer automatisch lief!!

Hoffe, Jemand im weiten Tiefen des Netz hat noch einen Tipp für mich

Danke!!!!


----------



## nickname (7. Nov 2018)

AHHHHHHHH
Ich bin doch ein IDIOT!

hab zwar meinen BroadcastReceiver registriert aber das nicht eingefügt...

```
this.registerReceiver(wifiBroadcastReceiverClass, new IntentFilter( WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
```

Jetzt klappt es !! Danke trotzdem Bis zum nächten mal!!


----------



## nickname (8. Nov 2018)

Hallo zusammen.. da bin ich wieder
hab ein kleines Problem mit meinem Code...So weit läuft es ja. Ich kann
die SSID und BSSID anzeigen aber,wenn ich einen int-Wert, wie bspw.  level auslesen
möchte, klappt das nicht. Da stürzt meine App immer ab. Beim String klappt das ohne Prob.

Hoffe jemand kann mir da helfen Danke schon mal!!

Habe den Konstruktor angepaßt usw.
Hier der Teilcode in der Main

```
class CustomBroadcastReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
           
            wifiManager.startScan();
            listCustomData = new ArrayList<CustomData>();       
            for( int x = 0; x < wifiManager.getScanResults().size(); x++ ) {
//                listCustomData.add(new CustomData(wifiManager.getScanResults().get( x ).SSID, wifiManager.getScanResults().get( x ).BSSID));
                listCustomData.add(new CustomData(wifiManager.getScanResults().get( x ).level));
               
            }
            CustomArrayAdapter arrayAdapter = new CustomArrayAdapter(getApplicationContext(), R.layout.custom_listview, listCustomData);
            listView.setAdapter(arrayAdapter);       
            Toast.makeText(MainActivity.this, "Scan...", Toast.LENGTH_SHORT).show();
        }   
    }
```

Hier der Code in der CustomData

```
public class CustomData {

   
    String textSSID;
    String bssid;
    int levelInt;

   
   
    public CustomData( String ssid, String bssid) {
        this.textSSID = ssid;
        this.bssid = bssid;
    }
   
    public CustomData( int levelint ) {
        this.levelInt = levelint;
    }
    public String getSSID() {
        return textSSID;
    }
   
    public String getBSSID() {
        return bssid;
    }
   
    public int getLevelInt() {
        return levelInt;
    }
   
}
```

Und der Letzte in der Adapter Klasse

```
public View getView(int position, View convertView, ViewGroup parent ) {
       
        LayoutInflater layoutInflater = ( LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = convertView;
       
//        String textSSID = getItem(position).getSSID();
//        String bssidString = getItem( position ).getBSSID();
        int levelIntID = getItem( position ).getLevelInt();
       
        if( convertView == null ) {
        view = layoutInflater.inflate( R.layout.custom_listview, null );
       
//            TextView ssidNameFromID = ( TextView ) view.findViewById( R.id.textViewSSID );
//            TextView bssidFromID = ( TextView ) view.findViewById( R.id.textViewIpAdress_ID );
            TextView levelIntFromID = ( TextView ) view.findViewById( R.id.textViewIpAdress_ID );
           
            CustomData cd = customData.get( position );
           
//            ssidNameFromID.setText(textSSID);
//            bssidFromID.setText(bssidString);
            levelIntFromID.setText(levelIntID);
           
            ImageView wifi = (ImageView) view.findViewById( R.id.imageViewWifiNet_ID );
            wifi.setImageResource(R.drawable.wifi_net);//Es wird immer das gleiche Bild angezeigt
        }
       
        return view;
    }
```


----------



## Robat (8. Nov 2018)

nickname hat gesagt.:


> wenn ich einen int-Wert, wie bspw. level auslesen
> möchte, klappt das nicht. Da stürzt meine App immer ab.


Wenn du setText() einen Integer übergibst denkt Android, dass du damit eine ResouceID meinst. Diese kann er logischerweise nicht finden und wirft eine Exception. Wenn du also wirklich den int-Wert ausgeben lassen willst, musst du diesen vorher zu einem String umwandeln.


----------



## nickname (8. Nov 2018)

Hi Robat!

Danke für deine Antwort

Hab meinen Code angepaßt und rate mal...hat natürlich geklpatt
Hier meine Veränderung... aus der CustomData.

```
. . .
if( convertView == null ) {
        view = layoutInflater.inflate( R.layout.custom_listview, null );
       
            TextView ssidNameFromID = ( TextView ) view.findViewById( R.id.textViewSSID );
            TextView bssidFromID = ( TextView ) view.findViewById( R.id.textViewIpAdress_ID );
            TextView levelIntFromID = ( TextView ) view.findViewById( R.id.textViewLevel_ID );
           
            CustomData cd = customData.get( position );
           
            ssidNameFromID.setText(textSSID);
            bssidFromID.setText(bssidString);

            levelIntFromID.setText(String.valueOf(levelIntID));//HIER MEINE VERÄNDERUNG
           
            ImageView wifi = (ImageView) view.findViewById( R.id.imageViewWifiNet_ID );
            wifi.setImageResource(R.drawable.wifi_net);
        }
        return view;
```

Vielen Dank für deinen Tipp!!!! Wollte schon für heute aufgeben aber jetzt geht´s weiiiiter!!

Gruß nickname


----------



## nickname (8. Nov 2018)

Hallo zusammen, ich bin´s mal wieder

Hab ein kleines Problem. Und zwar möchte ich die passende IP zur der dazugehörigen SSID
ausgeben aber das klappt nicht. Wenn es mir angezeigt wird, dann wird natürlich nur ein IP
für alle gescannten SSID´s angezeigt. Ich wollte das gerne in der vorliegenden for-Schleife
realisieren. 
Hat jemand vielleicht einen Tipp für mich??? 

Wie immer vielen Dank für eure Hilfe


```
class CustomBroadcastReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
           
            wifiManager.startScan();//Beginnt mit dem Scannvorgang   
           
            listScanResult = wifiManager.getScanResults();//Speichert die gescannten Elemente
           
            wifiInfo = wifiManager.getConnectionInfo();
           
            listCustomData = new ArrayList<CustomData>();//Nimmt die Daten auf, die mit add hinzugefügt werden. Ist somit ein Speicher
           
            /* Der Konstruktor nimmt alles auf, was gescannt wird */
            for( int x = 0; x < wifiManager.getScanResults().size(); x++ ) {
                listCustomData.add(new CustomData(listScanResult.get( x ).SSID, listScanResult.get( x ).BSSID,
                        listScanResult.get( x ).level, listScanResult.get( x ).frequency));      
                wifiInfo.getIpAddress();//HIER KLAPPT ES NICHT MIT [X] BEI WIFIINFO
            }
           
            //
           
            CustomArrayAdapter arrayAdapter = new CustomArrayAdapter(getApplicationContext(), R.layout.custom_listview, listCustomData);
            listView.setAdapter(arrayAdapter);       
            Toast.makeText(MainActivity.this, "Scan...", Toast.LENGTH_SHORT).show();
        }   
    }
```


----------



## mihe7 (9. Nov 2018)

nickname hat gesagt.:


> Und zwar möchte ich die passende IP zur der dazugehörigen SSID
> ausgeben aber das klappt nicht.


Wenn Du das vorhast, was ich glaube, dass Du vorhast, dann kann das nicht funktionieren. Die IP-Adresse gibts - wenn überhaupt - erst bei einer Verbindung.


----------



## nickname (9. Nov 2018)

Hi. ich habe es wohl falsch ausgedrückt. Ich meinte alle Elemente, die ich mit WifiInfo auslesen kann,
da klappt es nicht, nur mit WifiManager...
Ich glaube, dass es an der Verbindung zw. der Main Klasse und der CustomAdapter Klasse liegt und
dem dazugehörigen Konstruktor. Muss ich vllt. den Konstruktor in der CustomAdapter Klasse ändern??

Hier noch mal die beiden Klassen
(Main Klasse)

```
public class MainActivity extends Activity {

    Button buttonClose;
    ListView listView;
   
    WifiManager wifiManager;
    WifiInfo wifiInfo;
    List<CustomData> listCustomData;
    List<ScanResult> listScanResult;
   
    Switch switchWifiOnOff;
   
    int wifiStateInteger;
   
    //Cnstructor of inner class
    CustomBroadcastReceiver wifiBroadcastReceiverClass;
   
   
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       
        wifiManager = (WifiManager)getApplicationContext().getSystemService( Context.WIFI_SERVICE );
        wifiStateInteger = wifiManager.getWifiState();
       
        wifiBroadcastReceiverClass = new CustomBroadcastReceiver();
       
        this.registerReceiver(wifiBroadcastReceiverClass, new IntentFilter( WifiManager.NETWORK_STATE_CHANGED_ACTION ));
       
        listView = ( ListView ) findViewById( R.id.listView );
        
        buttonClose = ( Button ) findViewById( R.id.buttonClose );
        buttonClose.setOnClickListener( new OnClickListener() {
            @Override
            public void onClick( View view ) {
                finish();
            }
        });
        switchWifiOnOff = ( Switch ) findViewById( R.id.switchWifiOnOff );
        switchWifiOnOff.setOnCheckedChangeListener( new OnCheckedChangeListener() {
           
            @Override
            public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
                               
                boolean wifiOnOff = wifiManager.isWifiEnabled();//return value is "true=wifi is enabled" or "false=wifi is disabled"
               
                    if( !wifiOnOff ) { // 1 = Wifi is disabled
                        wifiEnabled();
                        switchWifiOnOff.setEnabled( false );
                    }
                    if( wifiOnOff ) {// 3 = Wifi is enabled
                        wifiDisanbled();
                        switchWifiOnOff.setEnabled( true );
                    }
               
                }
            });
        
    }// Ende onCreate()...
    
    private void wifiEnabled() {
        wifiManager.setWifiEnabled( true );
    }
   
    private void wifiDisanbled() {
        wifiManager.setWifiEnabled( false );
    }
   
    /*****************************************************************************/
    class CustomBroadcastReceiver extends BroadcastReceiver{
       
        @Override
        public void onReceive(Context context, Intent intent) {
           
            wifiManager.startScan();//Beginnt mit dem Scannvorgang       
            listScanResult = wifiManager.getScanResults();//Speichert die gescannten Elemente  
            wifiInfo = wifiManager.getConnectionInfo();
            listCustomData = new ArrayList<CustomData>();           

            for( int x = 0; x < wifiManager.getScanResults().size(); x++ ) {
                listCustomData.add(new CustomData(listScanResult.get( x ).SSID, listScanResult.get( x ).BSSID,
                        listScanResult.get( x ).level, listScanResult.get( x ).frequency));  
              }
           
            //
           
            CustomArrayAdapter arrayAdapter = new CustomArrayAdapter(getApplicationContext(), R.layout.custom_listview, listCustomData);
            listView.setAdapter(arrayAdapter);       
            Toast.makeText(MainActivity.this, "Scan...", Toast.LENGTH_SHORT).show();
        }   
    }
}//Ende der Klasse
```

Und hier die Adapter Klasse

```
public class CustomArrayAdapter extends ArrayAdapter<CustomData>{

    Context context;
    int resourceLayout;
    List<CustomData> customData;
   
    LayoutInflater layoutInflater;   
        /* Konstruktor */
        public CustomArrayAdapter(Context context, int resourceLayout, List<CustomData> customData) {
           
            super( context, resourceLayout, customData );
       
            this.context = context;
            this.resourceLayout = resourceLayout;
            this.customData = customData;
        }
         // getView()...
       
       @Override
        public View getView(int position, View convertView, ViewGroup parent ) {
       
        layoutInflater = ( LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
           
        View view = convertView;
       
        String textSSID = getItem(position).getSSID();
        String bssidString = getItem( position ).getBSSID();
        int levelIntID = getItem( position ).getLevelInt();
        int frequenzIntID = getItem( position ).getFrequenz();
       
        if( convertView == null ) {
        view = layoutInflater.inflate( R.layout.custom_listview, null );
        }
       
            TextView ssidNameFromID = ( TextView ) view.findViewById( R.id.textViewSSID );
            TextView bssidFromID = ( TextView ) view.findViewById( R.id.textViewIpAdress_ID );
            TextView levelIntFromID = ( TextView ) view.findViewById( R.id.textViewLevel_ID );
            TextView frequenzIntFromID = ( TextView ) view.findViewById( R.id.textViewFrequenz_ID );
         
            ssidNameFromID.setText(textSSID);
            bssidFromID.setText(bssidString);
            levelIntFromID.setText(String.valueOf(levelIntID));
            frequenzIntFromID.setText(String.valueOf(frequenzIntID));
           
            ImageView wifi = (ImageView) view.findViewById( R.id.imageViewWifiNet_ID );
            wifi.setImageResource(R.drawable.wifi_net);//Es wird immer das gleiche Bild angezeigt
       
        return view;
    }
}
```

Danke schon mal m Voraus!!!


----------



## mihe7 (9. Nov 2018)

Du bekommst die WifiInfo nur für die aktuell bestehende Verbindung, falls eine solche überhaupt existiert.

Nachtrag: oder geht es Dir um zusätzliche "Spalten"? Dann musst Du die CustomData-Klasse entsprechend anpassen oder nutzen.


----------



## nickname (9. Nov 2018)

Hallo mihe7,

ach so... d.h. es sind versteckte Informationen, die ein Außenstehender gar nicht (legal) einsehen kann...ist das richtig???? Dann kann ich mir ja einen Wolf schreiben
Also liefert mir WifiManager nur Infos über (legale) Daten, bzgl. des Wlan...

Kann ich das irgendwo vllt nachlesen?? Kennst du da was??

Danke für deine Hilfe!!!!

Gruß nickname


----------



## mihe7 (9. Nov 2018)

nickname hat gesagt.:


> d.h. es sind versteckte Informationen, die ein Außenstehender gar nicht (legal) einsehen kann...


Das hat schon allein technische Gründe. Nehmen wir mal einen Ethernet-Adapter. Die kümmert sich darum, dass die Daten auf die Leitung kommen und im LAN verschickt werden können. Zu diesem Zweck erhält jeder Ethernet-Adapter eine (zumindest im Netzwerk) eindeutige MAC-Adresse. Ethernet weiß gar nicht, dass es etwas wie IP-Adressen gibt.


----------



## mihe7 (9. Nov 2018)

nickname hat gesagt.:


> Kann ich das irgendwo vllt nachlesen?? Kennst du da was??


Was meinst Du? Bzgl. Android? Das steht so schon in der API.


----------



## nickname (9. Nov 2018)

Ja, ich meinte Android. Also kann ich halt nur meine Daten, auf die ich auch zugreifen kann, auslesen...
Klar, die API, aber ich dachte auch andere Seiten... Danke dir trotzdem!!

Gruß nickname


----------



## mihe7 (9. Nov 2018)

Naja, wenn Du in die API reinschaust, steht unter WifiManager#getConnectionInfo(): 
"Return dynamic information about the current Wi-Fi connection, if any is active." Ich finde, dass "about the current Wi-Fi connection" ziemlich eindeutig ist.


----------

