7

当我运行具有Broadcast Receiver for WiFi的 Android 应用程序时,我遇到了一个问题。它在不同版本的 Android 操作系统(如4.1.14.2.2)上表现不同。

当我在4.1.1上运行它时,它就像广播接收器在 Wifi 状态改变时接收广播一样完美。(在断开 wifi 广播接收时,我计算了 wifi 连接的总时间并将其存储在数据库中)。

但是当我在4.2.2上运行它时,当 Wifi 断开连接时,广播接收器会调用两次,因此当时值(即 wifi 连接的时间)在数据库中存储两次

所以我需要知道为什么会这样?为什么广播接收器wifi 断开时调用两次?我需要代码使其适用于所有Android 版本

这是我的代码。

Android 清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.evowifiservice"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8" android:maxSdkVersion="17" android:targetSdkVersion="17"/>

    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.evowifiservice.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name=".WiFiReceiver" >
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
                <action android:name="android.net.wifi.STATE_CHANGE" />
            </intent-filter>
            <!--
            <intent-filter>
                <action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
            </intent-filter>
            -->
        </receiver>

        <service android:name=".FirstService" >
        </service>
    </application>

</manifest>

扩展广播接收器的接收器代码(wifi断开时执行两次)

package com.example.evowifiservice;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import android.content.BroadcastReceiver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.util.Log;
import android.widget.Toast;

public class WiFiReceiver extends BroadcastReceiver {

    SharedPreferences sharedpref;
    SharedPreferences.Editor editor;
    public static String PREFS_NAME = "WifiList";
    WifiInfo connectionInfo;
    Calendar calendar;
    String strSSID;
    ArrayList<String> arySSID;

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub

        try {
            MainActivity.mDatabase = context.openOrCreateDatabase(
                    "WifiDetails.db", SQLiteDatabase.CREATE_IF_NECESSARY, null);
            MainActivity.mDatabase.setVersion(1);
            MainActivity.mDatabase.setLocale(Locale.getDefault());
            MainActivity.mDatabase.setLockingEnabled(true);


            arySSID = new ArrayList<String>();

            Cursor c = MainActivity.mDatabase.query("tbl_SSID", null, null, null, null,null, null);
            arySSID.clear();
            c.moveToFirst();
            while (!c.isAfterLast()) {

                arySSID.add(c.getString(1));
                c.moveToNext();

            }
            Log.d("ArySSID","Array : "+arySSID+"  Size  "+arySSID.size());
        } catch (Exception e) {
            // TODO: handle exception
        }

        sharedpref = context.getSharedPreferences(PREFS_NAME, 0);
        if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {

            NetworkInfo networkInfo = intent
                    .getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);

