我有一个问题,当我运行我的
Android应用程序,其中有广播接收器为WiFi.它在不同版本的Android OS上表现不同(如4.1.1和4.2.2).
当我在4.1.1上运行时,它工作完美就像广播接收器在Wifi状态改变时接收广播.(在断开wifi广播接收时,我已经计算了wifi连接的总时间并将其存储在数据库中).
但是当我在4.2.2上运行它时,广播接收器在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); 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",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","DISCONNECTED"); myval.put("Date",DcdateText); myval.put("Time",DctimeText); myval.put("Total_Connection_Time",diff); MainActivity.mDatabase.insert("tbl_WifiDet",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",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",myval); myval.put("SSID","evosys2"); mDatabase.insert("tbl_SSID","ROUTE-999"); mDatabase.insert("tbl_SSID",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); 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,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); 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); 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; } } }
解决方法
如果您希望此BroadcastReciever仅用于更改wi-fi的状态(已连接/已断开连接),则以下是您的解决方案:
而不是倾听行动 – android.net.conn.CONNECTIVITY_CHANGE& android.net.wifi.STATE_CHANGE,你应该只收听android.net.wifi.WIFI_STATE_CHANGED的广播
<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“连接”或“断开连接”时代码才执行一次:)