6

I am currently working on an android project and I am trying to start a service and when the service has started running some code to initialise some stuff.

Below is the code I am using for the service.

Context context;
    PowerManager.WakeLock wakeLock;

    public PowerDetectionService(Context context)
    {
        this.context = context;
    }

    public PowerDetectionService()
    {}

    public void onCreate()
    {
        super.onCreate();
        PowerManager pm = (PowerManager)getApplication().getApplicationContext().getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "ScreenStay");
    }

    public void onStart(Intent intent, int startId)
    {
        super.onStart(intent, startId);
        PowerManager pm = (PowerManager)getApplication().getApplicationContext().getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "ScreenStay");
    }

    @Override
    public IBinder onBind(Intent intent) {

        return null;
    }

    public void receivedPowerConnected()
    {
        try
        {
            Toast.makeText(context, "Power connected", Toast.LENGTH_LONG).show();
            wakeLock.acquire();
        }
        catch (Exception ex)
        {
            Toast.makeText(context, ex.toString(), Toast.LENGTH_LONG).show();
        }
    }

    public void receivedPowerDisconnected()
    {
        try
        {
            Toast.makeText(context, "Power disconnected", Toast.LENGTH_LONG).show();
            wakeLock.release();
        }
        catch (Exception ex)
        {
            Toast.makeText(context, ex.toString(), Toast.LENGTH_LONG).show();
        }
    }

The wake lock is always null as that bit of code never gets executed in the oncreate or onstart. I've tried putting it in the bind function but still no joy.

When I go into the android settings I can see that my app has the service running but I need that code to be initialised before anything would work.

Thanks for any help you can provide.

UPDATE I've discovered that the functions are being called thanks to the previous comment. For some reason the debugger doesn't get fired.

Below is the code that shows how to create the server as requested.

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    startService(this);
}

public void onResume()
{
    super.onResume();
    startService(this);
}

private void startService(Context context)
{
    Intent service = new Intent(context, PowerDetectionService.class);
    context.startService(service);
}

UPDATE 2 As requested below is all the code that starts the service and performs the wake lock.

Below is the main activity that starts the service

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        StartPowerService(this);
        //getActionBar().setDisplayHomeAsUpEnabled(true);
    }

    public void onResume()
    {
        super.onResume();
        StartPowerService(this);
    }

    private void StartPowerService(Context context)
    {
        Intent service = new Intent(context, PowerDetectionService.class);
        startService(service);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            //case android.R.id.home:
            //    NavUtils.navigateUpFromSameTask(this);
            //    return true;
        }
        return super.onOptionsItemSelected(item);
    }

}

Below is the class for the service

public class PowerDetectionService extends Service {

    Context context;
    PowerManager.WakeLock wakeLock;

    public PowerDetectionService(Context context)
    {
        this.context = context;
    }

    public PowerDetectionService()
    {}

    public void onCreate()
    {
        super.onCreate();
        Log.d("SERVICE", "ON CREATE CALLED");
        PowerManager pm = (PowerManager)getApplication().getApplicationContext().getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "ScreenStay");
    }

    public int OnStartCommand(Intent intent, int flags, int startId)
    {
        Log.d("SERVICE", "ONSTARTCOMMAND Called");
        PowerManager pm = (PowerManager)getApplication().getApplicationContext().getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "ScreenStay");
        return START_STICKY;
    }

    public void onStart(Intent intent, int startId)
    {
        super.onStart(intent, startId);
        Log.d("SERVICE", "ON START CALLED");
        PowerManager pm = (PowerManager)getApplication().getApplicationContext().getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "ScreenStay");
    }

    @Override
    public IBinder onBind(Intent intent) {

        return null;
    }

    public void receivedPowerConnected()
    {
        try
        {
            Toast.makeText(context, "Power connected", Toast.LENGTH_LONG).show();
            wakeLock.acquire();
        }
        catch (Exception ex)
        {
            Toast.makeText(context, ex.toString(), Toast.LENGTH_LONG).show();
        }
    }

    public void receivedPowerDisconnected()
    {
        try
        {
            Toast.makeText(context, "Power disconnected", Toast.LENGTH_LONG).show();
            wakeLock.release();
        }
        catch (Exception ex)
        {
            Toast.makeText(context, ex.toString(), Toast.LENGTH_LONG).show();
        }
    }
}

And below is the mainfest file.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.BoardiesITSolutions.ScreeenStay"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name="PowerDetectionService"
            android:process=":ScreenStay"
            android:icon="@drawable/ic_launcher"
            android:label="Screen Stay">
        </service>
        <receiver android:name="BroadcastReceiveDetection">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
                <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

Hope this helps.

Boardy
  • 35,417
  • 104
  • 256
  • 447

