I am creating an app where there is a vocabulary list, when the user click on an item it should say the word using text-to-speech.
I figured it out how to initialize it and call the method from MainActivity, but It doesn't seem to work in any other class.
I'm new at android development, and new to coding, so if there are useless lines or not properly written you can point it to me, so I can remove/fix.
Thanks in advance!
public class MainActivity extends ActionBarActivity
implements NavigationDrawerFragment.NavigationDrawerCallbacks, TextToSpeech.OnInitListener/*, TextToSpeech.OnUtteranceCompletedListener*/{ //The 2nd and 3rd implements are part of a test
//private Speaker speaker;
TextToSpeech tts;
public boolean ready = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); // this is the original one
tts = new TextToSpeech(this, this);
//tts.setLanguage(Locale.US);
//these methods below are for TTS
@Override
public void onInit(int status) { //for TTS
if (status == TextToSpeech.SUCCESS) {
// Change this to match your
// locale
tts.setLanguage(Locale.US);
ready = true;
} else {
ready = false;
}
}
@Override
protected void onDestroy() { //for TTS
super.onDestroy();
}
public void textToSpeech(String text){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ttsGreater21(text);
} else {
ttsUnder20(text);
}
}
@SuppressWarnings("deprecation")
private void ttsUnder20(String text) {
HashMap<String, String> map = new HashMap<>();
map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "MessageId");
tts.speak(text, TextToSpeech.QUEUE_FLUSH, map);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void ttsGreater21(String text) {
String utteranceId=this.hashCode() + "";
tts.speak(text, TextToSpeech.QUEUE_FLUSH, null, utteranceId);
//tts.speak(text, TextToSpeech.QUEUE_FLUSH, null, null);
}
public void ttsExample(View y) {
Button myButton = (Button) y;
textToSpeech("Random joke");
}
}
This is the method I use to call it in another class, I'm sure the problem is here, since I have no idea how to get this working, I've tried various different ways.
MainActivity mainActivity = new MainActivity();
mainActivity.textToSpeech(clickedVocab); //<--here
This is the full class where the list is (and the 2 lines above too):
public class VocabularyFragment extends Fragment implements View.OnClickListener {
//initialize vocab list
private ArrayList<String> vocabsList;
private ArrayAdapter<String> itemsAdapter;
private ListView vocabListView;
private String clickedVocab;
private View rootview;
private Speaker speaker;
private final int CHECK_CODE = 0x1;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootview = inflater.inflate(R.layout.fragment_vocab_list,container, false); //this works!
initialVocabList(rootview);
Button b = (Button) rootview.findViewById(R.id.BtnAddVocab);
b.setOnClickListener(this);
return rootview;
}
void initialVocabList(View view) {
// ADD HERE
vocabListView = (ListView)view.findViewById(R.id.vocabList);
//vocabsList = new ArrayList<String>();
//retrieve from SharedPreferences
TinyDB tinydb = new TinyDB(getActivity());
vocabsList = tinydb.getListString("vocabs");
//itemsAdapter = new ArrayAdapter<String>(this, R.layout.vocab_notes_item, items);
itemsAdapter = new ArrayAdapter<String>(getActivity(), R.layout.vocab_notes_item, vocabsList);
vocabListView.setAdapter(itemsAdapter);
// Setup remove listener method call
setupListViewListener();
// Setup Onclick method call
setOnClickListener();
}
private void setupListViewListener() {
vocabListView.setOnItemLongClickListener(
new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> adapter,
View item, int pos, long id) {
// Remove the item within array at position
/* createDelVocDialog();
if (confirmDelete){ //if boolean is true
items.remove(pos);
}*/
noteDeletedToast(vocabsList.get(pos));
vocabsList.remove(pos);
// Refresh the adapter
itemsAdapter.notifyDataSetChanged();
// Return true consumes the long click event (marks it handled)
return true;
}
});
}
private void setOnClickListener() {
vocabListView.setOnItemClickListener(
new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapter,
View view, int pos, long id) {
//System.out.println("entrei"); //anderson's test "dividir para conquistar"
Context context = view.getContext();
clickedVocab = vocabsList.get(pos);
MainActivity mainActivity = new MainActivity();
mainActivity.textToSpeech(clickedVocab); //<-- HERE!
Toast.makeText(context, "Item: " + clickedVocab, Toast.LENGTH_SHORT).show();
}
});
}
private void noteDeletedToast (String note) {
Toast.makeText(getActivity(), "Vocab note deleted: " + note , Toast.LENGTH_SHORT).show();
}
private void onAddVocab(View v) {
EditText vocabTextBox = (EditText) v.findViewById(R.id.edTextVocab);
if (vocabTextBox.getText().toString().equals("")) { //Check if the EditText is not empty
Toast.makeText(getActivity(), "You forgot to write in the box!", Toast.LENGTH_SHORT).show();
return;
} else {
String itemText = vocabTextBox.getText().toString();
itemsAdapter.add(itemText.trim()); //This also performs "trim" on text
vocabTextBox.setText("");
Toast.makeText(getActivity(), "Note added", Toast.LENGTH_SHORT).show();
//save to SharedPreferences
TinyDB tinydb = new TinyDB(getActivity());
tinydb.putListString("vocabs", vocabsList);
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.BtnAddVocab:
onAddVocab(rootview);
break;
}
}
}
Finally, this is the error message:
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.speech.tts.TextToSpeech.speak(java.lang.CharSequence, int, android.os.Bundle, java.lang.String)' on a null object reference
Any help is appreciated =)