I have two problems regarding Android Services.
First, I would like to know which is less computationally expensive? Threads or Services?
Secondly, In my main android application I have tried to trigger 2 services:
Intent intent = new Intent("android.intent.action.MAIN");
intent.setComponent(ComponentName
.unflattenFromString("com.mrlite.service1"));
intent.addCategory("android.intent.category.LAUNCHER");
startService(intent);
intent.setComponent(ComponentName
.unflattenFromString("com.mrlite.service2"));
intent.addCategory("android.intent.category.LAUNCHER");
startService(intent);
Service1:
package com.mrlite.service1;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class Service1Activity extends Service {
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
//Intent intent = new Intent("android.intent.action.MAIN");
//String value = getIntent().getExtras().getString("1")
Log.e(getClass().getSimpleName(), "Service 1 Started");
}
#Override
public void onDestroy()
{
super.onDestroy();
Log.e(getClass().getSimpleName(), "Service 1 Destroyed");
}
}
Service 2:
package com.mrlite.service2;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class Service2Activity extends Service {
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
// Intent intent = new Intent("android.intent.action.MAIN");
// String value = getIntent().getExtras().getString("1")
Log.e("Service 2", "Service 2 Started");
}
#Override
public void onDestroy() {
super.onDestroy();
Log.e("Service 2", "Service 2 Destroyed");
}
}
Whenever I try to execute this code, only service 1 is called. Service 2 is never called.
How to trigger 2 services simultaneously?
Is there a reason why you are starting your services that way? Why not do it this way:
Intent intent = new Intent(this, Service1Activity.class);
startService(intent);
intent = new Intent(this, Service2Activity.class);
startService(intent);
The reason it probably doesn't work the way you're doing it is because android.intent.action.MAIN can only be assigned to one class.
Related
I am working on an android application where an action is triggered after specific interval of time again and again when there is an Intent.FLAG_ACTIVITY_NEW_TASK Broadcast message received.
I have the following code in UpdateService.java:
package com.missnoob.screentimeout;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class UpdateService extends Service {
#Override
public void onCreate() {
super.onCreate();
// REGISTER RECEIVER THAT HANDLES SCREEN ON AND SCREEN OFF LOGIC
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new ScreenReceiver();
registerReceiver(mReceiver, filter);
}
#Override
public void onStart(Intent intent, int startId) {
boolean screenOn = intent.getBooleanExtra("screen_state", false);
if (!screenOn) {
Log.v("ScreenTimeOut","Broadcast Received");
Toast.makeText(getApplicationContext(), "Broadcast Received", Toast.LENGTH_LONG).show();
//This part is not working
Intent i = new Intent(this, Notification.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//This part is not working
}
else
{
// YOUR CODE
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
And the following code in Notification.java:
package com.missnoob.screentimeout;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import com.shadow.screentimeout.R;
public class Notification extends Activity {
/** Called when the activity is first created. */
Timer timer;
Toast toast;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timer = new Timer();
toast = Toast.makeText(getApplicationContext(), "15 seconds after",Toast.LENGTH_SHORT);
timer.scheduleAtFixedRate(new TimerTask()
{
#Override
public void run() {
toast.show();
Log.v("ScreenTimeOut","Toast showed");
}
}, 0, 5000);
}
}
In UpdateService.java
Intent i = new Intent(this, Notification.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
never gets triggered.
You are missing startActivity(i)
Intent i = new Intent(this, Notification.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
Also you cannot have
toast.show();
in timer as it runs on a different thread and you can update ui only on the ui thread.
Instead use a Handler. You can find an example #
Android Thread for a timer
You have not called startActivity(i).
See Start Another Activity (android developer website).
You are didn't call startActivity(i), thats why your activity is never caled, all you have to do is like this :
Intent i = new Intent(this, Notification.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
After I have bound a service by calling:
bindService(new Intent(IBumpAPI.class.getName()), connection, Context.BIND_AUTO_CREATE);
I need for debugging purposes to make the onServiceDisconnected() get called.
I am aware that the Android system calls this when the connection to the service is unexpectedly lost, such as when the service has crashed or has been killed and that this is not called when the client unbinds.
So my question is how to force the onServiceDisconnected() get called whenever I want so I can complete a test?
You need to start you service then bind with Context.BIND_NOT_FOREGROUND flag and then stop it. This will cause onServiceDisconnected to be called. Here is code (assuming that you have TestService service defined) of MainActivity with two buttons which are linked to call doBind and doUnbind methods:
package com.example.servicetest;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.Menu;
import android.view.View;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
private ServiceConnection connection = new ServiceConnection() {
#Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG, "Service disconnected: " + name);
}
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "Service connected: " + name);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public void doBind(View v) {
Intent i = new Intent(this, TestService.class);
startService(i);
bindService(i, connection, Context.BIND_NOT_FOREGROUND);
}
public void doUnbind(View v) {
Intent i = new Intent(this, TestService.class);
stopService(i);
}
}
This code provides following logs when you click on buttons:
11-27 09:21:57.326: D/MainActivity(10724): Service connected: ComponentInfo{com.example.servicetest/com.example.servicetest.TestService}
11-27 09:21:58.099: D/MainActivity(10724): Service disconnected: ComponentInfo{com.example.servicetest/com.example.servicetest.TestService}
You might just unbind your service
public void openService {
mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = IService.Stub.asInterface(service);
}
#Override
public void onServiceDisconnected(ComponentName cn) {
mService = null;
}
};
bindService(service, mConnection, Context.BIND_AUTO_CREATE);
}
}
public void closeService() {
unbindService(mConnection);
stopService(new Intent(this, Service.class));
}
How To start new service in Thread...
Thread is running continuously but the startservice() method in run() is not gets started...
Please Help Me.
The code is as follows.....
package com.example.demo;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
public class Act extends Service {
/** Called when the activity is first created. */
#Override
public void onCreate() {
super.onCreate();
Toast.makeText(Act.this,"In On Create",Toast.LENGTH_SHORT).show();
Intent i=new Intent(getApplicationContext(),HelloService.class);
startService(i);
Toast.makeText(Act.this,"In End Create",Toast.LENGTH_SHORT).show();
updateTimeTask.start();
}
private Thread updateTimeTask = new Thread() {
public void run() {
Intent i=new Intent(getApplicationContext(),HelloService.class);
startService(i); //This Service not gets started
}
};
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
You must have a Pending Intent for this:
// start something with Intent
Intent widgetUpdate = new Intent(SomeClass.this,
SomeService.class);
widgetUpdate.putExtra("Something", something);
// make this pending intent unique
widgetUpdate.setData(Uri.withAppendedPath(
Uri.parse(mUriSchemaId + "://widget/id/"),
String.valueOf(appWidgetId)));
PendingIntent newPending = PendingIntent.getService(
getApplicationContext(), 0, widgetUpdate,
PendingIntent.FLAG_UPDATE_CURRENT);
remoteview.setOnClickPendingIntent(R.id.someview,
newPending);
I am making a media player ,who can run in background. i have to send a string uri in this service.
but i cant send the uri value from my activity through bundle.Services class doesnot support getIntent() and show error.
how can i send uri in service through activity.
please help
package com.abc.activity;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class MyService extends Service {
private static final String TAG = "MyService";
MediaPlayer player;
String uri,url;
Bundle b;
AudioPlayer2 ap;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Log.d(TAG, "onCreate");
Uri path=Uri.parse("/mnt/sdcard/download/abc.mp3");
player = MediaPlayer.create(this,path );
player.setLooping(false); // Set looping
}
#Override
public void onDestroy() {
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
player.stop();
}
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
Log.d(TAG, "onStart");
//Bundle extras = getIntent().getExtras();
player.start();
}
public void getValue(String uri)
{
url=uri;
}
}
This is working with static url which i use in this example. please suggest what can i fetch uri's value from my activity class.Bundle is not working in this class
You should use IntentService http://developer.android.com/reference/android/app/IntentService.html.
Implement onHandleIntent(Intent intent) which will be called each time you start service with the startService(intent). You can pass your data to service through this intent.
If you are trying to send a string or String-array from one Activity to another this can be done in the Intent.
In ClassA:
Intent intent = new Intent(this, ClassB);
tring[] myStrings = new String[] {"test", "test2"};
intent.putExtra("strings", myStrings);
startActivity(intent);
In ClassB:
public void onCreate() {
Intent intent = getIntent();
String[] myStrings = intent.getStringArrayExtra("strings");
}
I want to know if it is possible to call an activity through background service in android like :
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
public class background extends Service{
private int timer1;
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
SharedPreferences preferences = getSharedPreferences("SaveTime", MODE_PRIVATE);
timer1 = preferences.getInt("time", 0);
startservice();
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
private void startservice() {
Handler handler = new Handler();
handler.postDelayed(new Runnable(){
public void run() {
mediaPlayerPlay.sendEmptyMessage(0);
}
}, timer1*60*1000);
}
private Handler mediaPlayerPlay = new Handler(){
#Override
public void handleMessage(Message msg) {
try
{
getApplication();
MediaPlayer mp = new MediaPlayer();
mp = MediaPlayer.create(background.this, R.raw.alarm);
mp.start();
}
catch(Exception e)
{
e.printStackTrace();
}
super.handleMessage(msg);
}
};
/*
* (non-Javadoc)
*
* #see android.app.Service#onDestroy()
*/
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
}
i want to call my activity......
You can call an Activity while onStart() of your service.....
Snippet might be as follows:
#Override
public void onStart(Intent intent, int startId) {
...
Log.i("Service", "onStart() is called");
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
callIntent.setClass(<Set your package name and class name here>);
startActivity(callIntent);
...
}
I believe launching user-interactive Activity from a non-interactive Service goes against the design of Android, in that it would pull out control from under the user.
Notifications are the mechanism intended to get user's attention from a background app, and give them an opportunity to launch the interactive Activity.