Memory leak happening. Unable to detect the leak and clean it - java

I have the below ConnectivityReceiver class that extends BroadcastReceiver which is used to check the internet connection.
Also there is another activity SplashActivity, which implements this class for checking the internet connection. I am registering the receiver in OnCreate and unregistering it in the OnDestroy method. But still, after going to next activity, LeakCanary shows memory leak in SplashActivity.
I have instantiated LeakCanary and few methods in MyApplication class.
Please find below the screenshot of the leak.
Can someone please help me in detecting the memory leak and solving this issue?
ConnectivityReceiver.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
public class ConnectivityReceiver extends BroadcastReceiver
{
public static ConnectivityReceiverListener connectivityReceiverListener;
public ConnectivityReceiver()
{
super();
}
#Override
public void onReceive(Context context, Intent arg1)
{
if(arg1.getAction() != null && arg1.getAction().equalsIgnoreCase(ConnectivityManager.CONNECTIVITY_ACTION))
{
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if(cm != null)
{
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
if (connectivityReceiverListener != null)
connectivityReceiverListener.onNetworkConnectionChanged(isConnected);
}
}
}
public static boolean isConnected()
{
ConnectivityManager cm = (ConnectivityManager) MyApplication.getInstance().getApplicationContext()
.getSystemService(Context.CONNECTIVITY_SERVICE);
if(cm != null)
{
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
}
return false;
}
public interface ConnectivityReceiverListener
{
void onNetworkConnectionChanged(boolean isConnected);
}
}
MyApplication.java
import android.app.Application;
import com.squareup.leakcanary.LeakCanary;
public class MyApplication extends Application
{
private static MyApplication mInstance;
#Override
public void onCreate()
{
super.onCreate();
mInstance = this;
if(LeakCanary.isInAnalyzerProcess(this))
return;
LeakCanary.install(this);
}
public static synchronized MyApplication getInstance()
{
return mInstance;
}
public void setConnectivityListener(ConnectivityReceiver.ConnectivityReceiverListener listener)
{
ConnectivityReceiver.connectivityReceiverListener = listener;
}
}
SplashActivity.java
public class SplashActivity extends AppCompatActivity implements ConnectivityReceiver.ConnectivityReceiverListener
{
final int REQUEST_CODE_RECOVER_PLAY_SERVICES = 1001, PERMISSION_READ_STORAGE = 0;
RelativeLayout relativeLayout;
IntentFilter intentFilter;
ConnectivityReceiver connectivityReceiver;
Bitmap thumbnail;
#Override
public void onCreate(Bundle icicle)
{
super.onCreate(icicle);
Fabric.with(this, new Crashlytics());
setContentView(R.layout.activity_main);
intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
connectivityReceiver = new ConnectivityReceiver();
registerReceiver(connectivityReceiver, intentFilter);
if(checkInternet())
{
Intent mainIntent = new Intent(SplashActivity.this, WelcomeActivity.class);
SplashActivity.this.startActivity(mainIntent);
SplashActivity.this.finish();
}
}
boolean checkInternet()
{
boolean isConnected = ConnectivityReceiver.isConnected();
showSnack(isConnected);
return isConnected;
}
private void showSnack(boolean isConnected)
{
Snackbar snackbar = Snackbar.make(relativeLayout, AppConfig.noInternet, Snackbar.LENGTH_INDEFINITE);
if(!isConnected)
{
snackbar.setAction("GO OFFLINE", new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent mainIntent = new Intent(SplashActivity.this, WelcomeActivity.class);
SplashActivity.this.startActivity(mainIntent);
SplashActivity.this.finish();
}
});
View sbView = snackbar.getView();
TextView textView = sbView.findViewById(android.support.design.R.id.snackbar_text);
textView.setTextColor(Color.WHITE);
snackbar.setActionTextColor(getResources().getColor(R.color.colorPrimary));
snackbar.show();
}
else
snackbar.dismiss();
}
#Override
public void onDestroy() {
unregisterReceiver(connectivityReceiver);
connectivityReceiver = null;
super.onDestroy();
}
#Override
public void onPause()
{
super.onPause();
}
#Override
public void onResume()
{
super.onResume();
MyApplication.getInstance().setConnectivityListener(this);
}
#Override
public void onNetworkConnectionChanged(boolean isConnected)
{
showSnack(isConnected);
}
}

