Sviluppo app per connettersi a Wifi con WPS

di il
11 risposte

Sviluppo app per connettersi a Wifi con WPS

Sto scrivendo un'app che dovrebbe permettere la connessione a una rete wireless tramite PIN WPS. Naturalmente non ha nessuna utilità pratica ed è un'app a uso personale.Ho un problema nell'ottenere un 'istanza di WifiManager che mi servirebbe per ottenere la lista di AP disponibili.

ackage com.woops.neon.woops;

import android.content.Context;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;

import java.util.ArrayList;

import  android.content.Context.*;

/**
 * Created by neon on 24/11/15.
 */
public class WifiScanner
{
    private WifiManager manager;
    public WifiScanner()
    {
        manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
    }
    public ArrayList<ScanResult> scan()
    {

        return null;
    }
}
Android Studio mi segnala un errore in getSystemService dicendo che non è statico,ma anche usando Context.getSystemService continua a segnalare l'errore.Come risolvo?

11 Risposte

  • Re: Sviluppo app per connettersi a Wifi con WPS

    Come ti dice giustamente android studio, il metodo "getSystemService" non è statico, ma deve essere invocato su un oggetto di tipo Context, cosa che nel tuo caso non avviene.

    Inoltre così come l'hai fatta, la classe WifiScanner non è né un'Activity né un Service (entrambe sono sottoclassi di Context, per cui potresti usare il metodo in oggetto all'interno di una delle callback, ad esempio "onCreate"), per cui per funzionare hai bisogno di un riferimento a un context:
    
    public class WifiScanner {
        private WifiManager mWifiManager;
        public WifiScanner(Context context) {
            mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        }
    }
    
  • Re: Sviluppo app per connettersi a Wifi con WPS

    Avevo provato a usare un oggetto Context ma non ha funzionato,allora ho scoperto quel che ha detto tu.Per ora l'app a volte funziona e va in crash oppure va in crash direttamente,ma non mi intendo di programmazione Android e quindi niente logcat.
    MainActivity
    
    package com.woops.neon.woops;
    
    import android.net.wifi.ScanResult;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.widget.ArrayAdapter;
    import android.widget.ListView;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity
    {
    
        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            WifiScanner scanner = new WifiScanner();
            final ListView l = (ListView) findViewById(R.id.wifiListView);
            ArrayList<String> r = scanner.scan(getApplicationContext());
            final ArrayAdapter<String> aa = new ArrayAdapter<String>(this, android.R.layout.list_content, r);
            for(int i = 0; i < aa.getCount();i++)
            {
                aa.add(r.get(i));
            }
            l.setAdapter(aa);
        }
        @Override
        public boolean onCreateOptionsMenu(Menu menu)
        {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.menu_main, menu);
            return true;
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item)
        {
            // Handle action bar item clicks here. The action bar will
            // automatically handle clicks on the Home/Up button, so long
            // as you specify a parent activity in AndroidManifest.xml.
            int id = item.getItemId();
    
            //noinspection SimplifiableIfStatement
            if (id == R.id.action_settings)
            {
                return true;
            }
    
            return super.onOptionsItemSelected(item);
        }
    }
    
    WifiScanner
    
    package com.woops.neon.woops;
    
    import android.content.Context;
    import android.net.wifi.ScanResult;
    import android.net.wifi.WifiManager;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import  android.content.Context.*;
    import android.widget.ArrayAdapter;
    import android.widget.Toast;
    
    /**
     * Created by neon on 24/11/15.
     */
    public class WifiScanner
    {
        public ArrayList<String> scan(Context context)
        {
            WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
            boolean enabled  = manager.isWifiEnabled();
            if(enabled == false)
            {
                manager.setWifiEnabled(true);
                String text = "Wifi attivato";
                int duration = Toast.LENGTH_SHORT;
                Toast toast = Toast.makeText(context, text, duration);
                toast.show();
            }
            boolean scanStarted = manager.startScan();
            if(scanStarted == true)
            {
                Toast toast = Toast.makeText(context,"Scansione avviata",Toast.LENGTH_SHORT);
                toast.show();
            }
            else
            {
                Toast.makeText(context, "Errore: impossibile avviare la scansione", Toast.LENGTH_SHORT).show();
                return null;
            }
            List<ScanResult> wifiNetworks = manager.getScanResults();
            ArrayList<String> l = new ArrayList<String>();
            for(int i = 0;i < wifiNetworks.size();i++)
            {
                l.add(wifiNetworks.get(i).SSID);
            }
    
            return l;
        }
    }
    
    MainActivity
    
    <VerticalLayout 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:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:paddingBottom="@dimen/activity_vertical_margin"
        tools:context="com.woops.neon.woops.MainActivity">
    
       <ListView
           android:id="@+id/wifiListView"
           android:layout_width="match_parent"
           android:layout_height="match_parent">
    
       </ListView>
    
    </VerticalLayout>
    
  • Re: Sviluppo app per connettersi a Wifi con WPS

    loopunrolling ha scritto:


    non mi intendo di programmazione Android e quindi niente logcat.
    Senza LogCat è un parto trovare l'errore! Comunque non è necessario essere un guru di android, basta copiare i messaggi di errore e incollarli qua (possibilmente in un tag code) (il logcat lo trovi in basso, i messaggi di errore sono in rosso, vedi anche: )
  • Re: Sviluppo app per connettersi a Wifi con WPS

    Errori da Android Studio:
    
       --------- beginning of crash
    11-25 12:26:36.097  15178-15178/? E/AndroidRuntime? FATAL EXCEPTION: main
        Process: com.woops.neon.woops, PID: 15178
        java.lang.RuntimeException: Unable to start activity ComponentInfo{com.woops.neon.woops/com.woops.neon.woops.MainActivity}: android.view.InflateException: Binary XML file line #1: Error inflating class VerticalLayout
                at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2370)
                at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2432)
                at android.app.ActivityThread.access$900(ActivityThread.java:154)
                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321)
                at android.os.Handler.dispatchMessage(Handler.java:102)
                at android.os.Looper.loop(Looper.java:135)
                at android.app.ActivityThread.main(ActivityThread.java:5310)
                at java.lang.reflect.Method.invoke(Native Method)
                at java.lang.reflect.Method.invoke(Method.java:372)
                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
         Caused by: android.view.InflateException: Binary XML file line #1: Error inflating class VerticalLayout
                at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:757)
                at android.view.LayoutInflater.inflate(LayoutInflater.java:482)
                at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
                at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
                at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:256)
                at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109)
                at com.woops.neon.woops.MainActivity.onCreate(MainActivity.java:21)
                at android.app.Activity.performCreate(Activity.java:6865)
                at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
                at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2323)
                at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2432)
                at android.app.ActivityThread.access$900(ActivityThread.java:154)
                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321)
                at android.os.Handler.dispatchMessage(Handler.java:102)
                at android.os.Looper.loop(Looper.java:135)
                at android.app.ActivityThread.main(ActivityThread.java:5310)
                at java.lang.reflect.Method.invoke(Native Method)
                at java.lang.reflect.Method.invoke(Method.java:372)
                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
         Caused by: java.lang.ClassNotFoundException: Didn't find class "android.view.VerticalLayout" on path: DexPathList[[zip file "/data/app/com.woops.neon.woops-1/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
                at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
                at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
                at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
                at android.view.LayoutInflater.createView(LayoutInflater.java:571)
                at android.view.LayoutInflater.onCreateView(LayoutInflater.java:665)
                at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:65)
                at android.view.LayoutInflater.onCreateView(LayoutInflater.java:682)
                at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:741)
                at android.view.LayoutInflater.inflate(LayoutInflater.java:482)
                at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
                at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
                at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:256)
                at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109)
                at com.woops.neon.woops.MainActivity.onCreate(MainActivity.java:21)
                at android.app.Activity.performCreate(Activity.java:6865)
                at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
                at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2323)
                at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2432)
                at android.app.ActivityThread.access$900(ActivityThread.java:154)
                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321)
                at android.os.Handler.dispatchMessage(Handler.java:102)
                at android.os.Looper.loop(Looper.java:135)
                at android.app.ActivityThread.main(ActivityThread.java:5310)
                at java.lang.reflect.Method.invoke(Native Method)
                at java.lang.reflect.Method.invoke(Method.java:372)
                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
        Suppressed: java.lang.ClassNotFoundException: android.view.VerticalLayout
                at java.lang.Class.classForName(Native Method)
                at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
                at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
                at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
                ... 25 more
         Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available
    
    Devo dire che sul telefono non crasha anche se non mostra la lista delle reti come vorrei,mentre se lo testo via ADB crasha.
  • Re: Sviluppo app per connettersi a Wifi con WPS

    Il problema che causa il crash è che Android non riesce a trovare la classe android.view.VerticalLayout (vedi il messaggio "Caused by: java.lang.ClassNotFoundException: Didn't find class "android.view.VerticalLayout""), che in effetti non è una classe presente nella libreria standard. Usi per caso una qualche libreria esterna?
    La cosa strana è che dovrebbe darti errori anche in fase di compilazione, e comunque l'app dovrebbe crashare su tutti i dispositivi
  • Re: Sviluppo app per connettersi a Wifi con WPS

    Uso solo quel che c'è in Android Studio,niente di esterno.Comunque non so come mai,ma crasha solo via ADB.Può essere che VerticalLayout non si chiami più così nei file xml?
  • Re: Sviluppo app per connettersi a Wifi con WPS

    La classe VerticalLayout non esiste (non so dirti se in versioni vecchie di Android esistesse o meno), per cui non puoi usarla se vuoi evitare crash. Al suo posto potresti usare un altro layout, come LinearLayout (dispone gli elementi in modo sequenziale, verticalmente od orizzontalmente) o altri che puoi trovare sulla documentazione
  • Re: Sviluppo app per connettersi a Wifi con WPS

    Grazie Della per l'aiuto.Adesso no crasha più nemmeno con ADB.Però come mai non visualizza la lista di reti Wireless?
    PS: ho cambiato il titolo perchè sto parlando dell'app in generale
    EDIT: col già wifi attivo mi crasha via ADB
    
    mport  android.content.Context.*;
    import android.widget.ArrayAdapter;
    import android.widget.Toast;
    
    /**
     * Created by neon on 24/11/15.
     */
    public class WifiScanner
    {
        public ArrayList<String> scan(Context context)
        {
            WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
            boolean enabled  = manager.isWifiEnabled();
            if(enabled == false)
            {
                manager.setWifiEnabled(true);
                String text = "Wifi attivato";
                int duration = Toast.LENGTH_SHORT;
                Toast toast = Toast.makeText(context, text, duration);
                toast.show();
            }
            else
            {
                Toast.makeText(context,"Wifi già attivo",Toast.LENGTH_SHORT).show();
            }
            boolean scanStarted = manager.startScan();
            if(scanStarted == true)
            {
                Toast toast = Toast.makeText(context,"Scansione avviata",Toast.LENGTH_SHORT);
                toast.show();
            }
            else
            {
                Toast.makeText(context, "Errore: impossibile avviare la scansione", Toast.LENGTH_SHORT).show();
                return null;
            }
            List<ScanResult> wifiNetworks = manager.getScanResults();
            ArrayList<String> l = new ArrayList<String>();
            for(int i = 0;i < wifiNetworks.size();i++)
            {
                l.add(wifiNetworks.get(i).SSID);
            }
    
            return l;
        }
    }
    
    La classe per MainActivity non l'ho modificata.
    Errori
    
    11-25 14:21:06.855  26915-26915/com.woops.neon.woops E/art? Throwing OutOfMemoryError "Failed to allocate a 68706640 byte allocation with 16777216 free bytes and 44MB until OOM"
    11-25 14:21:06.856  26915-26915/com.woops.neon.woops D/AndroidRuntime? Shutting down VM
    11-25 14:21:06.857  26915-26915/com.woops.neon.woops E/AndroidRuntime? FATAL EXCEPTION: main
        Process: com.woops.neon.woops, PID: 26915
        java.lang.OutOfMemoryError: Failed to allocate a 68706640 byte allocation with 16777216 free bytes and 44MB until OOM
                at java.util.ArrayList.add(ArrayList.java:118)
                at android.widget.ArrayAdapter.add(ArrayAdapter.java:179)
                at com.woops.neon.woops.MainActivity.onCreate(MainActivity.java:28)
                at android.app.Activity.performCreate(Activity.java:6865)
                at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
                at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2323)
                at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2432)
                at android.app.ActivityThread.access$900(ActivityThread.java:154)
                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321)
                at android.os.Handler.dispatchMessage(Handler.java:102)
                at android.os.Looper.loop(Looper.java:135)
                at android.app.ActivityThread.main(ActivityThread.java:5310)
                at java.lang.reflect.Method.invoke(Native Method)
                at java.lang.reflect.Method.invoke(Method.java:372)
                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
    
  • Re: Sviluppo app per connettersi a Wifi con WPS

    loopunrolling ha scritto:


    
    11-25 14:21:06.855  26915-26915/com.woops.neon.woops E/art? Throwing OutOfMemoryError "Failed to allocate a 68706640 byte allocation with 16777216 free bytes and 44MB until OOM"
    ...
    java.lang.OutOfMemoryError: Failed to allocate a 68706640 byte allocation with 16777216 free bytes and 44MB until OOM
                at java.util.ArrayList.add(ArrayList.java:118)
                at android.widget.ArrayAdapter.add(ArrayAdapter.java:179)
                at com.woops.neon.woops.MainActivity.onCreate(MainActivity.java:28)
                ...
    
    Il messaggio mi sembra abbastanza esplicativo: non hai abbastanza memoria per aggiungere dei dati all'arrayadapter. Nota comunque che stai cercando di inserire più 65 MB di dati, quindi probabilmente hai commesso qualche errore.. Ad esempio ho notato che aggiungi 2 volte ogni elemento della lista all'adapter (la prima volta passando "r" al costruttore dell'adapter, la seconda volta tramite il ciclo for, per cui elimina quest'ultimo).

    Inoltre, supponendo che tu abbia richiesto nel manifest i permessi idonei (es: android.permission.CHANGE_WIFI_STATE, per accendere/spegnere il wifi, android.permission.ACCESS_FINE_LOCATION e android.permission.ACCESS_COARSE_LOCATION per ottenere i risultati di uno scan, e forse ne servono anche altri), il metodo che usi per controllare i risultati è errato.
    Se guardi nella documentazione, infatti, noterai che il metodo startScan() ha la seguente descrizione:
    Request a scan for access points. Returns immediately. The availability of the results is made known later by means of an asynchronous event sent on completion of the scan.
    Questo significa che non puoi chiamare "startScan()" e, subito dopo, "getScanResults()", perché non è detto che lo scan sia finito.
    La soluzione è creare una sottoclasse di BroadcastReceiver con l'intentfilter idoneo (in questo caso devi monitorare l'azione SCAN_RESULTS_AVAILABLE_ACTION) per essere notificato di quando uno scan termina. E' all'interno di esso che potrai poi chiamare in sicurezza il metodo "getScanResults()", perché a quel punto lo scan sarà sicuramente terminato e la lista di reti wifi sarà disponibile.
    Nota che affinché il BroadcastReceiver funzioni è necessario registrarlo all'interno della tua app, e uno dei modi per farlo è attraverso il metodo (tipicamente chiamato nella callback "onResume()"). Infine per evitare di sprecare risorse inutilmente è sempre meglio chiamare anche il metodo (tipicamente nella callback "onPause()"), per rimuovere il BroadcastReceiver
  • Re: Sviluppo app per connettersi a Wifi con WPS

    Direi che è un po' complicato.Meglio iniziare da una semplice calcolatrice
  • Re: Sviluppo app per connettersi a Wifi con WPS

    In realtà non è così complicato, e poi impari a conoscere 3 dei 4 dei componenti fondamentali del mondo android, ovvero Activity, BroadcastReceiver e Intent! Se proprio non sai da dove iniziare ecco il link a una soluzione completa che ho appena scritto
Devi accedere o registrarti per scrivere nel forum
11 risposte