0

Can we call IntentService class from a running Service class .

Intent myintentservice = new Intent(this, MyIntentService.class);
startService(myintentservice);

I using above lines of code in service class to start IntentService class. But then I get following error:-

Process: objectdistance.ankeshkjaisansaria.ram.sita.cameratag, PID: 21823


java.lang.NullPointerException: Attempt to invoke virtual method 

'java.lang.String android.content.Context.getPackageName()' on a null object reference


at android.content.ComponentName.<init>(ComponentName.java:77)


at android.content.Intent.<init>(Intent.java:4161)

**Edited:------------- **

1. Main Activity.Java

OnCreate():-

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

2. ServiceA.java

public class ServiceA extends Service {


    String TAG = "Log";
    private static HandlerThread sWorkerThread;
    private static Handler sWorkerQueue;
    private static DataProviderObserver sDataObserver;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        sWorkerThread = new HandlerThread("ContentObserver");
        sWorkerThread.start();
        sWorkerQueue = new Handler(sWorkerThread.getLooper());

        final ContentResolver r = this.getContentResolver();
        if (sDataObserver == null) {
            sDataObserver = new DataProviderObserver(getApplicationContext(), sWorkerQueue);
            Log.d("CP", " " + android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            r.registerContentObserver(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, true, sDataObserver);

        }
        else{Log.d("Error","Error Content Observer Service");}

        super.onCreate();
    }

    public void IntService(){

        Intent MyIntentService = new Intent(this, MyIntentService.class);
        startService(MyIntentService);

    }

    @Override
    public void onDestroy() {
        getContentResolver().unregisterContentObserver(sDataObserver);
        super.onDestroy();
    }


}

3. DataProviderObserver.Class

public class DataProviderObserver extends ContentObserver {

    Context context;

    DataProviderObserver(Context context ,Handler h) {
        super(h);
        this.context = context;

    }


    @Override
    public void onChange(boolean selfChange, Uri uri) {
        if (uri.toString().equals("content://media/external/images/media")){
            ServiceA  obj1 = new ServiceA();
            ob1.IntService();
        }
    }

    @Override
    public boolean deliverSelfNotifications() {
        return false;
    }



}

4. MyIntentService.java

public class MyIntentService extends IntentService {
Context ctx;

public MyIntentService() {
    super("test-service");
}

@Override
public void onCreate() {
    ctx = getBaseContext();
    super.onCreate();
}
@Override
public void onHandleIntent(Intent i){

         try {

        Uri uri;
        Cursor cursor;
        int column_index_id , column_index_data;
        uri = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        String order = MediaStore.MediaColumns.DATE_ADDED + " desc";
        String[] projection = {MediaStore.MediaColumns._ID , MediaStore.MediaColumns.DATA};
        cursor = **CONTEXT_REQUIRED**.getContentResolver().query(uri, projection, null, null, order);


        column_index_id = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID);
        column_index_data = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);

        cursor.close();


    }catch (Exception e){
        e.printStackTrace();
    }

 // My Task
 }

}
Ankesh kumar Jaisansaria
  • 1,563
  • 4
  • 26
  • 44
  • The `Context` provided by `this` is apparently `null` when you instantiate your `Intent`, but you've not provided enough information for us to be able to determine exactly why. – Mike M. May 07 '16 at 20:27
  • This is a trivial question but you need to post more code as said by Mike, your this is returning null. But why is it so? To determine that more code will be needed. Please post full code of the service and also the code for starting the running service. – varunkr May 08 '16 at 00:17
  • @MikeM. I think I was not clear enough in asking my question. Sorry for that. Now I have posted my code also. In sort Main Activity triggers a service class which registers a ContentObserver. That Content Observer onChange calls IntentService for heavy task. As I cannot call Intent Service directly from ContentObserver Class, I made an object and called it from ServiceA.class – Ankesh kumar Jaisansaria May 08 '16 at 05:34
  • @varunkr I think I was not clear enough in asking my question. Sorry for that. Now I have posted my code also. In sort Main Activity triggers a service class which registers a ContentObserver. That Content Observer onChange calls IntentService for heavy task. As I cannot call Intent Service directly from ContentObserver Class, I made an object and called it from ServiceA.class – Ankesh kumar Jaisansaria May 08 '16 at 05:34

1 Answers1

1

I have answered another question today which has exactly the same mistake.

ServiceA  obj1 = new ServiceA();
ob1.IntService();

You are trying to create a new object of a service which is a very very bad practice. You cannot simply create an object of service like this. All Services in Android must go through the Service lifecycle so that they have a valid context attached to them. In this case a valid context is not attached to the obj1 instance. So as a result the line

Intent MyIntentService = new Intent(this, MyIntentService.class);

causes a null pointer as 'this' is null. (Why? Because this refers to the context which has not yet been created as the service is not started using startService(intent))

Btw I don't understand why you are starting the intent service from within the service. you can simply do it from the DataProviderObserver class like this

Intent MyIntentService = new Intent(context, MyIntentService.class);
context.startService(MyIntentService);

since context is present in the class.

Community
  • 1
  • 1
varunkr
  • 5,364
  • 11
  • 50
  • 99
  • So how should I call IntentService after ContentObservers OnChange() has triggered. – Ankesh kumar Jaisansaria May 08 '16 at 05:43
  • @AnkeshkumarJaisansaria The way I wrote in the answer, have a look at the final 3 lines – varunkr May 08 '16 at 05:44
  • I mean should I create an Object of ServiceA class in ContentObserver Class or not ? – Ankesh kumar Jaisansaria May 08 '16 at 05:47
  • You should never ever create an object of a service, fragment or activity like that. It is a very bad practice. You will always run into errors. SImply do this Intent MyIntentService = new Intent(context, MyIntentService.class); context.startService(MyIntentService); I am not sure what is the problem with this? – varunkr May 08 '16 at 05:48
  • @AnkeshkumarJaisansaria Also in line sDataObserver = new DataProviderObserver(getApplicationContext(), sWorkerQueue); You should use Service context instead of application context – varunkr May 08 '16 at 05:49
  • @AnkeshkumarJaisansaria Nice, I also hope you understood the logic behind it !! And why should not use it in future. – varunkr May 08 '16 at 05:54
  • To use Service context, how do I get Service context? I see only getApplicatioContext() and getBaseContext() . – Ankesh kumar Jaisansaria May 08 '16 at 05:56
  • 1
    ServiceA.this gives context – varunkr May 08 '16 at 05:56
  • Hi... I have one more query in this code related to context. In myIntentService onHandle method I have content provider uri and I query that content provider to get images. This content provider has to pass a context. So what context should I pass. – Ankesh kumar Jaisansaria May 10 '16 at 08:35
  • Sorry, solved my above query by passing MyIntentService.this as context. Thanks – Ankesh kumar Jaisansaria May 10 '16 at 08:43