2

I am trying to access a editText and a Button in a Service. I've seen this answer and this answer, and tried to merge and work out, but no gain. What am I missing here? I have seen other similar answers too and been trying to get it done from last 2 days but all in vain. Any other way of accomplishing it will also be welcome.

Here is the relevant code: MainActivity.java

btn_start.setOnClickListener(new Button.OnClickListener(){

            @Override
            public void onClick(View view) {
                startService(new Intent(getApplicationContext(), MyService.class));
            }
        });

MyService.java

        Context context = MyService.this;
        Activity activity = (Activity) context;
        Button stopButton = activity.findViewById(R.id.btn_stop);
        EditText editTextUsername = activity.findViewById(R.id.edit_name);

AndroidManifest.xml

        <service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true">
        </service>

But I get this error: LOGCAT

11-14 02:55:07.835 5906-5906/? E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.nwagh.myapplication, PID: 5906 java.lang.RuntimeException: Unable to start service com.example.nwagh.myapplication.MyService@32189af with Intent { cmp=com.example.nwagh.myapplication/.MyService }: java.lang.ClassCastException: com.example.nwagh.myapplication.MyService cannot be cast to android.app.Activity at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3060) at android.app.ActivityThread.access$2300(ActivityThread.java:153) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1473) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:5527) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629) Caused by: java.lang.ClassCastException: com.example.nwagh.myapplication.MyService cannot be cast to android.app.Activity at com.example.nwagh.myapplication.MyService.onStartCommand(MyService.java:68) at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3043) at android.app.ActivityThread.access$2300(ActivityThread.java:153)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1473)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:154)  at android.app.ActivityThread.main(ActivityThread.java:5527)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)  11-14 02:55:07.844 5906-5906/? E/MQSEventManagerDelegate: failed to get MQSService.

Here is the complete code if you need any more reference.

Nikhil Wagh
  • 1,376
  • 1
  • 24
  • 44
  • So what part of this : `Context context = MyService.this; Activity activity = (Activity) context;` doesn't make sense? You are casting `Activity` to a `context` object, which you just assigned as your `Service` instance? Also you are trying to access Activity/UI elements in a Service - this is bound to cause more issues. – Mark Nov 13 '17 at 21:51
  • So what should I do? I can't cast a service to a activity. – Nikhil Wagh Nov 13 '17 at 21:56
  • You should bind your service to your activity. Then inside service, create a method that takes your activity. This way you can use fields and methods of the activity inside the service – Francis Nduba Numbi Nov 13 '17 at 21:57
  • No they are different Object types, both extend from `Context`, but are not compatible, hence `ClassCastException` - read the docs for `Service` and `Activity` – Mark Nov 13 '17 at 21:57
  • But according to [this answer](https://stackoverflow.com/questions/30817775/does-anyone-know-how-to-get-edittext-value-in-service/30817894#30817894) he said it could be done. And it was accepted too. – Nikhil Wagh Nov 13 '17 at 21:59
  • what is the purpose of the Service? You should use a service to do long mid/long running background tasks. You can bind to a service (bound service) or use a started service, what you are trying to do here. However not too sure of your use case here. – Mark Nov 13 '17 at 21:59
  • I am getting values from the sensors and storing them in files, this task is done in the service. I thought it would be a good idea to stop the `MyService` when user clicks on `stopButton` – Nikhil Wagh Nov 13 '17 at 22:03
  • @MarkKeen nice to help from the comments. – trocchietto Nov 13 '17 at 22:07
  • @trocchietto not really sure what you mean? – Mark Nov 13 '17 at 22:21
  • that is nice you help the community even without writing an answer that would give you reputation points:) respect. In the end the maximum advantage we have replying in stackoverflow is that we learn a lot and become ourselves better devs:) and problem solvers – trocchietto Nov 13 '17 at 22:26
  • @trocchietto Oh right, well sometimes suggesting people have a look at the documentation is the best answer - and more comprehensive than any answer, especially as the OP seems misguided as to the purpose of a `Service` over an `Activity` – Mark Nov 13 '17 at 22:31
  • eh eh for sure we went trough the same troubles x years ago:) components, components – trocchietto Nov 13 '17 at 22:33

2 Answers2

4

You are barking up the wrong tree ;-) Your Service shouldn't know anything about your UI, nor should it want to muck around with it. If you want to change the UI from your Service then you need to delegate that task to the Activity. Activity is responsible for the UI. There are several well documented approaches you can use:

  • Activity binds to Service and Service executes a callback on the Activity
  • Service sends a broadcast Intent and Activity registers a listener that reacts to the Intent when it is broadcast
  • Use an Event Bus implementation
David Wasser
  • 93,459
  • 16
  • 209
  • 274
1

Services are NOT activities. Services have no UI related to them.

So:

1) you can't cast a service to an activity. 2) there is no UI for your to find in your service.

Why would a service need a button? services run in the background, with no user interaction.

I don't know what you are doing, but in Android it works like this:

1) activity launches a service (like your button press) 2) service carries out a task in the background 3) service reports back to the activity or terminates

Chris Merrick
  • 110
  • 1
  • 4
  • I want to stop the service when user clicks on the stop Button. How would I know when to call `stopSelf()`. – Nikhil Wagh Nov 13 '17 at 22:29
  • Although your answer is nice explains why I can't do what I was trying to do. – Nikhil Wagh Nov 13 '17 at 22:30
  • @NikhilWagh - Chris Merrick is right in what he has said, but you are starting to ask questions out of the scope of the original post, I reiterate, read the documentation for a `Service` - https://developer.android.com/guide/components/services.html (it is worth the read!) and the Java exception tells you why you can't do what you are attempting - the accepted answer you pointed to is simply wrong. – Mark Nov 13 '17 at 22:37
  • Shall we flag that answer then @MarkKeen – Nikhil Wagh Nov 13 '17 at 22:43