            if (networkInfo.isConnected()) {
                // Wifi is connected
                WifiManager wifiManager = (WifiManager) context
                        .getSystemService(Context.WIFI_SERVICE);
                wifiManager.getConfiguredNetworks();
                connectionInfo = wifiManager.getConnectionInfo();

                strSSID = connectionInfo.getSSID();
                Log.d("Currently Connected with", "" + strSSID);



                // Retrieve the values
                String comparestr=strSSID.replaceAll("^\"|\"$", "");

                editor = sharedpref.edit();
                editor.putString("CurrentSSID", "" + comparestr);
                editor.commit();

                if (arySSID.contains(comparestr)) {

                    Log.d("CONTAINSSSS", "CONTAINSSSS");

                    Date date = new Date();
                    long timeInMili = date.getTime();

                    editor.putLong("ConnectedTimeMili", timeInMili);
                    editor.commit();
                    Log.d("Connected Time", "" + timeInMili);

                    SimpleDateFormat df1 = new SimpleDateFormat("dd/MM/yyyy");
                    String connectedDateText = df1.format(date);
                    Log.d("Connected Date", connectedDateText);

                    SimpleDateFormat df2 = new SimpleDateFormat("HH:mm:ss");
                    String connectedTimeText = df2.format(date);
                    Log.d("Connected Time", connectedTimeText);

                    Toast.makeText(
                            context,
                            "You are Connected with Evosys Organization @ "
                                    + "" + connectedTimeText, Toast.LENGTH_SHORT).show();

                    ContentValues myval = new ContentValues();
                    myval.put("SSID", "" + comparestr);
                    myval.put("Status", "CONNECTED");
                    myval.put("Date", connectedDateText);
                    myval.put("Time", connectedTimeText);

                    MainActivity.mDatabase.insert("tbl_WifiDet", null, myval);

                    Toast.makeText(context,
                            "Insert while Connected Successfully",
                            Toast.LENGTH_LONG).show();
                }
                Log.d("Inetify",
                        "Wifi is connected: " + String.valueOf(networkInfo));
            }
        } else if (intent.getAction().equals(
                ConnectivityManager.CONNECTIVITY_ACTION)) {

            NetworkInfo networkInfo = intent
                    .getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);

            if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI
                    && !networkInfo.isConnected()) {
                // Wifi is disconnected

                strSSID = sharedpref.getString("CurrentSSID", "");
                Log.d("Currently DisConnected with", "-----" + strSSID);

                String comparestr=strSSID.replaceAll("^\"|\"$", "");
                if (arySSID.contains(comparestr)) {

                    Date date = new Date();

                    long dctimemili = date.getTime();
                    Log.d("DCConnected Time", "" + dctimemili);
                    SimpleDateFormat df1 = new SimpleDateFormat("dd/MM/yyyy");
                    String DcdateText = df1.format(date);
                    Log.d("Disconnected Date", DcdateText);

                    SimpleDateFormat df2 = new SimpleDateFormat("HH:mm:ss");
                    String DctimeText = df2.format(date);
                    Log.d("Disconnected Time", DctimeText);

                    long ctimemili = sharedpref.getLong("ConnectedTimeMili", 0);

                    long diff = dctimemili - ctimemili;
                    Log.d("MILI SECOND You are connected upto", "" + diff);

//                  int seconds = (int) (diff / 1000) % 60 ;
//                  int minutes = (int) ((diff / (1000*60)) % 60);
//                  int hours   = (int) ((diff / (1000*60*60)) % 24);

                    int mHour = (int) (diff / (1000*60*60));
                    int mMin = (int) ((diff % (1000*60*60)) / (1000*60));
                    int mSec  = (int) (((diff % (1000*60*60)) % (1000*60)) / 1000);


                    String connectionTime = mHour + ":" + mMin + ":" + mSec;
                    Log.d("You are connected upto", "" + connectionTime);

                    ContentValues myval = new ContentValues();
                    myval.put("SSID", "" + comparestr);
                    myval.put("Status", "DISCONNECTED");
                    myval.put("Date", DcdateText);
                    myval.put("Time", DctimeText);
                    myval.put("Total_Connection_Time", diff);

                    MainActivity.mDatabase.insert("tbl_WifiDet", null, myval);
                    Toast.makeText(context, "Insert while D/C Successfully",
                            Toast.LENGTH_LONG).show();

                    Toast.makeText(context, "Wifi is disconnected.",
                            Toast.LENGTH_LONG).show();
                    Log.d("Inetify",
                            "Wifi is disconnected: "
                                    + String.valueOf(networkInfo));
                }
            }
        }
    }
}

主要活动

package com.example.evowifiservice;

