How do I solve Could not find method in a parent or ancestor Context for android:onClick attribute?

问题: 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...

问题:

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:

How to solve error: Could not find method onClick(View) in a parent or ancestor Context for android:onClick

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;
    }
}

回答1:

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.

  • 发表于 2019-03-30 14:40
  • 阅读 ( 4591 )
  • 分类:sof

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除