I'm trying to create a tuner app right now and it has two errors, both stemming from Handlers.
public class Pitch extends Fragment {
private static final String TAG = "Pitch";
private TextView tv_pitch;
private TextView tv_note;
View rootView;
Context mContext;
Tuner tn;
private Handler mHandler;
private final static double[] stringFreqs = {82.41, 110.0, 146.83, 196.00, 246.94, 329.63};
private static HashMap<Double, String> stringNames = new HashMap<>();
Tuner.PitchDetectedListener listener = new Tuner.PitchDetectedListener() {
@Override
public void onPitchDetected(double pitch, double amplitude) {
Log.d(TAG, "Pitch: " + pitch + " Amplitude: " + amplitude);
if (amplitude > 1000000.0) {
double doublePitch = pitch * 2;
double halfPitch = pitch / 2;
for (double freq : stringFreqs) {
if (pitch > freq - 3 && pitch < freq + 3) {
Log.d(TAG, stringNames.get(freq) + " with pitch of " + pitch);
display_color(pitch, freq);
return;
}
}
for (double freq : stringFreqs) {
if (doublePitch > freq - 3 && doublePitch < freq + 3) {
Log.d(TAG, stringNames.get(freq) + " with pitch of " + pitch);
display_color(doublePitch, freq);
return;
}
}
for (double freq : stringFreqs) {
if (halfPitch > freq - 3 && halfPitch < freq + 3) {
Log.d(TAG, stringNames.get(freq) + " with pitch of " + pitch);
display_color(halfPitch, freq);
return;
}
}
}
}
};
private void display_color(final double pitch, final double freq) {
mHandler.post(new Runnable() {
@Override
public void run() {
tv_note.setText(stringNames.get(freq));
tv_pitch.setText(Double.toString(pitch));
}
});
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.activity_tuner, container, false);
final BoxInsetLayout tuner = (BoxInsetLayout) rootView.findViewById(R.id.tuner_box);
final ImageView start = (ImageView) rootView.findViewById(R.id.tuner);
final ImageView stop = (ImageView) rootView.findViewById(R.id.tuner);
mContext = getActivity().getApplicationContext();
Typeface font = Typeface.createFromAsset(mContext.getAssets(), "fonts/Foglihten-068.otf");
tv_note.setTypeface(font);
tv_note.setText("-");
mHandler = new Handler(getMainLooper());
tv_note = (TextView) rootView.findViewById(R.id.tv_note);
int i = 0;
stringNames.put(stringFreqs[i++], "E");
stringNames.put(stringFreqs[i++], "A");
stringNames.put(stringFreqs[i++], "D");
stringNames.put(stringFreqs[i++], "G");
stringNames.put(stringFreqs[i++], "B");
stringNames.put(stringFreqs[i], "e");
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tn.run();
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tn.stop();
}
});
tv_pitch = (TextView) tuner.findViewById(R.id.tv_pitch);
tv_note = (TextView) tuner.findViewById(R.id.tv_note);
return rootView;
tn = new Tuner(listener);
}
public void onPause() {
tn.stop();
super.onPause();
}
}
My errors are in these lines:
mHandler.post(new Runnable() {
mHandler = new Handler(getMainLooper());
The first line results in cannot resolve method 'post(java.lang.Runnable)', and the second line results in cannot resolve method 'getMainLooper.'
Can anyone help figure out what's going wrong?
Check your imports. You accidentally imported java.util.logging.Handler
instead of android.os.Handler
.
Most of the time you create object where you need a handler on UI thread so you're safe to use this:
private final Handler mHandler = new Handler();
A more general approach will look like this (post to UI thread from other threads):
private final Handler mHandler = new Handler(Looper.getMainLooper());