我遇到一个问题,当我运行我的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;
}
}
}
答案 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)