import java.util.ArrayList;
import java.util.Locale;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

    SharedPreferences sharedpref;
    SharedPreferences.Editor editor;
    public static String PREFS_NAME = "WifiList";
    static SQLiteDatabase mDatabase;
    ListView list_wifiDet;
    Button btn_wifiDetView,btn_delete_records,btn_tot_con_time;
    ArrayList<String> arySSID,aryConStatus,aryDate,aryTime;
    ArrayAdapter<String> adpt;
    static final int CUSTOM_DIALOG_ID1 = 1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btn_wifiDetView=(Button) findViewById(R.id.btn_wifiDetView);
        btn_delete_records=(Button) findViewById(R.id.btn_delete_records);
        btn_tot_con_time=(Button) findViewById(R.id.btn_tot_con_time);
        list_wifiDet=(ListView) findViewById(R.id.list_wifiDet);
        try 
        {       
            mDatabase=openOrCreateDatabase("WifiDetails.db",SQLiteDatabase.CREATE_IF_NECESSARY, null);
            mDatabase.setVersion(1);
            mDatabase.setLocale(Locale.getDefault());
            mDatabase.setLockingEnabled(true);

            String s="Create table tbl_WifiDet(Id INTEGER PRIMARY KEY AUTOINCREMENT,SSID TEXT,Status TEXT,Date TEXT,Time TEXT,Total_Connection_Time INTEGER)";
            mDatabase.execSQL(s);
            String s1="Create table tbl_SSID(Id INTEGER PRIMARY KEY AUTOINCREMENT,SSID TEXT)";
            mDatabase.execSQL(s1);

            ContentValues myval = new ContentValues();
            myval.put("SSID", "evosys1");
            mDatabase.insert("tbl_SSID", null, myval);
            myval.put("SSID", "evosys2");
            mDatabase.insert("tbl_SSID", null, myval);
            myval.put("SSID", "ROUTE-999");
            mDatabase.insert("tbl_SSID", null, myval);
//          
            Toast.makeText(getApplicationContext(), "Insert SSID List Successfully",
                    Toast.LENGTH_LONG).show();
        } catch (Exception e) {
            // TODO: handle exception
        }

    }

    @Override
    protected void onStart() {
        // TODO Auto-generated method stub
        super.onStart();

        sharedpref = getSharedPreferences(PREFS_NAME, 0);


        Log.d("Starting Service", "in MainActivity");
        startService(new Intent(this,FirstService.class));


        btn_wifiDetView.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                Cursor c = mDatabase.query("tbl_WifiDet", null, null, null, null,null, null);
                c.moveToFirst();

                arySSID = new ArrayList<String>();
                aryConStatus = new ArrayList<String>();
                aryDate = new ArrayList<String>();
                aryTime = new ArrayList<String>();

                arySSID.clear();
                aryConStatus.clear();
                aryDate.clear();
                aryTime.clear();

                while (!c.isAfterLast()) {

                    arySSID.add(c.getString(1));
                    aryConStatus.add(c.getString(2));
                    aryDate.add(c.getString(3));
                    aryTime.add(c.getString(4));
                    c.moveToNext();

                }
                showDialog(CUSTOM_DIALOG_ID1);
                adpt = new MyCustomBaseAdapteradptWifiDet(MainActivity.this, R.layout.wifi_list,arySSID,aryConStatus,aryDate,aryTime);
                list_wifiDet.setAdapter(adpt);
            }
        });

        btn_tot_con_time.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

//              String[] columns = new String[]{ "sum(Total_Connection_Time) as " + "Total_Connection_Time" };

                Cursor c = mDatabase.query("tbl_WifiDet", null, null, null, null,null, null);
                c.moveToLast();
                long contime=c.getLong(5);
                Log.d("Chking Time", "-----"+contime);

                c.moveToFirst();
                long result = 0;
                while(!c.isAfterLast()){

                    Log.d("SUMMM", ""+result+"+"+c.getLong(5));                 
                    result=(result + c.getLong(5));
                    Log.d("Answer:", "--"+result);
                    c.moveToNext();
                }
                Log.d("Toatal Con Time", ""+result);

                int mHour = (int) (result / (1000*60*60));
                int mMin = (int) ((result % (1000*60*60)) / (1000*60));
                int mSec  = (int) (((result % (1000*60*60)) % (1000*60)) / 1000);

                String connectionTime = mHour + ":" + mMin + ":" + mSec;
                Log.d("Formated Toatal Con Time", "" + connectionTime);

                Toast.makeText(getApplicationContext(),"Connection Duration :: "+connectionTime, Toast.LENGTH_LONG).show();
            }
        });

        btn_delete_records.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                new MyTask().execute();

            }
        });
    }

    public class MyTask extends AsyncTask<Void, Void, Void> {
        ProgressDialog dialog = new ProgressDialog(MainActivity.this);

        @Override
        protected void onPreExecute() {
            // update the UI immediately after the task is executed
            dialog.setMessage("Please wait...");
            dialog.setCancelable(false);
            dialog.show();

            super.onPreExecute();
        }

        @Override
        protected Void doInBackground(Void... arg0) {
            // TODO Auto-generated method stub
            mDatabase.delete("tbl_WifiDet",null,null);
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);
            try {
                dialog.dismiss();
            } catch (Exception e) {
                // TODO: handle exception
            }
            Toast.makeText(getApplicationContext(), "Record Delete Successfully",Toast.LENGTH_LONG).show();

        }
    }
    @Override
    protected Dialog onCreateDialog(int id) {
        Dialog dialog = null;
        switch (id) {

        case CUSTOM_DIALOG_ID1:
            dialog = new Dialog(MainActivity.this);
            dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
            dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            dialog.setContentView(R.layout.wifi_list);
            list_wifiDet = (ListView) dialog.findViewById(R.id.list_wifiDet);
            break;
        }
        return dialog;
    }
    class MyCustomBaseAdapteradptWifiDet extends ArrayAdapter<String> 
    {
        public MyCustomBaseAdapteradptWifiDet(Context context, int textViewResourceId,ArrayList<String> object, ArrayList<String> aryConStatus, ArrayList<String> aryDate, ArrayList<String> aryTime) 
        {
            super(context, textViewResourceId, object);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent)
        {
            LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View v = inflater.inflate(R.layout.wifi_list_cell, null);
            final TextView lblSSID,lblStatus,lblDate,lblTime;
            lblSSID = (TextView) v.findViewById(R.id.view_ssid);
            lblStatus = (TextView) v.findViewById(R.id.view_connectionStatus);
            lblDate = (TextView) v.findViewById(R.id.view_Date);
            lblTime = (TextView) v.findViewById(R.id.view_Time);

            lblSSID.append(arySSID.get(position));
            lblStatus.append(aryConStatus.get(position));
            lblDate.append(aryDate.get(position));
            lblTime.append(aryTime.get(position));
            return v;
        }
    }

}
4