you need to unregisterReceiver(connectivityReceiver); receiver in onPause() or onStop();because onDestroy(); will not called until the Activity in stack of Activities. onDestroy(); will called when you will finish the Activity and unregisterReceiver(connectivityReceiver); will be excuted.

Related

How to update the UI with BroadcastReceiver onReceive in Android?

I want to update the UI according to the WiFi status in my Android app in Java. I am unable to update the UI to show the new string. Please help me.
Here is my code
public class MainActivity extends AppCompatActivity {
IntentFilter intentFilter = new IntentFilter();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(new NetworkConnectionReceiver(), intentFilter);
TextView displayStatus = findViewById(R.id.displayStateTextView);
}
}
class NetworkConnectionReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
Log.i("MyReceiver", Boolean.toString(wifiManager.isWifiEnabled()));
}
}
Use this code:
public class MainActivity extends AppCompatActivity {
...
BroadcastReceiver br = new BroadcastReceiver(){
#Override
public void onReceive( Context context, Intent intent ){
//update UI here directly
View view = findViewById( R.id.example );
}
};
#Override
protected void onResume(){
super.onResume();
// Check state here
...
IntentFilter filter = new IntentFilter();
filter.addAction( ConnectivityManager.CONNECTIVITY_ACTION );
registerReceiver( br, filter);
}
#Override
protected void onPause(){
super.onPause();
unregisterReceiver( br );
}
...
}
You can do it using interface
interface WifiStateListener{
void onStateChanged(Boolean enabled);
}
Then add a constructor to pass the WifiStateListener to BroadcastReceiver
class NetworkConnectionReceiver extends BroadcastReceiver {
private WifiStateListener mWifiStateListener;
public NetworkConnectionReceiver(WifiStateListener wifistateListener){
mWifiStateListener = wifistateListener;
}
#Override
public void onReceive(Context context, Intent intent) {
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
if(mWifiStateListener != null){
mWifiStateListener.onStateChanged(wifiManager.isWifiEnabled());
}
Log.i("MyReceiver", Boolean.toString(wifiManager.isWifiEnabled()));
}
}
And in Activity, while registering receiver you can pass the interface
registerReceiver(new NetworkConnectionReceiver(enabled -> {
//do based on wifi state change
}), intentFilter);
Other options are to use EventBus, Observables etc
You can user LocalBroadCastManager.
First write broadCastReceiver in activity
register that broadcast with LocalBroadCastManager in onResume
unregister that broadcast with LocalBroadCastManager in onPause as well
than write Broadcast of internet connection and call LocalBroadCastManager which you register in activity
private BroadcastReceiver broadCastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction() == "local_broadcast_update_UI"){
updateUI()
}
}
};
#Override
protected void onResume(){
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver( broadCastReceiver, new
IntentFilter("local_broadcast_update_UI"));
}
#Override
protected void onPause(){
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver("local_broadcast_update_UI");
}
public class NetworkChangeReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, final Intent intent) {
final ConnectivityManager connMgr = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
final android.net.NetworkInfo wifi = connMgr
.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
final android.net.NetworkInfo mobile = connMgr
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (wifi.isAvailable() || mobile.isAvailable()) {
LocalBroadcastManager.getInstance(context).sendBroadcast(new
Intent("local_broadcast_update_UI"));
}
}
}

add snackbar in android activity from asynktask

