0

I have a problem with starting the service from a fragment.The service is started but it isn't foregrounded and I have no idea why the isCancelled variable is set true (so the doInBackground task is not processed).

When I'm starting it from a FragmentActivity it works: startService(new Intent(this, Recorder.class));. But when I trying to start it from a Fragment getActivity().startService(new Intent(getActivity(), Recorder.class)); it isn't work as expected (as I've described above).

Recorder.class:

public class Recorder extends Service {

boolean isCancelled = false;


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


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

    Log.v("service","started");
    Intent intent1 = new Intent(this, MainActivity.class);
    intent1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    PendingIntent pendIntent = PendingIntent.getActivity(this, 0, intent1, 0);

    Notification noti = new NotificationCompat.Builder(this)
            .setContentTitle("Recorder")
            .setContentText("running")
            .setSmallIcon(R.drawable.ic_launcher)
            .setContentIntent(pendIntent)
            .setPriority(Notification.PRIORITY_MIN)
            .build();

    startForeground(12345, noti);


    new RecordTask().execute("http://path");

    return START_STICKY;
}

@Override
public void onDestroy() {
    super.onDestroy();

   isCancelled = true;
}

@Override
public void onCreate() {
    super.onCreate();
}


private class RecordTask extends AsyncTask<String, Void, Boolean> {
    protected Boolean doInBackground(String... StringUrls) {

     // do something
                Log.v("isCancelled", String.valueOf(isCancelled));  
                   // <-- why isCancelled = true?
                if (isCancelled) break;  

            }


        } catch (IOException e) {
            System.err.println("Caught IOException: " + e.getMessage());
        }

       return true;
    }

    protected void onProgressUpdate(Integer... progress) {

    }

    protected void onPostExecute(Boolean result) {

    }
  }

}

AddNewRecordFragment:

public class AddNewRecordFragment extends Fragment implements View.OnClickListener {

//   @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    setRetainInstance(true);
    // Inflate the layout for this fragment
    View v = inflater.inflate(R.layout.addnewrecordfragment, container, false);

    Button b = (Button) v.findViewById(R.id.button);
    Button b2 = (Button) v.findViewById(R.id.button2);
    b.setOnClickListener(this);
    b2.setOnClickListener(this);
    return v;


}


@Override
public void onClick(View view) {
    switch (view.getId()) {
        case R.id.button:
            Log.v("start ", "clicked");
            getActivity().startService(new Intent(getActivity(), Recorder.class));

        case R.id.button2:

            getActivity().stopService(new Intent(getActivity(), Recorder.class));

            break;
    }
}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    Log.v("fragment", "onAttach");
}

@Override
public void onDetach() {
    super.onDetach();

    Log.v("fragment", "onDetach");
}

@Override
public void onDestroy() {
    super.onDestroy();

    Log.v("fragment", "onDestroy");
  }
}
XorOrNor
  • 8,868
  • 12
  • 48
  • 81
  • where do you start it in your fragment class ? You must make sure that the activity is Created and the fragment properly attached before using GetActivity(). Or else it won't work ! – An-droid Aug 21 '13 at 12:34

1 Answers1

1

Your issue is not related to starting the service from the fragment. If the only time you're setting isCancelled to true is in onDestroy then the service is starting as you inteded it's just also getting killed before your AsyncTask finishes. Have a look at this post. Services can be killed in certain instances. The question is why is onDestroy being called. If you're running this service on it's own process it's possible the service will be killed since all you're doing is setting up an AsyncTask. If this is run on the same process as the hosting activity it's not entirely clear why onDestroy is being called (usually because the system needs the memory but I can't tell if that's true in this case).

Community
  • 1
  • 1
Rarw
  • 7,645
  • 3
  • 28
  • 46
  • The issue is related to starting the service from the fragment because when I starting it from the FragmentActivity (host Activity) it works. – XorOrNor Aug 21 '13 at 12:29
  • But your service is starting, it's just getting killed. Is your fragment still active when this occurs? I suggest putting Log tags in some of the lifecycle methods to see when onDestroy is getting called in relationship to the fragment and activity lifecycle. I can't tell why onDestroy is getting called from what is posted above. – Rarw Aug 21 '13 at 12:37
  • I've added `AddNewRecordFragment` from where I'm starting the service. – XorOrNor Aug 21 '13 at 14:34
  • 2
    How about you break at the end of case1 as well as at the end of case2. Any chance the lack of the break is causing case1 to start and then immediatly stop the service (cause that's case2) – Rarw Aug 21 '13 at 15:23