广播接收器在不同版本的Android(4.1.1& 4.2.2)上的工作方式不同

时间:2013-08-02 07:09:04

标签: android broadcastreceiver

我遇到一个问题,当我运行我的Android应用 WiFi 广播接收器时。它在不同版本的Android OS上表现不同(如 4.1.1 4.2.2 )。

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

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

所以我需要知道为什么会这样?为什么广播接收器 wifi断开连接时呼叫两次?对于所有 Android版本,我需要代码同样

这是我的代码。

Android Menifest文件

<?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;
        }
    }

}

3 个答案:

答案 0 :(得分:4)

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

而不是倾听行动 - android.net.conn.CONNECTIVITY_CHANGE&amp; android.net.wifi.STATE_CHANGE,您应该只收听android.net.wifi.WIFI_STATE_CHANGED

的广播

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

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

在BroadcastReceiver的onReceive()方法中,处理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“连接”或“断开连接”时代码只执行一次:)

答案 1 :(得分: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。

答案 2 :(得分:0)