My alarmManager is in the MainActivity it fires every 30 second to the MyReceiver
class then from it I start the GetLLRD
IntentService class. Thereafter, I am sending a request from the onHandleIntent
method to the Server following which I am getting a Response. Now I want to achieve the following, every time the alarmManager fires in the MainActivity
I want to pass the Intent from the Response from the Server in the GetLLRD
class to the Map
class.
I have tried it twice with the intent's code in the GetLLRD class with this part Intent intent1 = new Intent(this, Map.class);
I received the intent just once in the Map
activity. With this one Intent intent1 = new Intent(mContext, Map.class);
the app crashes and I got this error below. How can I achieve my purposes?
Error:
07-08 13:04:33.482: E/AndroidRuntime(16838): FATAL EXCEPTION: IntentService[IntentService]
07-08 13:04:33.482: E/AndroidRuntime(16838): Process: com.bustracker, PID: 16838
07-08 13:04:33.482: E/AndroidRuntime(16838): java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
07-08 13:04:33.482: E/AndroidRuntime(16838): at android.content.ComponentName.<init>(ComponentName.java:77)
07-08 13:04:33.482: E/AndroidRuntime(16838): at android.content.Intent.<init>(Intent.java:4570)
07-08 13:04:33.482: E/AndroidRuntime(16838): at com.bustracker.GetLLRD.onHandleIntent(GetLLRD.java:98)
07-08 13:04:33.482: E/AndroidRuntime(16838): at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
07-08 13:04:33.482: E/AndroidRuntime(16838): at android.os.Handler.dispatchMessage(Handler.java:102)
07-08 13:04:33.482: E/AndroidRuntime(16838): at android.os.Looper.loop(Looper.java:145)
07-08 13:04:33.482: E/AndroidRuntime(16838): at android.os.HandlerThread.run(HandlerThread.java:61)
MainActivity:
public class MainActivity extends ActionBarActivity{
Context context;
getLRLD.received_MainActvity_Context(context);
Intent intent = new Intent(MainActivity.this,
IntentReceiver.class);
intent.putExtra("json_data", json);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
getApplicationContext(), 1, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar cal = Calendar.getInstance();
alarm.setRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(), 30 * 1000,
pendingIntent);
startService(intent);
}
MyReceiver class:
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
try {
String action = intent.getStringExtra("json_data");
if (!action.isEmpty()) {
startService(context, action);
}
} catch (Exception e) {
}
}
public void startService(Context context, String action) {
Intent inetent = new Intent(context, GetLLRD.class);
inetent.putExtra("json_data", action);
context.startService(inetent);
}
}
GetLLRD class:
public class GetLLRD extends IntentService {
Context mContext;
public GetLLRD() {
super("IntentService");
}
public void received_MainActvity_Context(Context context){
this.mContext = context;
}
@Override
protected void onHandleIntent(Intent intent) {
String jSONString = intent.getStringExtra("json_data");
if (jSONString != null) {
//So if I try it in this way I am just receiving the data intent just once in the Map activity.
Intent intent1 = new Intent(this, Map.class);
intent1.putExtra("list_data", data);
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent1);
//When I do it in this way I am getting the error above:
Intent intent1 = new Intent(mContext, Map.class);
intent1.putExtra("list_data", data);
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent1);
}
}
}
Map activity:
public class Map extends ActionBarActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = getIntent();
@SuppressWarnings("unchecked")
ArrayList<ItemDTO> list =(ArrayList<ItemDTO>) intent.getSerializableExtra("list_data");
for (ItemDTO itemDTO : list) {
double latitude = itemDTO.getLatitude();
double longitude = itemDTO.getLongitude();
int route = itemDTO.getRoute();
String direction = itemDTO.getDirection();
System.out.println("test from Map activity: " + latitude + ", " + longitude
+ ", " + ", " + route + ", " + direction);
}
}
}
Edit:
GetLLRD IntentService class:
if (data != null && !data.isEmpty()) {
Intent localIntent = new Intent(
Constants.BROADCAST_ACTION).putExtra(
"data_list", data);
LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
}
Inside the Map activity:
onCraete(Bundle savedInstanceState){
IntentFilter data_filter = new IntentFilter();
data_filter.addAction(Constants.BROADCAST_ACTION);
registerReceiver(data_receiver, data_filter);
}
final BroadcastReceiver data_receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@SuppressWarnings("unchecked")
ArrayList<ItemDTO> list = (ArrayList<ItemDTO>) intent
.getSerializableExtra("list_data");
for (ItemDTO itemDTO : list) {
double latitude = itemDTO.getLatitude();
double longitude = itemDTO.getLongitude();
int route = itemDTO.getRoute();
String direction = itemDTO.getDirection();
System.out.println("test from Apple activity: " + latitude
+ ", " + longitude + ", " + ", " + route + ", "
+ direction);
}
}
};
Your architecture is flawed. The
IntentService
is created when you callstartService()
. ThenonCreate()
andonHandleIntent()
is called in the Service. Upon completion ofonHandleIntent()
, if there are no other pending Intents to be processed the Service stops.You are making this call in
MainActivity
before you callstartService()
:You don't show how you are setting the reference variable
getLRLD
, but this isn't going to work. The Service isn't actually created until you callstartService()
.You are trying to establish a communcations channel between the Service and the Activity. However, you are using
IntentService
which is a non-persistent Service. It gets created as needed and when it has nothing to do it goes away. You therefore cannot pass a reference to the Service to the Activity, and you also should not pass a reference to the Activity to the Service.The best way to achieve communication between the Service and the Activity is one of the following:
Service sends a broadcast
Intent
with the data. The Activity can register a BroadcastRecevier to listen for this.Activity creates a
PendingIntent
containing the necessary ACTION, COMPONENT, etc. and passes this to the Service as an "extra" in theIntent
it uses when callingstartService()
. The Service callssend()
on thatPendingIntent
in order to return data to the Activity.In both cases the Service doesn't need to know anything about the Activity, and the Activity doesn't need a reference to the Service.
EDIT: Add code to start Activity
If you want to start an Activity, you can do this in the
Service.onHandleIntent()
:Using
Intent.FLAG_ACTIVITY_SINGLE_TOP
will prevent Android from launching a new instance of the Activity, if there is already an instance of the Activity running. In case the Activity is already running, you can get the "extras" from theIntent
by overridingonNewIntent()
in the Activity.If you use this approach you don't need to use the broadcast Intent to send the data from the Service to the Activity.