I faced to one problem on android 4.0.3 (on 4.1.2 it works fine). I have in my Activity BroadcastReceiver. When I send a broadcast, method onReceive() called always twice. P
Inatialize BroadcastReciver
on onStart()
. This fix my problem.
I had same issue.
onReceive()
gets called twice because i was registering Broadcast receiver twice. One in my activity's onCreate()
and another in manifest
.
I remove broadcast receiver registration from onCreate()
and it's working fine. Register your broadcast receiver in only one of them.
There are two ways to do this:
Which method (static or dynamic) to use when depends completely upon what you’re trying to do. Basically when you want to do some changes right on the screen (home screen, launcher, status bar, etc.) by showing up some notification or some indicator in the status bar by listening to system wide events or maybe those sent by other apps, then it make sense to use statically registered broadcast receivers. Whereas based on similar events you want to do changes right in your app when the user is using it or maybe it’s put in the background, then it makes sense to use dynamically registered receivers which’ll last till the registering components are destroyed.
For more info: http://codetheory.in/android-broadcast-receivers/
You can also implement it by setting a boolean flag, when you enter to onReceive()
function
I believe this is the correct way to determine if Wifi has connected or disconnected.
The onReceive() method in the BroadcastReceiver:Just put a Simple checking(Its a logic implemented by SharedPreferences):
package com.example.broadcasttest;
import java.util.List;
import java.util.Random;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.util.Log;
import android.widget.Toast;
public class CustomReceiver extends BroadcastReceiver {
boolean isInternetPresent = false;
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
ActivityManager am = (ActivityManager) context
.getSystemService(Activity.ACTIVITY_SERVICE);
String packageName = am.getRunningTasks(1).get(0).topActivity
.getPackageName();
@SuppressWarnings("deprecation")
List<RunningTaskInfo> taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = taskInfo.get(0).topActivity;
if(packageName.equals("com.example.broadcasttest") && taskInfo.get(0).topActivity.getClassName().toString().equals("com.example.broadcasttest.MainActivity"))
{
// SharedPreferences sharedPreferences=context.getSharedPreferences("FLAG", Context.MODE_PRIVATE);
// String check=sharedPreferences.getString("check","");
ConnectionDetector cd = new ConnectionDetector(context);
// get Internet status
isInternetPresent = cd.isConnectingToInternet();
// check for Internet status
if (isInternetPresent) {
SharedPreferences sharedPreferences=context.getSharedPreferences("FLAG", Context.MODE_PRIVATE);
String check=sharedPreferences.getString("check","");
if(check.equals("chkd1")){
Log.d("activity name", "CURRENT Activity ::" + taskInfo.get(0).topActivity.getClassName()+" Package Name : "+componentInfo.getPackageName());
String abc = context.getClass().toString();
Toast.makeText(context, "hiiii "+abc, Toast.LENGTH_SHORT).show();
Log.e("ghorar kochu", "checking:");
MainActivity m = new MainActivity();
m.abc(context);
}
else if(check.equals("chkd"))
{
Log.e("Thanks For the checking", "checking:"+check);
}
}
else if (!isInternetPresent) {
SharedPreferences sharedPreferences1=context.getSharedPreferences("FLAG", Context.MODE_PRIVATE);
SharedPreferences.Editor editor1=sharedPreferences1.edit();
editor1.putString("check","chkd1");
editor1.commit();
}
}
}
}
This is actual receiver class.Now coming to the main activity.
package com.example.broadcasttest;
import java.net.URLEncoder;
import java.util.ArrayList;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
public class MainActivity extends Activity {
Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences sharedPreferences1=getSharedPreferences("FLAG", Context.MODE_PRIVATE);
SharedPreferences.Editor editor1=sharedPreferences1.edit();
editor1.putString("check","chkd1");
editor1.commit();
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent in =new Intent(MainActivity.this,Second.class);
startActivity(in);
}
});
}
public void abc(Context context){
try{
SharedPreferences sharedPreferences1=context.getSharedPreferences("FLAG", Context.MODE_PRIVATE);
SharedPreferences.Editor editor1=sharedPreferences1.edit();
editor1.putString("check","chkd");
editor1.commit();
}
catch(NullPointerException e)
{
e.printStackTrace();
}
new JsonForTimeLineList().execute();
}
class JsonForTimeLineList extends AsyncTask<Void, Void, Void> {
private String msg = null;
@Override
protected void onPreExecute() {
super.onPreExecute();
// pDialog.show();
}
@Override
protected Void doInBackground(Void... params) {
return null;
}
@Override
protected void onPostExecute(Void resultaaa) {
Log.e("hi", "helo");
}
}
}
This code only works when your app is onresume state and when it is in MainActivity.
Here is my ConnectionDetector class.Through which i am checking the connection of wifi.
package com.example.broadcasttest;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
public class ConnectionDetector {
private Context _context;
public ConnectionDetector(Context context){
this._context = context;
}
public boolean isConnectingToInternet(){
ConnectivityManager connectivity = (ConnectivityManager) _context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity != null)
{
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null)
for (int i = 0; i < info.length; i++)
if (info[i].getState() == NetworkInfo.State.CONNECTED)
{
return true;
}
}
return false;
}
}
And here is my Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.broadcasttest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<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=".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>
<activity
android:name=".Second"
android:label="@string/app_name" >
</activity>
<receiver android:name="com.example.broadcasttest.CustomReceiver">
<intent-filter >
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
</application>
</manifest>
And here is my log when i am enable the wifi.
11-19 20:13:11.474: D/activity name(25417): CURRENT Activity ::com.example.broadcasttest.MainActivity Package Name : com.example.broadcasttest
11-19 20:13:11.481: E/ghorar kochu(25417): checking:
11-19 20:13:11.542: E/hi(25417): helo
11-19 20:13:11.573: V/RenderScript(25417): Application requested CPU execution
11-19 20:13:11.580: V/RenderScript(25417): 0xb90a7850 Launching thread(s), CPUs 4
11-19 20:13:17.158: E/Thanks For the checking(25417): checking:chkd
If you have any query just let me know.
I faced a similar problem, but my BroadcastReceiver
was static because I wanted to use it as an inner class, what I did was to register the receiver (in order to create the static instance), then unregister the same receiver, that made it be called once which is by the AlarmManager
timer, ofcourse code is always much explanatory :
public void setAlarm(Context context) {
Log.d("EX", "Alarm SET !!");
Intent intent = new Intent("com.example.START_ALARM");
IntentFilter myIf = new IntentFilter("com.example.START_ALARM");
PendingIntent sender = PendingIntent.getBroadcast(context, 192837,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
myBroadcastReceiver mbr = new myBroadcastReceiver();
// ****Here goes the trick.****
context.registerReceiver(mbr, myIf);
context.unregisterReceiver(mbr);
// Get the AlarmManager service
AlarmManager am = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Long firstTime = SystemClock.elapsedRealtime()
+ TimeUnit.SECONDS.toMillis(70);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime,
TimeUnit.SECONDS.toMillis(70), sender);
}
I feel that it would be best to register the receiver after you have overridden the BroadcastReceiver
and before starting the intent from which you want to receive data.(Otherwise it may throw a NullPointerException
.
Unregister the reciever in onStop()
rather than in onPause()
.
I have noticed that unregistering the receiver in the onPause()
creates problems if you have services or background tasks to be executed, which will pause the activity and hence unregister your Broadcast Receiver. (This will result in multiple calls to the onRecieve()
method, i.e. each time the receiver is re-registered.)