Activity wait for Intent - android

What I'm trying to do
Hello Guys, I'm trying to create a SplashScreen which starts a Service over an Intent. After the Service is started to Activity(SplashScreen) should wait until it receive an Intent from my Service.
Question
What do I need to do, that my Activity waits until it received the Intent from my Service. It would be nice if you could provide me a good tutorial or some code-snippets.
Down here you find the Code of my SplashScreen.
Code
package de.stepforward;
import de.stepforward.service.VideoService;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public class SplashActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
// Sagt dem Video-Service das er beginnen soll die
// Videos herunter zu laden
Intent LoadVideos = new Intent(this, VideoService.class);
LoadVideos.putExtra("VIDEO_SERVICE", "start");
startService(LoadVideos);
// In this thread I want that it waits for my Intent
// and than it goes to the next Activity
Thread splashThread = new Thread() {
#Override
public void run() {
try {
int waited = 0;
while (waited < 3000) {
sleep(100);
waited += 100;
}
}
catch (InterruptedException e) {
// do nothing
}
finally {
finish();
final Intent Showvideo = new Intent(SplashActivity.this,
ChannelTest.class);
startActivity(Showvideo);
}
}
};
splashThread.start();
}
}

Here is what your architecture should look like :
INTENT_CST
String START_INIT_ACTION = "your.package.name.START_INIT";
String INIT_ENDED_ACTION = "your.package.name.INIT_ENDED";
SplashActivity
In onCreate:
startService(new Intent(START_INIT_ACTION)
In onResume:
If you choose to send a broadcast in your service :
registerReceiver(new BroadcastReceiver(){
//implement onChange()},
new IntentFilter(INIT_ENDED_ACTION));
In onPause, unregister your receiver to free memory
LoadingService
Extend AsyncTask to do your background stuff. In onPostExecute, 2 options :
startActivity(new Intent(...)) // as your doing in your post
or
sendBroadcast(new Intent(INIT_ENDED_ACTION)); stopSelf();
Your manifest
Declare the service LoadingService with an IntentFilter with an <action name="your.package.name.START_INIT"/>

See this link it might be helpful for you. You can monitor your service state from your activity.
Restful API service

starting a service does not affect foreground screen .so launch splashscreen and start service , as you are doing right now . do operations in service, after that start new activity form service itself .

Related

IntentService - Wakelock release issue

I have an alarm application.
Flow looks like this :
WakefulBroadcastReceiver(Acquires wakelock) --->> Intent service -->> startActivity
public class AlarmService extends IntentService {
protected void onHandleIntent(Intent intent) {
Intent activityIntent = new Intent(this, TriggeredActivity.class);
activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(activityIntent);
Basically WakefulBroadcaseReceiver starts an intent service using startWakefulService(). Inside intent service's onHandleIntent(), only work I am doing is further starting a new activity using startActivity(). That new activity is where I am using mediaPlayer in a loop, which sounds the alarm. That activity has a dismiss button, which waits for user click to stop the media player & activity finishes.
Now the problem I am facing is that after calling startactivity() inside intent service, I can not wait for TriggeredActivity to finish(no equivalent to startActivityForResult in Service) and then complete wakeful intent. Related link
startActivity(activityIntent);
WakefulBCastReceiver.completeWakefulIntent(intent); /* can't do here */
So I am not explicitly releasing wakelock here.
My question is will the wakelock be released automatically(link-to-death), when the process that is holding it is killed.
If yes, then in my particular scenario, I need not call WakefulBCastReceiver.completeWakefulIntent().
Yes, you need to use completeWakefulIntent.
You need to put your TriggeredActivity intent into EXTRAs.
#Override
public void onReceive(Context context, Intent intent) {
Intent intentService = new Intent(context, NotificationsIntentService.class);
// Inserting data inside the Intent
intentService.putExtra(NotificationsIntentService.EXTRA_NOTIF, new Intent(context, TriggeredActivity.class));
startWakefulService(context, intentService);
}
NotificationsIntentService.class
public class NotificationsIntentService extends IntentService {
private static final String TAG = "DebugNotifIntent";
public static final String EXTRA_NOTIF = "extra_notif";
public NotificationsIntentService(){
super(NotificationsIntentService.class.getSimpleName());
}
#Override
protected void onHandleIntent(Intent intent) {
Log.d(TAG, "onHandleIntent: ");
Intent extraIntent = intent.getParcelableExtra(EXTRA_NOTIF);
extraIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(extraIntent);
NotificationWakefulBroadcastReceiver.completeWakefulIntent(intent);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy: ");
}
}
I have managed to find a solution for my problem. I am now using a Messenger for message based cross process communication between intent service & triggered activity.
I am passing a handler - alarmServiceHandler, from intent service to activity through a messenger.
Handler alarmServiceHandler = new Handler(){
#Override
public void handleMessage(Message msg) {
if(msg.arg1 == 1) {
completedTriggeredActivity = true;
}
}
};
Inside onHandleIntent(), I am passing handler through Messenger object in intent's extra data.
Messenger alarmServiceMessenger = new Messenger(alarmServiceHandler);
Intent activityIntent = new Intent(this, TriggeredActivity.class);
activityIntent.putExtra("AlarmServiceMessenger", alarmServiceMessenger);
activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(activityIntent);
while(!completedTriggeredActivity){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
WakefulBCastReceiver.completeWakefulIntent(intent);
In TriggeredActivity, I am retrieving messenger in Dismiss button's OnClickListener, just before calling finish() on the activity. And sending back a message to AlarmService with arg = 1, implying end of processing in triggered activity.
buttonDismiss.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Messenger alarmServiceMessenger = getIntent().getParcelableExtra("AlarmServiceMessenger");
Message alarmServiceMessage = Message.obtain();
alarmServiceMessage.arg1 = 1;
try {
alarmServiceMessenger.send(alarmServiceMessage);
} catch (RemoteException e) {
e.printStackTrace();
}
finish();
}
After starting triggered activity, I am putting AlarmService in sleep mode till boolean variable completedTriggeredActivity has not been set to true in handleMessage(). Once true, it means triggered activity has finished & now I can proceed with releasing wake lock.
I would be glad to receive comments about my approach & any suggestions towards a better solution to my problem, than the one I have deviced.

broadcast message keeps coming into service after quit and re-start the activity which starts the service

I'm working on a Android APP. There's a main activity and a service. The service is started by calling startService(intent) in main activity. and it would be running in background no matter the activity is running or not. After the activity is created, it will send broadcast message to service to query some status. The first time of the running is okay, both activity and service initiated correctly. But I get an issue that when I quit the activity and restart it, the service will keep receiving the query message like the activity is sending it repeatedly. But I confirmed the sending code in activity was only executed once. Anyone have idea where the messages comes from?
the codes in main activity onCreate method
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.v("debug", "Main.onCreate");
Intent intent=new Intent(MainActivity.this, PingService.class);
startService(intent);
Intent intent = new Intent(PingService.ACTION_QUERY);
sendBroadcast(intent);
}
And below are codes in service
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(PingService.ACTION_QUERY)) {
Log.v("debug", "PingService.receiver.onReceive: ACTION_QUERY");
//the program keeps coming here
}
}
};
#Override
public void onCreate() {
Log.v("debug", "PingService.onCreate");
HandlerThread thread = new HandlerThread("pingd",
android.os.Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
//handlers
serviceHandler = new ServiceHandler();
daemonHandler = new DaemonHandler(thread.getLooper());
//register broadcast receiver
IntentFilter filter = new IntentFilter();
filter.addAction(PingService.ACTION_ADD);
filter.addAction(PingService.ACTION_QUERY);
filter.setPriority(999);
registerReceiver(receiver, filter);
instance = this;
}

android services and activity lifecycle?

I am having problem with my android IntentService. When I first open the application, the service gets started by intent from the profile activity and data is fetched from this service. If I switch to other activity and then back service is still running and that is ok.
However if you press back, so that activity is finished and put in the background, the service is still working as the application is in background but If I get it back to foreground service stops. I do not know why. Bellow is my code, please help.
I have read activity life cycle couple of times and still do not get it why this is happening.
What is weird is that Service receive data one more time before it stops when MainActivity is brought back to running state. Service is not crashing.
Service
public class SomeService extends IntentService
{
public static final String extra = "someData";
public SomeService()
{
super(SomeService.class.getSimpleName());
}
#Override
protected void onHandleIntent(Intent intent)
{
Log.e("SomeService", "starting service");
while (true)
{
SomeData data = Api.getNewSocketData();
//Broadcast data when received to update the view
Intent broadcastData = new Intent();
broadcastData.setAction(dataBroadcastReceiver.ACTION_DATA_RECEIVED);
broadcastData.addCategory(Intent.CATEGORY_DEFAULT);
broadcastData.putExtra(extra, " ");
sendBroadcast(broadcastData);
Log.e("SomeService", "received from socket");
}
}
}
Receiver
public class dataBroadcastReceiver extends BroadcastReceiver
{
public final static String ACTION_DATA_RECEIVED = "net.bitstamp.intent.action.ACTION_SOMEDATA_RECEIVED";
#Override
public void onReceive(Context context, Intent intent)
{
Log.e("receiver", "data received");
}
}
Main Activity
#Override
public void onPause()
{
super.onPause();
unregisterReceiver(dataBroadcastReceiver);
}
#Override
public void onResume()
{
super.onResume();
IntentFilter intentFilter = new IntentFilter(dataBroadcastReceiver.ACTION_DATA_RECEIVED);
intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
dataBroadcastReceiver = new dataBroadcastReceiver();
registerReceiver(dataBroadcastReceiver, intentFilter);
Intent someService = new Intent(this, SomeService.class);
startService(someService);
}
I really need help on this. Thanks
You don't want to the up the IntentService in an infinite loop. It will block all other incoming requests. From the documentation:
All requests are handled on a single worker thread -- they may take as long as necessary (and will not block the application's main loop), but only one request will be processed at a time.
Your Service is likely still happily running along, it just isn't processing your new request because your old one is still being handled in the infinite loop.

refreshing and reloading an Activity from a Service without exiting the Activity, Android appwidget

Good day, I have an activity which i navigate to from an icon on an appwidget using pending Intents. Everything is being done in a service class. Now, the activity has a refresh button which when pressed, it sends an intent that calls the onStart() method on the service to update itself and perform some web operations. How do i go about reflecting the changes that could have occurred from the service in the activity without temporarily existing the activity.
Service to Activity:
if(intent.getExtras()!= null){
appWidgetId = intent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
//if i get this action from my detailedinfo class add a boolean to it
if(intent.getAction() == refresh_action){
// boolean variable to hold condition
my_action = true;
}
Intent forecast = new Intent(this,detailedInfo.class );
forecast.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
forecast.putExtra("cityname", city);
PendingIntent forecastIntent = PendingIntent.getActivity(this, 0, forecast, 0);
/*onclick to go to detailedInfo class*/
remoteView.setOnClickPendingIntent(R.id.city_image_id, forecastIntent);
if(my_action == true){
//Log.d(TAG, "my_action is true, performing pending intent");
try {
forecastIntent.send(this, 0, forecast);
} catch (CanceledException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
And in the Activity class:
Intent service = new Intent(this, cityService.class);
service.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
service.setAction(refresh_action);
Uri data = Uri.withAppendedPath(Uri.parse(CityWidgetProvider.URI_SCHEME + "://widget/id/"), String.valueOf(appWidgetId));
service.setData(data);
startService(service);
I tried adding a setAction() method to the intent that calls the service and then use the same pendingIntent(even though i think is a long shot) but they seems to be ignored. Please how do i go about this and what could i have been doing wrong.? As usual any help is highly appreciated. Thank you.
I'm not 100% clear on what you're trying to do, but the easiest thing to do would be to register a BroadcastReceiver in your Activity onResume (remove it in onPause). When the service is done with whatever it needs to do, broadcast that info.
In the Activity
public static final String ACTION_STRING = "THE_BIG_ACTION";
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Do whatever you want here
Toast.makeText(getApplicationContext(), "received", Toast.LENGTH_SHORT);
}
};
#Override
protected void onResume() {
super.onResume();
registerReceiver(receiver, new IntentFilter(ACTION_STRING));
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
In the service, when you're done, just call...
sendBroadcast(new Intent(YourActivityClass.ACTION_STRING));
If you want to include some data, just put it in the intent like you would when starting an Activity.
If your Activity is off screen when the service completes, and the user goes back to it, you'll have missed the notification. That's a different issue to resolve.

Android Service stopping without being told?

I am having a weird situation where a Service that is created is stopping - sometimes. I have a entry Activity A that starts a service using bindService
// if we now have an IP address then bind ourselves to the MessageService
bindService(new Intent(this, MessagingService.class),
onMessageService,
BIND_AUTO_CREATE);
The MessageService handles kicking of Read and Send threads to handle message traffic with the app. It basically handles polling for new messages at 1 second intervals using a StatusTask and it's timer using timer.scheduleAtFixedRate.
Activity A then kicks off another Activity B that displays info to the user. For some reason that I yet to figure out, most of the time when I press the home button, the polling stops and the Service seems to have stopped. Reslecting my app from the Home recent apps list or via a notification I post when not visible brings the Activity to the foreground, but the Service seems to be gone. Making this harder to debug, about 10-20% of the time everything works great and the Message Polling service keeps plugging away.
Should I be using startService instead? The only direct relationship that the second Activity B has with the Service is that registers itself as an observer of the Read thread in order to be notified about timeouts on Reads. I am not calling stopService anywhere in my code.
public class Testservice extends Service {
private static final String TAG = Testservice.class.getSimpleName();
public Timer timer;
TimerTask scanTask;
final Handler handler = new Handler();
Timer t = new Timer();
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "Service creating");
_startService();
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "Service destroying");
t.cancel();
t = null;
}
public void yourfunction()
{
}
//this will invoke the function on everysecond basis so try it if it helpsa
public void _startService(){
scanTask = new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
yourfunction();
}
});
}};
t.schedule(scanTask, 1000L, 1000L);
}
if developing using eclipse ---> try this go to DDMS that will be in the Perspective Option in Menu bar ---> select Logcat and while you are running your application just try to repeat the sequence you just mentioned above and on pressing home button just look at what is the error if at all coming during that instance and post the error so that the specific reason could be understood
Regards,
Mistry Hardik
Starting a service with bbindService makes the service lifecycle tied to the bound activities. Once your activity unbinds from the service, the service dies.
a simple service demo class
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class ServicesDemo extends Activity implements OnClickListener {
private static final String TAG = "AlertService";
Button buttonStart, buttonStop;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.servicedemo);
buttonStart = (Button) findViewById(R.id.btnStart);
buttonStop = (Button) findViewById(R.id.btnStop);
buttonStart.setOnClickListener(this);
buttonStop.setOnClickListener(this);
}
public void onClick(View src) {
switch (src.getId()) {
case R.id.btnStart:
Log.d(TAG, "onClick: starting srvice");
startService(new Intent(this, Testservice.class));
break;
case R.id.btnStop:
Log.d(TAG, "onClick: stopping srvice");
stopService(new Intent(this, Testservice.class));
break;
}
}
}

Categories

Resources