Reputation: 101
I am trying to launch a foreground service and notification when the user clicks on a button. This button is called "startBtn". It is meant to show the number of steps that the user takes.
I have 3 files, StepsFragment.java, fragment_steps.xml and StepsService.java.
I encountered this error in Logcat when the user clicks on the button:
java.lang.IllegalStateException: Could not find method startService(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatButton with id 'startBtn'
I have tried these following solutions asked on StackOverflow:
Could not find method in a parent or ancestor Context for android:onClick attribute
This is my code in StepsFragment.java:
package sg.edu.singaporetech.teamproject;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class StepsFragment extends Fragment implements SensorEventListener, View.OnClickListener {
Button updateBtn;
ProgressBar progressBar;
TextView tv_steps;
TextView levelDisplay;
SensorManager sensorManager;
Sensor sensor;
boolean running = false;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_steps, container, false);
super.onCreate ( savedInstanceState );
updateBtn = view.findViewById(R.id.updateBtn);
progressBar = view.findViewById(R.id.progress_bar);
tv_steps = (TextView) view.findViewById(R.id.tv_steps);
levelDisplay = (TextView) view.findViewById(R.id.levelDisplay);
sensorManager = (SensorManager) getActivity().getSystemService ( Context.SENSOR_SERVICE);
updateBtn.setOnClickListener(this);
return view;
}
public void startService(View view) {
String input = tv_steps.getText().toString();
Intent serviceIntent = new Intent(getActivity(),StepsService.class);
serviceIntent.putExtra("inputExtra",input);
getActivity().startService(serviceIntent);
}
}
This is the button code in fragment_steps.xml:
<android.support.v7.widget.AppCompatButton
android:id="@+id/startBtn"
style="?android:attr/borderlessButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:background="@drawable/btn_orange"
android:text="@string/start_steps"
android:textColor="@color/white"
android:textSize="15dp"
android:onClick="startService"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/updateBtn" />
And lastly, this is the code in StepsService.java
package sg.edu.singaporetech.teamproject;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import static sg.edu.singaporetech.teamproject.StepsNotification.CHANNEL_ID;
public class StepsService extends Service {
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String input = intent.getStringExtra("inputExtra");
Intent notificationIntent = new Intent(this,StepsFragment.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,notificationIntent,0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Steps Tracker")
.setContentText("Steps tracked")
.setSmallIcon(R.drawable.exersize)
.setContentIntent(pendingIntent)
.build();
startForeground(1,notification);
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
Upvotes: 1
Views: 2741
Reputation: 12803
android:onClick="startService"
will not called in fragment. You should use OnClickListener
instead to handle this type of events.
Another approach is declare the startService
function in activity, then call the fragment method from the activity.
Kindly refer Android app crashing (fragment and xml onclick) to know more.
Upvotes: 3