From main activity i call this background process. here in this background there is onprexecute method there is an if else condition in else part i need to add a Snackbar
public class background extends AsyncTask<String,Void,String> {
private ProgressDialog dialog;
private ProgressDialog progressDialog;
private ConnectivityManager cm;
private String jsonurl, jsonstring;
public static String listRequest;
private mobile_form mform;
private Context ctx;
ProgressBar progressbar;
background (Context ctx){
this.ctx = ctx;
cm = (ConnectivityManager)ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
dialog = new ProgressDialog(ctx);
progressbar = new ProgressBar(ctx);
progressbar.getIndeterminateDrawable().setColorFilter(Color.parseColor("#039BE5"), android.graphics.PorterDuff.Mode.SRC_IN);
mform = new mobile_form();
}
#Override
protected void onPreExecute() {
super.onPreExecute();
jsonurl = "https://crackstrickblog.000webhostapp.com/json_get_data.php";
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
if (isConnected) {
dialog.setCancelable(false);
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
dialog.show();
dialog.setContentView(progressbar);
}
else {
// here i need to add snackbar like this
//Snackbar.make(this.findViewById(android.R.id.content), "Message", Snackbar.LENGTH_LONG).show();
}
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String result) {
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
if (isConnected) {
ctx.startActivity(new Intent(ctx, mobile_form.class));
if (dialog.isShowing())
dialog.dismiss();
}
}
#Override
protected String doInBackground(String... voids) {
return null;
}
}
This Snackbar.make(this.findViewById(android.R.id.content), "Message", Snackbar.LENGTH_LONG).show();
will not work. findViewById is a method of activity class not of AsyncTask.
Use interface as a callback.
interface Callback {
public void showSnackBar();
}
In AsyncTask
private Callback callback;
Then
public background (Context ctx){
callback =(Callback) ctx;
Then in onPreExecute
else {
if(callback!=null)
callback.showSnackbar();
}
In activity class implement the interface and the method
public YourActivity extends AppCompatActivity implements Callback {
Then
#Override
public void showSnackBar()
{
// show snack bar in activity
}
You could also use some event bus mechanism instead of the above.
You are not passing a context use your activity to find view in that context as you are in asynchronous class, you don't have access to your activity view.
Snackbar.make(MainActivity.this.findViewById(android.R.id.content), "Message", Snackbar.LENGTH_LONG).show();
A code snippet to display a basic SnackBar is shown below:
Snackbar snackbar = Snackbar
.make(coordinatorLayout, "www.journaldev.com", Snackbar.LENGTH_LONG);
snackbar.show();
In the above snippet make() method accepts three parameters:
coordinatorLayout : It is the root layout of the activity
www.journaldev.com : This is the message to be appear on snackbar, and we can customise it with our own message
Snackbar.LENGH_LONG : This is last parameter which is the time limit how long snackbar to be displayed
show() method is used to display the SnackBar on the screen.
Does this help you?

Can't create handler inside thread that has not called Looper.prepare() on locationManager in service

I is the first time I am working with the location manager and I always get the same error:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
This happens when i call .requestLocationUpdates on a locationManager. I don't know how can I put this in the Main UI thread. Here is the code of the service where the error occurs:
public class TrackerService extends Service {
private Context mContext;
private LocListener mlocListener;
private LocationManager mlocManager;
private final IBinder myBinder = new MyLocalBinder();
public void initiateTracking() {
this.mContext = getApplicationContext();
mlocManager = (LocationManager) this.mContext.getSystemService(Context.LOCATION_SERVICE);
mlocListener = new LocListener();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
}
public Boolean getGPSStatus(){
return mlocManager.isProviderEnabled(mlocManager.GPS_PROVIDER);
}
public Double[] getCurrentLocation(){
Double[] lonLat = new Double[]{mlocListener.getLon(), mlocListener.getLat()};
Log.d("DEBUG", "getCurrentLocation: " + lonLat);
return lonLat;
}
public class MyLocalBinder extends Binder {
public TrackerService getService() {
return TrackerService.this;
}
}
#Override
public IBinder onBind(Intent arg0) {
return myBinder;
}
#Override
public void onCreate()
{
isRunning = true;
}
#Override
public int onStartCommand(final Intent intent, int flags, int startId) {
new Thread(new Runnable() {
#Override
public void run() {
initiateTracking();
}
}).start();
return Service.START_STICKY;
}
#Override
public void onDestroy() {
isRunning = false;
}
}
Here is how i start my service and then bind to it:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
startService(new Intent(this, TrackerService.class));
bindService(new Intent(MainActivity.this, TrackerService.class), myConnection, Context.BIND_AUTO_CREATE);
}
You can add the code to run on the main UI Thread like this:
runOnUiThread(new Runnable() {
#Override
public void run() {
//your code here
}
});

How to access service functions from fragment, which is bound to parent activity in Android?

I have an Android activity with a viewpager fragment. In the onCreate method of the activity, I bind a service to it which constantly runs in the background.
In the fragment, on a certain condition I need to call a function in the service which deals with the condition. What is the correct way to access the service, and call it's functions?
MainActivity.java
public class MainActivity extends AppCompatActivity {
private String TAG = "MainActivity";
DbHelper dbHelper;
SessionManager sessionManager;
SessionCache sessionCache;
Map<String, ?> userDetails;
protected SocketListener socketService;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sessionManager = new SessionManager(getApplicationContext());
// Connect to background socketlistener service
Intent serviceIntent = new Intent(MainActivity.this, SocketListener.class);
startService(serviceIntent);
.
.
.
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.addTab(tabLayout.newTab().setText("").setIcon(getResources().getDrawable(R.drawable.profileicon)));
tabLayout.addTab(tabLayout.newTab().setText("").setIcon(getResources().getDrawable(R.drawable.homeicon)));
tabLayout.addTab(tabLayout.newTab().setText("").setIcon(getResources().getDrawable(R.drawable.chaticon)));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
final NonSwipeableViewPager viewPager = (NonSwipeableViewPager) findViewById(R.id.view_pager);
final CustomPagerAdapter pagerAdapter = new CustomPagerAdapter
(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(pagerAdapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
viewPager.setCurrentItem(1);
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
private ServiceConnection serviceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
socketService = ((SocketListener.LocalBinder) iBinder).getService();
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
socketService = null;
}
};
}
This is my service. I connect to a server, and constantly listen for updates.
SocketListener.java
package com.example.gopa2000.mobapps;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
import java.net.URISyntaxException;
import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;
public class SocketListener extends Service {
private static String TAG = "SocketListener";
private Socket socket;
public SocketListener() { }
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return localBinder;
}
private final IBinder localBinder = new LocalBinder();
public class LocalBinder extends Binder {
public SocketListener getService(){
Log.i(TAG, "getService: Sitting in local binder.");
return SocketListener.this;
}
public void sendMessage(String message){
socket.emit("match", message);
}
}
#Override
public void onCreate() {
super.onCreate();
}
public void isBoundable(){
Log.i(TAG, "Bind like a baller.");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Runnable connect = new ConnectSocket();
new Thread(connect).start();
return START_STICKY;
}
class ConnectSocket implements Runnable {
#Override
public void run() {
try {
socket = IO.socket(RESTClient.getURL());
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.i(TAG, "call: Connected to backend!");
}
});
socket.connect();
} catch (URISyntaxException e){
Log.e(TAG, "run: ", e);
}
}
}
public Socket getSocket(){
return this.socket;
}
}
And this is the fragment where I would need to call the sendMessage(string).
public class MainViewFragment extends Fragment {
private final String TAG = "MVFragment";
private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
private RecyclerView.Adapter adapter;
private SessionManager sessionManager;
private ArrayList<CustomCard> cards;
private CardAdapter cardAdapter;
private Button btn;
private SwipeFlingAdapterView flingContainer;
private Map<String, ?> userDetails;
// hax
private static String userEmail;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.from(getContext()).inflate(R.layout.fragment_main_view, container, false);
.
.
flingContainer.setAdapter(adapter);
flingContainer.setFlingListener(new SwipeFlingAdapterView.onFlingListener(){
.
.
#Override
public void onRightCardExit(Object o) {
.
.
if(match){
// need to call sendMessage from the service here. <------------------------
sessionCache.addToMatchTable(Liker, Likee);
}
}
#Override
public void onAdapterAboutToEmpty(int i) {
}
#Override
public void onScroll(float v) {
}
});
flingContainer.setOnItemClickListener(new SwipeFlingAdapterView.OnItemClickListener(){
#Override
public void onItemClicked(int itemPosition, Object dataObject){
Toast.makeText(getActivity(), "Clicked!", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(getActivity().getApplicationContext(), FullScreenCardLayout.class);
startActivity(intent);
}
});
return view;
}
First the method sendMessage(message) should be inside the service not the LocalBinder class
public class SocketListener extends Service {
public void sendMessage(String message){
socket.emit("match", message);
}
}
Second to access activity method from fragment you should create interface inside your fragment
interface MessageSender {
void sendMessage(String message);
}
then implement it in your activity
public class MainActivity extends AppCompatActivity implements MessageSender {
#Override
public void sendMessage(String message) {
// call the service here
socketService.sendMessage(message);
}
}
inside your fragment, implement onAttach() and initialize the interface instance
public class MainViewFragment extends Fragment {
private MessageSender mMessageSenderCallback;
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
mMessageSenderCallback = (MessageSender) context;
} catch (ClassCastException e) {
// Error, class doesn't implement the interface
}
}
#Override
public void onDetach() {
super.onDetach();
// Remove activity reference
mMessageSenderCallback = null;
}
}
To send a message, call mMessageSenderCallback.sendMessage(message) with your message inside the fragment.