3 Answers3

9

You are starting service in different process.

    <service android:name="PowerDetectionService"
        android:process=":ScreenStay"
        android:icon="@drawable/ic_launcher"
        android:label="Screen Stay">

The debugger is attached to your main process. When the new one starts, it has no debugger attached, so it will ignore your breakpoints. If you want to debug remote process, you can do it via Eclipse in DDMS perspective. Under devices, you can see its processes. Then you can select one and press debug selected process (green bug icon). This is also useful when you only want to start debugging your app at some point.

As for debugging onCreate(), you have to attach debugger after the process started, but before onCreate() is called. You can for example put some Thread.sleep() in the beginning of onCreate() for few seconds so you can attach debugger.

ferini
  • 1,908
  • 14
  • 17
3

Which class are you extending? Service?

The method onStart() is only used for old Android versions (<2.0). For more recent versions you should use onStartCommand() as bellow:

@Override
public int onStartCommand(Intent intent, int flags, int startId)

And you need to return START_STICKY from the method above if you want the service to keeps running after executing the code. If service is not kept alive the PowerManager.FULL_WAKE_LOCK will be released. Probably you can also get away making wakeLock static.

To start service use:

    Intent i=new Intent(this, PowerDetectionService.class);
    startService(i);

--EDITED--

As per the topic here: getApplication() vs. getApplicationContext() you may get different Context object when getting the context using getApplicationContext(). Try change the following line:

    PowerManager pm = (PowerManager)getApplication().getApplicationContext().getSystemService(Context.POWER_SERVICE);

by:

    PowerManager pm = (PowerManager)this.getSystemService(Context.POWER_SERVICE);

regrads.

Community
  • 1
  • 1
Luis
  • 11,978
  • 3
  • 27
  • 35
  • Thanks tried this but this doesn't get executed, I've put a Log.d but nothing is output only the onCreate is called. – Boardy Oct 26 '12 at 22:40
  • which class are you extending? – Luis Oct 26 '12 at 22:53
  • I'm using ``extends Service`` – Boardy Oct 26 '12 at 23:00
  • How do you start the service? – Luis Oct 26 '12 at 23:02
  • I´ve added to my answer how service could be started. – Luis Oct 26 '12 at 23:05
  • That's what I'm doing, and the service is started but the wake lock is always null – Boardy Oct 26 '12 at 23:11
  • Did you add `android.permission.WAKE_LOCK` to the AndroidManifest.xml? – Luis Oct 26 '12 at 23:13
  • yea I did at the top just before the tag – Boardy Oct 26 '12 at 23:18
  • If you were doing all I said above it should be working. I'll stop guessing, you need to post your code were you start the service, your AndroidManifest and the full service code. – Luis Oct 26 '12 at 23:30
  • I've edited my answer with additional information. Let me know if it still not solves the issue, and I'll further investigate. – Luis Oct 27 '12 at 14:00
  • unfortunately still no luck, the log.d for the onstartcommand never gets printed in the logcat – Boardy Oct 27 '12 at 15:15
  • I've noticed now that you are running your service in a new process `android:process=":ScreenStay"`. Usually this is not required, and you can remove it. If you realy need it, you need to use `bindService()` to start and connect to the service. See doc here: http://developer.android.com/reference/android/app/Service.html – Luis Oct 27 '12 at 15:35
  • I've removed that as well still not calling the onstartcommand. I've tried uninstalling the app and re-installing just in case but no joy – Boardy Oct 27 '12 at 15:41
  • I've copied you code to a new project and run it in both SDK10 and SDK16. It runned perfectly (surprisingly it called `onStart()` instead of `OnStartCommand()`) and the wake lock is not null. The only difference to your code, is that I'm starting the service just once in `onResume()` – Luis Oct 27 '12 at 16:08
  • I suggest that you remove your service from `AndroidManifest.xml` and add it back again without `icon`. – Luis Oct 27 '12 at 16:10
  • thanks I tried that, and done a debug on it again and can now see that the oncreate is called and the wakelock variable is being set. But then when I plug in the power either on device or emulator, when I debug it, it says the wakelock is null. – Boardy Oct 27 '12 at 16:28
  • Thanks for your help I sussed out why wakelock was returning null after everything else was fixed. It was because I create the wakelock in one instance and then creating a new instance and trying to use wakelock again so it was null. I've made wakelock static and that appears to have fixed it – Boardy Oct 27 '12 at 16:41
0

Just a note :

onStart() method is deprecated, and you should use onStartCommand() instead (which will be called only if you start your service with Context.startService().

However, onCreate() should called if your service does run (but only once).

Amir Dora.
  • 2,831
  • 4
  • 40
  • 61
Orabîg
  • 11,718
  • 6
  • 38
  • 58