3 回答 3

4

如果您希望此 BroadcastReciever 仅用于更改wi-fi的状态(连接/断开连接) ,那么以下是您的解决方案:

而不是听动作 - android.net.conn.CONNECTIVITY_CHANGE& android.net.wifi.STATE_CHANGE,你应该只听广播android.net.wifi.WIFI_STATE_CHANGED

<receiver>将 manifest.xml 文件中的标记修改为:

<receiver android:name=".WiFiReceiver" >
            <intent-filter>
                <action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
            </intent-filter>
</receiver>

在您onReceive()的 BroadcastReceiver 方法中,处理 wi-fi 状态更改如下:

    public void onReceive(Context context, Intent intent) {

        if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {

            int newWifiState = intent.getIntExtra(
                    WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN);

            switch(newWifiState){

                case WifiManager.WIFI_STATE_ENABLED:

                    Toast.makeText(context, "Wi-fi is Connected", Toast.LENGTH_SHORT).show();
                    // Put your code here to perform actions when wi-fi is connected
                    break;

                case WifiManager.WIFI_STATE_DISABLED:

                    Toast.makeText(context, "Wi-fi Disconnected", Toast.LENGTH_SHORT).show();
                    // Put your code here to perform actions when wi-fi is disconnected
                    break;

        /* You can also handle cases for the states "Connecting" and "Disconnecting" 
        by switching for values WifiManager.WIFI_STATE_ENABLING and WifiManager.WIFI_STATE_DISABLING */
        }
    }

}

这对我来说非常好用,当 wi-fi 为“已连接”或“已断开”时,代码仅执行一次 :)

于 2013-08-06T14:37:47.610 回答
2

如果您想接收 WiFi 连接更改(不仅仅是禁用/启用),您只需检查android.net.wifi.STATE_CHANGE事件(注意,它与 不同android.net.wifi.WIFI_STATE_CHANGED,仅在禁用或启用 WiFi 时发送)。

您可以检查您是否已连接到 WiFi 网络,例如通过检查WifiManager.getConnectionInfo().getNetworkId(),如果它是 -1,那么您已断开连接。

我在我的 4.1.2 设备上尝试过,它只向我发送了一次广播。

public class WifiBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        int networkId = wifiManager.getConnectionInfo().getNetworkId();
        boolean isConnected = networkId != -1;

        if (isConnected)
        {
            Toast.makeText(context, "WiFi connected: " + wifiManager.getConnectionInfo().getSSID(), Toast.LENGTH_SHORT).show() ;
        }
        else
        {
            Toast.makeText(context, "WiFi disconnected.", Toast.LENGTH_SHORT).show() ;
        }
    }
}

如果它在 4.2.2 上发送超过 1 个广播,您应该得到一个 bool 值(myIsConnected在示例中),它指示最后一个广播是否表示您已连接,如下所示:

if (connected)
{
    if (!myIsConnected)
    {
        myIsConnected = true ;
        Toast.makeText(context, "WiFi connected: " + mWifiManager.getConnectionInfo().getSSID(), Toast.LENGTH_SHORT).show() ;
    }
}
else
{
    if (myIsConnected)
    {
        myIsConnected = false ;
        Toast.makeText(context, "WiFi disconnected.", Toast.LENGTH_SHORT).show() ;
    }
}

您需要android.permission.ACCESS_WIFI_STATE为了接收这些广播并访问 WifiManager。

于 2013-08-08T17:59:28.573 回答
0

尝试检查当前 Wifi 连接SupplicantState

于 2013-08-02T07:27:52.107 回答