so i'm having a problem receiving intent from one of my services. I have been searching where the problem occur exactly and found that it occurs when the "TimerService" tries to broadcast the intent to the MainAcivity's fragment class. Here is the MainActicity class:
package com.exotics.buses;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.Location;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.NetworkInfo.State;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
@SuppressLint("NewApi")
public class MainActivity extends ActionBarActivity implements
NavigationDrawerFragment.NavigationDrawerCallbacks {
/**
* Fragment managing the behaviors, interactions and presentation of the
* navigation drawer.
*/
private static NavigationDrawerFragment mNavigationDrawerFragment;
/**
* Used to store the last screen title. For use in
* {@link #restoreActionBar()}.
*/
private static CharSequence mTitle;
/**
* Used to switch fragments when clicking on search icon on action bar.
*/
private static FragmentManager fManager;
/**
* Used to handle search EditText.
*/
private static EditText searchEditText;
/**
* Reference to "PlaceholderFragment" used to access current section number
* and to store all fragments numbers.
*/
private static PlaceholderFragment fragment;
/**
* Used to get the current section number.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Used to check for GPS and network settings.
*/
private LocationManager mLocationManager;
private ConnectivityManager mConnectivityManager;
private static boolean locationEnabled = false;
private static boolean networkEnabled = false;
/**
* Used to update the icon on the action bar.
*/
private static MenuItem actionbarMenu;
/**
* Used to manage keyboard (Show or Hide).
*/
private static InputMethodManager keyboardInput;
/**
* Used to manage UpdateService.
*/
private static Intent mServiceIntent;
private static String dataUrl = "com.exotics.buses.DATAURL";
/**
* Used to manage TimerService.
*/
static Intent timerIntent;
long timeSwapBuff = 0L;
long updatedTime = 0L;
static BroadcastReceiver broadcastReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNavigationDrawerFragment = (NavigationDrawerFragment) getSupportFragmentManager()
.findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
networkEnabled = isNetworkConnectionAvailable();
locationEnabled = isLocationServicesAvailable();
if (!networkEnabled)
Toast.makeText(getApplicationContext(),
"Internet connection not available.", Toast.LENGTH_LONG)
.show();
keyboardInput = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
/*
* Creates a new Intent to start the RSSPullService IntentService.
* Passes a URI in the Intent's "data" field.
*/
// mServiceIntent = new Intent(this, UpdateService.class);
}
@Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager
.beginTransaction()
.replace(R.id.container,
PlaceholderFragment.newInstance(position + 1)).commit();
fManager = getSupportFragmentManager();
}
public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.title_section1);
break;
case 2:
mTitle = getString(R.string.title_section2);
break;
case 3:
mTitle = getString(R.string.title_section3);
break;
}
}
public void restoreActionBar() {
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
if (isHomeSectionPresent())
actionbarMenu.setIcon(R.drawable.ic_search_actionbar);
else
actionbarMenu.setIcon(R.drawable.ic_map_actionbar);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.main, menu);
actionbarMenu = menu.findItem(R.id.action_bar);
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment implements
LocationListener, android.location.LocationListener,
UpdateReceiver.Receiver {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private View rootView;
/**
* Google Maps Variables.
*/
private MapView mMapView;
private GoogleMap mMap;
private Bundle mBundle;
private LocationManager locationManager;
private static final long MIN_TIME = 400;
private static final float MIN_DISTANCE = 1000;
private boolean isMapInitialized = false;
/**
* UpdateReciver manager.
*/
private UpdateReceiver mReceiver;
/**
* Returns a new instance of this fragment for the given section number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (getArguments().getInt(ARG_SECTION_NUMBER) == 1) {
rootView = inflater.inflate(R.layout.fragment_main, container,
false);
updateView();
if (hasLocation() && hasNetwork())
initializeMap();
return rootView;
}
rootView = inflater.inflate(R.layout.fragment_default, container,
false);
if (keyboardInput != null) {
keyboardInput.toggleSoftInput(
InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
}
return rootView;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((MainActivity) activity).onSectionAttached(getArguments().getInt(
ARG_SECTION_NUMBER));
}
/**
* Google Maps Functions.
*/
private void initializeMap() {
locationManager = (LocationManager) getActivity()
.getApplicationContext().getSystemService(
Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, MIN_TIME, MIN_DISTANCE,
this);
// Can also use LocationManager.GPS_PROVIDER and
// LocationManager.PASSIVE_PROVIDER
MapsInitializer.initialize(getActivity());
mMapView = (MapView) rootView.findViewById(R.id.map);
mMapView.onCreate(mBundle);
isMapInitialized = true;
setUpMapIfNeeded(rootView);
}
private void setUpMapIfNeeded(View inflatedView) {
if (mMap == null) {
mMap = ((MapView) inflatedView.findViewById(R.id.map)).getMap();
if (mMap != null) {
setUpMap();
}
}
}
private void setUpMap() {
mMap.setMyLocationEnabled(true);
mMap.setOnMapLongClickListener(new OnMapLongClickListener() {
@Override
public void onMapLongClick(LatLng point) {
mMap.addMarker(new MarkerOptions()
.title("Bus Location")
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.ic_map_marker))
// .anchor(0.0f, 1.0f) // Anchors the marker on the
// // bottom left
.snippet("MARKER TEST").position(point));
}
});
startUpdateService(); // Start UpdateService
startTimerService(); // Start TimerService
}
@Override
public void onResume() {
super.onResume();
if (getArguments().getInt(ARG_SECTION_NUMBER) == 1) {
updateView();
if (isMapInitialized)
mMapView.onResume();
}
}
@Override
public void onPause() {
super.onPause();
if (getArguments().getInt(ARG_SECTION_NUMBER) == 1
&& isMapInitialized)
mMapView.onPause();
}
@Override
public void onDestroy() {
if (getArguments().getInt(ARG_SECTION_NUMBER) == 1
&& isMapInitialized)
mMapView.onDestroy();
super.onDestroy();
}
@Override
public void onLocationChanged(Location location) {
LatLng latLng = new LatLng(location.getLatitude(),
location.getLongitude());
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(
latLng, 15);
mMap.animateCamera(cameraUpdate);
locationManager.removeUpdates(this);
}
private boolean hasLocation() {
return locationEnabled;
}
private boolean hasNetwork() {
return networkEnabled;
}
/**
* Updates the fragment view depending on the availability of location
* services and Internet connection.
*/
private void updateView() {
if (hasNetwork() == false && hasLocation() == true) {
TextView textView = (TextView) rootView
.findViewById(R.id.NetworkLocationText);
Button btn = (Button) rootView.findViewById(R.id.GPSButton);
btn.setVisibility(View.INVISIBLE);
btn = (Button) rootView.findViewById(R.id.NetworkButton);
btn.setVisibility(View.VISIBLE);
textView.setText(getString(R.string.NetworkNotAvailable));
} else if (hasNetwork() == true && hasLocation() == false) {
TextView textView = (TextView) rootView
.findViewById(R.id.NetworkLocationText);
Button btn = (Button) rootView.findViewById(R.id.NetworkButton);
btn.setVisibility(View.INVISIBLE);
btn = (Button) rootView.findViewById(R.id.GPSButton);
btn.setVisibility(View.VISIBLE);
textView.setText(getString(R.string.GPSNotAvailable));
} else if (hasNetwork() && hasLocation()) {
TextView textView = (TextView) rootView
.findViewById(R.id.NetworkLocationText);
textView.setVisibility(View.INVISIBLE);
Button btn = (Button) rootView.findViewById(R.id.NetworkButton);
btn.setVisibility(View.INVISIBLE);
btn = (Button) rootView.findViewById(R.id.GPSButton);
btn.setVisibility(View.INVISIBLE);
}
}
private void startUpdateService() {
/* Starting Update Service */
mReceiver = new UpdateReceiver(new Handler());
mReceiver.setReceiver(this);
mServiceIntent = new Intent(Intent.ACTION_SYNC, null,
getActivity(), UpdateService.class);
/* Send optional extras to Update IntentService */
mServiceIntent.putExtra("url", dataUrl);
mServiceIntent.putExtra("receiver", mReceiver);
mServiceIntent.putExtra("isMapInitialized", isMapInitialized);
getActivity().startService(mServiceIntent);
}
private void startTimerService() {
timerIntent = new Intent(getActivity(), TimerService.class);
getActivity().startService(timerIntent);
getActivity().registerReceiver(broadcastReceiver,
new IntentFilter(TimerService.BROADCAST_ACTION));
broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updateService(intent);
}
};
}
private void updateService(Intent intent) {
boolean startservice = intent.getBooleanExtra("StratUpdateService",
false);
if (startservice) {
}
startUpdateService(); // Restart Update service with an interval.
}
@Override
public void onReceiveResult(int resultCode, Bundle resultData) {
switch (resultCode) {
case UpdateService.STATUS_RUNNING:
/*
* TODO: show the user that something is running in the
* background (progress bar maybe).
*/
break;
case UpdateService.STATUS_FINISHED:
// TODO: Hide progress bar & extract results from bundle */
boolean doClear = resultData.getBoolean("clear", true);
double[][] results = null;
Object[] objectArray = (Object[]) resultData
.getSerializable("results");
if (objectArray != null) {
results = new double[objectArray.length][];
for (int i = 0; i < objectArray.length; i++) {
results[i] = (double[]) objectArray[i];
}
}
// TODO: Update Map with new results */
if (doClear) {
mMap.clear();
int row = results.length;
for (int i = 0; i < row; i++) {
Log.d("Location", String.valueOf(results[i][0]) + " "
+ String.valueOf(results[i][1]));
LatLng point = new LatLng(results[i][0], results[i][1]);
mMap.addMarker(new MarkerOptions()
.title("Bus Location")
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.ic_map_marker))
.snippet("MARKER TEST").position(point));
}
}
break;
case UpdateService.STATUS_ERROR:
// TODO: Handle the error */
String error = resultData.getString(Intent.EXTRA_TEXT);
Toast.makeText(getActivity(), error, Toast.LENGTH_LONG).show();
break;
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
}
// onResume will be used to handle fragment's view widgets
@Override
public void onResume() {
super.onResume();
resetFragment();
fManager = getSupportFragmentManager();
searchEditText = (EditText) findViewById(R.id.search_box);
searchEditText.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event) {
boolean handled = false;
String searchQuery = "";
if (actionId == EditorInfo.IME_ACTION_SEARCH
|| event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
searchQuery = String.valueOf(searchEditText.getText());
ServerHandler.pullData(searchQuery);
handled = true;
}
return handled;
}
});
}
// TODO: check this out maybe!
// @Override
// public void onPause(){
// super.onPause();
// unregisterReceiver(broadcastReceiver);
// stopService(timerIntent);
// }
// Focus on search edit box
public static void focusOnSearch(Activity activity) {
if (fragment.getArguments().getInt(ARG_SECTION_NUMBER) == 1) {
searchEditText = (EditText) ((MainActivity) activity)
.findViewById(R.id.search_box);
searchEditText.requestFocus();
if (keyboardInput != null) {
keyboardInput.toggleSoftInput(0,
InputMethodManager.SHOW_IMPLICIT);
}
} else {
fManager.beginTransaction()
.replace(R.id.container, PlaceholderFragment.newInstance(1))
.commit();
mNavigationDrawerFragment = (NavigationDrawerFragment) ((MainActivity) activity)
.getSupportFragmentManager().findFragmentById(
R.id.navigation_drawer);
mTitle = ((MainActivity) activity)
.getString(R.string.title_section1);
actionbarMenu.setIcon(R.drawable.ic_search_actionbar);
}
}
private boolean isNetworkConnectionAvailable() {
mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = mConnectivityManager.getActiveNetworkInfo();
if (info == null)
return false;
State network = info.getState();
return (network == NetworkInfo.State.CONNECTED || network == NetworkInfo.State.CONNECTING);
}
private boolean isLocationServicesAvailable() {
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
return (mLocationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER));
}
private boolean isHomeSectionPresent() {
if (fragment.getArguments().getInt(ARG_SECTION_NUMBER) == 1)
return true;
else
return false;
}
public void resetFragment() {
// Do rechecks on location services and network state.
networkEnabled = isNetworkConnectionAvailable();
locationEnabled = isLocationServicesAvailable();
// Update the main content by replacing home fragment with it self.
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager
.beginTransaction()
.replace(
R.id.container,
PlaceholderFragment.newInstance(fragment.getArguments()
.getInt(ARG_SECTION_NUMBER))).commit();
fManager = getSupportFragmentManager();
}
// OnClick, refresh fragment.
public void tryAgain(View view) {
resetFragment();
Toast.makeText(getApplicationContext(), "Reset", Toast.LENGTH_SHORT)
.show();
}
// OnClick, Call GPS settings activity.
public void locationSettings(View view) {
Intent settingsIntent = new Intent(
Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(settingsIntent);
}
}
And here is the TimerService:
package com.exotics.buses;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
public class TimerService extends Service {
private Intent intent;
public static final String BROADCAST_ACTION = "com.exotics.buses.MainActivity.PlaceholderFragment";
private static final String TAG = "TimerService";
private Handler handler = new Handler();
long timeInMilliseconds = 0L;
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "Service Started!");
intent = new Intent(BROADCAST_ACTION);
handler.removeCallbacks(setupUpdateService);
handler.postDelayed(setupUpdateService, 10000); // 10 second
}
private Runnable setupUpdateService = new Runnable() {
public void run() {
Log.d(TAG, "Runnable Started!");
startUpdateService();
handler.postDelayed(this, 10000); // 10 seconds
}
};
private void startUpdateService() {
intent.putExtra("StratUpdateService", true);
Log.d(TAG, "Broadcastting!");
sendBroadcast(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy!");
handler.removeCallbacks(setupUpdateService);
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
And here is the error:
03-11 18:08:13.738: E/AndroidRuntime(27035): FATAL EXCEPTION: main
03-11 18:08:13.738: E/AndroidRuntime(27035): java.lang.RuntimeException: Error receiving broadcast Intent { act=com.exotics.buses.MainActivity.PlaceholderFragment flg=0x10 (has extras) } in com.exotics.buses.MainActivity$PlaceholderFragment$2@413ca660
03-11 18:08:13.738: E/AndroidRuntime(27035): at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:768)
03-11 18:08:13.738: E/AndroidRuntime(27035): at android.os.Handler.handleCallback(Handler.java:725)
03-11 18:08:13.738: E/AndroidRuntime(27035): at android.os.Handler.dispatchMessage(Handler.java:92)
03-11 18:08:13.738: E/AndroidRuntime(27035): at android.os.Looper.loop(Looper.java:137)
03-11 18:08:13.738: E/AndroidRuntime(27035): at android.app.ActivityThread.main(ActivityThread.java:5227)
03-11 18:08:13.738: E/AndroidRuntime(27035): at java.lang.reflect.Method.invokeNative(Native Method)
03-11 18:08:13.738: E/AndroidRuntime(27035): at java.lang.reflect.Method.invoke(Method.java:511)
03-11 18:08:13.738: E/AndroidRuntime(27035): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
03-11 18:08:13.738: E/AndroidRuntime(27035): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
03-11 18:08:13.738: E/AndroidRuntime(27035): at dalvik.system.NativeStart.main(Native Method)
03-11 18:08:13.738: E/AndroidRuntime(27035): Caused by: java.lang.NullPointerException
03-11 18:08:13.738: E/AndroidRuntime(27035): at android.content.ComponentName.<init>(ComponentName.java:75)
03-11 18:08:13.738: E/AndroidRuntime(27035): at android.content.Intent.<init>(Intent.java:3588)
03-11 18:08:13.738: E/AndroidRuntime(27035): at com.exotics.buses.MainActivity$PlaceholderFragment.startUpdateService(MainActivity.java:405)
03-11 18:08:13.738: E/AndroidRuntime(27035): at com.exotics.buses.MainActivity$PlaceholderFragment.updateService(MainActivity.java:436)
03-11 18:08:13.738: E/AndroidRuntime(27035): at com.exotics.buses.MainActivity$PlaceholderFragment.access$1(MainActivity.java:430)
03-11 18:08:13.738: E/AndroidRuntime(27035): at com.exotics.buses.MainActivity$PlaceholderFragment$2.onReceive(MainActivity.java:425)
03-11 18:08:13.738: E/AndroidRuntime(27035): at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:758)
03-11 18:08:13.738: E/AndroidRuntime(27035): ... 9 more
So please what am i doing wrong? Also is there a better way to approach this?