i am developing an android app, where i am registering my ContentObserver class to detect
the changes in VOLUME_RING.
My problem is, i am calling the ContentObserver class upon bootup of the phone, and i am able to get inside the Contentobserver class, but the onchange method is not getting called(i.e, the changes in volume is not getting detected).
Please check out the code below,
//BootupReceiver code.
public class Bootupreceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Intent startServiceIntent = new Intent(context,ServiceforVolumeChecker.class);
startServiceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startService(startServiceIntent);
}
}
//code to register the Content observer class.
public class ServiceforVolumeChecker extends Service
{
private VolumeChecker Volume;
#Override
public void onCreate()
{
super.onCreate();
Log.e("Service","Service");
Volume = new VolumeChecker(this,new Handler());
String vol_ring = android.provider.Settings.System.VOLUME_RING;
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion >= 17)
{
getApplicationContext().getContentResolver().registerContentObserver(android.provider.Settings.System.CONTENT_URI, true, Volume );
}
else
{
getApplicationContext().getContentResolver().registerContentObserver(android.provider.Settings.System.getUriFor(vol_ring), true, Volume);
}
stopService(new Intent(this, ServiceforVolumeChecker.class));
}
#Override
public IBinder onBind(Intent intent)
{
// TODO Auto-generated method stub
return null;
}
//code of ContentObserver class.
public class VolumeChecker extends ContentObserver
{
public VolumeChecker(Context c, Handler handler)
{
super(handler);
context=c;
this.handler = handler;
}
#Override
public boolean deliverSelfNotifications()
{
return super.deliverSelfNotifications();
}
#Override
public void onChange(boolean selfChange)
{
super.onChange(selfChange);
}
Please help! Thanks!
Put the service task in onStartCommand instead of using onCreate
Related
I want to have background music playing while the user is playing a game. The music starts when the user starts the application, pauses when they leave it, and it resumes when they go back to the application.
I tried using this method, I edited it a bit:
public class MainActivity extends Activity {
private boolean bounded;
private BackgroundSoundService backgroundSoundService;
ServiceConnection connection = new ServiceConnection() {
#Override
public void onServiceDisconnected( ComponentName name ) {
bounded = false;
backgroundSoundService = null;
}
#Override
public void onServiceConnected( ComponentName name, IBinder service ) {
bounded = true;
BackgroundSoundService.LocalBinder localBinder = (BackgroundSoundService.LocalBinder) service;
backgroundSoundService = localBinder.getServiceInstance();
}
};
#Override
public void onCreate( Bundle savedInstanceState ) {
super.onCreate(savedInstanceState);
// (code that's not necessary)
backgroundSoundService.start(); // this is where the error is thrown
}
#Override
public void onPause() {
super.onPause();
backgroundSoundService.pause();
}
#Override
public void onResume() {
super.onResume();
backgroundSoundService.resume();
}
#Override
public void onStop() {
super.onStop();
backgroundSoundService.pause();
}
#Override
public void onStart() {
super.onStart();
Intent intent = new Intent(this, BackgroundSoundService.class);
bindService(intent, connection, BIND_AUTO_CREATE);
backgroundSoundService.start();
}
#Override
public void onDestroy() {
super.onDestroy();
backgroundSoundService.destroy();
}
}
I use an activity to play, pause and resume background music. I'll leave out the unecessary methods/lines for this question here:
public class BackgroundSoundService extends Service {
private static final String TAG = null;
public IBinder binder = new LocalBinder();
public IBinder onBind( Intent arg0 ) {
return binder;
}
public IBinder onUnBind( Intent arg0 ) {
return null;
}
public class LocalBinder extends Binder {
public BackgroundSoundService getServiceInstance() {
return BackgroundSoundService.this;
}
}
}
However, when I run the application I get a NullPointerException in the MainActivity class (in the onCreate method, I commented it in the code).
The variable doesn't seem to be initialized yet, but I do need to start the music when the user opens the application.
I also tried removing the backgroundSoundService.start(); from the onCreate method, so the music would start when onStart is called. However, when I do that, I get the same error.
So, how can I initialize backgroundSoundService before it is used to call its methods?
first of all remove this backgroundSoundService.start() from onCreate and add it inside onServiceConnected() method
u need to check null before doing any backgroundSoundService related stuffs like below
#Override
public void onPause() {
super.onPause();
if(backgroundSoundService != null){
backgroundSoundService.pause();
}
}
add this kind of null check in all appearance of backgroundSoundService
I'm trying to implement service in android to make an app locker.
I'm trying to check the which activity is running on the foreground and if it's locked, forwarding it to my Locker activity.
I've added the service in manifest too, but it isn't working at all.
Here's the code `
private static Timer timer = new Timer();
public Boolean userAuth = false;
private Context mContext;
public String pActivity = "";
public IBinder onBind(Intent arg0) {
return null;
}
public void onCreate() {
super.onCreate();
mContext = this;
startService();
}
private void startService() {
timer.scheduleAtFixedRate(new mainTask(), 0, 500);
}
private class mainTask extends TimerTask {
public void run() {
toastHandler.sendEmptyMessage(0);
}
}
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service Stopped ...", Toast.LENGTH_SHORT).show();
}
private final Handler toastHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
String activityOnTop;
ActivityManager manager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> tasks = manager.getRunningAppProcesses();
//Getting the foreground activity name
activityOnTop=tasks.get(0).processName;
//Checking it against the app I need to lock
if (activityOnTop.equalsIgnoreCase("com.droiddigger.techmanik")) {
Intent lockIntent = new Intent(mContext, Lockscreen.class);
lockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(lockIntent);
} else if(activityOnTop.equalsIgnoreCase("com.droiddigger.applocker")){
}else{
}
}
};
You must start that service. It can be done in an Activity or a BroadcastReceiver.
startService(new Intent(this, UpdaterServiceManager.class));
For example:
public class MyActivity extends Activity {
#Override
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startService(new Intent(this, YourService.class));
finish();
}
}
EDIT:
You are always retrieving the item 0 of the list called tasks. Looking at the SDK documentation, it is said that list order is not especified: https://developer.android.com/reference/android/app/ActivityManager.html#getRunningAppProcesses()
Returns a list of RunningAppProcessInfo records, or null if there are
no running processes (it will not return an empty list). This list
ordering is not specified.
You must get the current visible activity other way. I suggest an AccessibilityService
I have some programm, where I want to save the instance of service and use it in another activities. But service doesn't create.
Just see the code, please.
MainActivity.java:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MainService.get(this);
}
}
MainService.java:
public class MainService extends Service {
public static Object sWait = new Object();
public static MainService instance;
#Override
public IBinder onBind(Intent intent) {
return null;
}
public static MainService get(Context mContext) {
if (instance == null) {
Intent intent = new Intent(mContext, MainService.class);
mContext.startService(intent);
}
while (true) {
if (instance != null) {
Log.v("myLogs", "all is good!");
break;
}
synchronized (sWait) {
try {
sWait.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
return instance;
}
#Override
public void onCreate() {
Log.v("myLogs", "created!");
instance = this;
synchronized (sWait) {
sWait.notify();
}
}
}
When I don't use while in MainService.get(), service creates. I added this service to manifest file. I don't know where is there error. I need your help.
That's just not the way you should use Service in Android.
What you probably need is to use bindService() call from your Activity.
See more about bound service here http://developer.android.com/guide/components/bound-services.html
If you need the service to be the same instance each time you bind to it, call startService once when your application start.
Example code:
public class LocalBinder<T> extends Binder {
private WeakReference<T> mService;
public LocalBinder(T service) {
mService = new WeakReference<T>(service);
}
public T getService() {
return mService.get();
}
}
public class MyService extends Service {
private final LocalBinder<MyService> binder;
public MyService() {
binder = new LocalBinder<MyService>(this);
}
#Override
public IBinder onBind(Intent intent) {
return binder;
}
}
public class MyActivity extends Activity implements ServiceConnection {
#Override
protected void onStart() {
super.onStart();
bindService(new Intent(this, MyService.class), this, Context.BIND_AUTO_CREATE);
}
#Override
protected void onStop() {
super.onStop();
unbindService(this);
}
#SuppressWarnings("unchecked")
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
MyService serv = ((LocalBinder<MyService>) service).getService();
// serv is your service instance now
}
#Override
public void onServiceDisconnected(ComponentName name) {
}
}
To start your service use (call this from your activity!):
Intent serviceIntent = new Intent(this, MainService.class);
startService(serviceIntent);
see docs: https://developer.android.com/training/run-background-service/send-request.html
That is definitely not the way you are supposed to use services in android.
I would suggest you revisit the offical android docs.
To get a quick introduction visit this tutorial here.
I have the following code being executed, I'm running this through a debugger and audioPlayerConnection.service is always null. Why may this be?
The various log calls don't always seem to be executed either (I guess this may have to do with the service being already starte).
Intent intent = new Intent(this, AudioPlayer.class);
AudioPlayerConnection audioPlayerConnection = new AudioPlayerConnection();
startService(intent);
bindService(intent, audioPlayerConnection, Context.BIND_AUTO_CREATE);
AudioPlayerConnection
public class AudioPlayerConnection implements ServiceConnection {
public IBinder service;
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
this.service = service;
Log.d("hmm", "audio service connected!!!");
}
#Override
public void onServiceDisconnected(ComponentName name) {
}
}
AudioPlayer
public class AudioPlayer extends Service {
public ArrayList<MediaPlayer> audioResources = new ArrayList<MediaPlayer>();
public AudioPlayer() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
Log.d("hmm", "audio service binded!!!");
return new AudioPlayerBinder();
}
public class AudioPlayerBinder extends Binder {
public void stopAll()
{
int i = 0;
for (MediaPlayer mp : audioResources)
{
mp.stop();
mp.release();
audioResources.remove(i);
i++;
}
}
public void add(Integer resourceId, boolean loop)
{
MediaPlayer mp = MediaPlayer.create(null, resourceId);
if (loop)
{
mp.setLooping(true);
audioResources.add(mp);
}
mp.start();
}
}
}
You're declaring audioPlayerService in the local scope where you are calling bindService(). The call to bindService is asynchronous, and onServiceConnected() is not being called before you are (presumably) trying to use audioPlayerConnection as if the Service was already bound.
How to pass handler from an activity to service? I am trying to update the activity UI on the state of Bluetooth connection by using Handler as shown below from service class.
mHandler.obtainMessage(MenuActivity.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
In the activity, I implemented this:
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
if (true)
Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
switch(msg.arg1){
case BluetoothService.STATE_CONNECTED:
showToast("Connected to " + mConnectedDeviceName, Toast.LENGTH_SHORT);
break;
I tried to use a constructor to pass the handler from the activity to service like this:
public BluetoothService(Handler handler, BluetoothAdapter mBluetoothAdapter) {
mAdapter = mBluetoothAdapter;
mState = STATE_NONE;
mHandler = handler;
}
But there was an error which shows Unable to instantiate service and found that the service needs to have a public no-args constructor. But after removing the constructor, the handler did not get passed into the service.
How to solve this problem?
You have to bind to the service from activity and establish a ServiceConnection and then get the instance of service and set your handler.
Here is the activity and service class which i use for one of my media player application.....
public class MainActivity extends Activity
{
private CustomService mService = null;
private boolean mIsBound;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
startService(new Intent(this.getBaseContext(), CustomService.class));
doBindService();
}
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder)
{
mService = ((CustomService.LocalBinder)iBinder).getInstance();
mService.setHandler(yourHandler);
}
#Override
public void onServiceDisconnected(ComponentName componentName)
{
mService = null;
}
};
private void doBindService()
{
// Establish a connection with the service. We use an explicit
// class name because we want a specific service implementation that
// we know will be running in our own process (and thus won't be
// supporting component replacement by other applications).
bindService(new Intent(this,
CustomService.class), mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
private void doUnbindService()
{
if (mIsBound)
{
// Detach our existing connection.
unbindService(mConnection);
mIsBound = false;
}
}
#Override
protected void onDestroy()
{
super.onDestroy();
doUnbindService();
}
}
CustomService Code ....
public class CustomService extends Service
{
private final IBinder mIBinder = new LocalBinder();
private Handler mHandler = null;
#Override
public void onCreate()
{
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flag, int startId)
{
return START_STICKY;
}
#Override
public void onDestroy()
{
if(mHandler != null)
{
mHandler = null;
}
}
#Override
public IBinder onBind(Intent intent)
{
return mIBinder;
}
public class LocalBinder extends Binder
{
public CustomService getInstance()
{
return CustomService.this;
}
}
public void setHandler(Handler handler)
{
mHandler = handler;
}
}