Updating RecyclerView with adapter.notifyDataSetChanged()

I've implemented a RecyclerView which has a user interface of a timer counting down. I created a BroadcastService class which creates a CountDownTimer and broadcasts the timer's contents in the onTick() method to my MainActivity, where I use a BroadCast receiever to update the UI.
My BroadcastReceiver is only receiving the initial value from the BroadcastService. I figured that's because I hadn't notified the recycler view's adapter that the data had changed. However, because of variable scope, I'm unable to access my adapter from my broadcast receiver.
Perhaps I have a fundamental lack of understanding of variable scope, but how can I access the adapter from
adapter = new DataAdapter(getApplicationContext(), data);
in my broadcast receiver class? Because right now it's not being recognized.
This is my class definition + onCreate()
public class Profile_Page extends ActionBarActivity implements DataAdapter.ClickListener {
private RecyclerView recyclerView;
public DataAdapter adapter;
private Context context;
String currentUser;
Data current = new Data();
final List<Data> data = new ArrayList<>();
public static String BROADCAST_ACTION =
"packagename.countdown_br";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter();
filter.addAction(BROADCAST_ACTION);
filter.addCategory(Intent.CATEGORY_DEFAULT);
registerReceiver(br, filter);
startService(new Intent(this, Broadcast_Service.class));
setContentView(R.layout.activity_profile__page);
ParseQuery<ParseObject> query = ParseQuery.getQuery("ParseClass");
query.whereEqualTo("author", ParseUser.getCurrentUser());
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> list, ParseException e) {
if (e == null) {
for (ParseObject getData : list)
{
current.1= getData.getString("1");
current.2= getData.getString("2");
current.3= getData.getString("3");
current.4= getData.getString("4");
current.5= getData.getString("5");
data.add(current);
}
}
else {
}
adapter = new DataAdapter(getApplicationContext(), data);
recyclerView.setAdapter(adapter); //set recyclerView to this adapter
}
});
}
And here's my Broadcast Receiver code [which is also in MainActivity.java]
public BroadcastReceiver br = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateGUI(intent);
//HOW TO NOTIFY DATA SET CHANGE
}
};
public void updateGUI(Intent intent) {
if (intent.getExtras() != null) {
long millisUntilFinished = intent.getLongExtra("countdown", 0);
current.goalTimer = String.valueOf(intent.getExtras().getLong("countdown") / 1000);
}
}
And, if it is of any use, here's my Broadcast Service class:
public class Broadcast_Service extends Service {
private final static String TAG = "BroadcastService";
LocalBroadcastManager broadcastManager;
public static final String COUNTDOWN_BR = "packagename.countdown_br";
Intent bi = new Intent(COUNTDOWN_BR);
CountDownTimer cdt = null;
#Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "Starting timer...");
cdt = new CountDownTimer(30000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
bi.putExtra("countdown", millisUntilFinished);
sendBroadcast(bi);
}
#Override
public void onFinish() {
Log.i(TAG, "Timer finished");
}
};
cdt.start();
}
#Override
public void onDestroy() {
cdt.cancel();
Log.i(TAG, "Timer cancelled");
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
First of all, extend the BroadcastReciever class as follows:
public class MyReciever extends BroadcastReciever{
private Profile_Page activity;
public MyReciever(Profile_Page activity){
this.activity = activity;
}
#Override
public void onReceive(Context context, Intent intent) {
activity.updateGUI(intent);
}
}
Create a static instance of your activity and pass it to your receiver.
public class Profile_Page extends ActionBarActivity implements DataAdapter.ClickListener {
private static Profile_Page instance;
private MyReciever myReceiver;
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
instance = this;
myReceiver = new MyReciever(instance);
...
}
public void updateGUI(Intent intent) {
...
}
}
Now you can access your adapter quite easily. Hope this helps.

Categories

Resources