onUtteranceCompleted won't allow PhoneCallListener - java

For some reason I can't call a method that contains PhoneCallListener from onutteranceCompleted. There are no error messages, it just seems to stop executing the script. I've added some Logs and it gets to the "here" log in setUpPhone with PhoneCallListener. Without PhoneCallListener it will get to the final log "phone set up". Here is example code of how I have it implemented.
#Override
public void onInit(int status)
{
if(status == TextToSpeech.SUCCESS)
{
tts.setOnUtteranceCompletedListener(this);
int result = tts.setLanguage(Locale.US);
if(result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED)
{
//Language not supported
}
else
{
speakOut();
}
}
}
private void speakOut()
{
HashMap<String, String> myHashAlarm = new HashMap<String, String>();
myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_ALARM));
myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "Text to Speech");
tts.speak("blah blah", TextToSpeech.QUEUE_FLUSH, myHashAlarm);
}
#Override
public void onDestroy()
{
if(tts != null)
{
tts.stop();
tts.shutdown();
}
super.onDestroy();
}
public void onUtteranceCompleted(String utteranceId)
{
Log.i("TEST", utteranceId);
setUpPhone();
Log.i("TEST", "phone set up"); //this is never reached
}
private void setUpPhone()
{
Log.i("TEST", "here");
PhoneCallListener phoneListener = new PhoneCallListener(); //If I remove this line, the log "phone set up" displays.
}

I don't know why PhoneCallListener stops execution, however I solved this by putting "phoneListener = new PhoneCallListener();" in the onCreate method.

Related

Android AsyncTask keeps return opposite value

I got a problem with AsyncTask at Android Studio. What I am trying to do is before I create a new user, I am checking if the username and email exist in my database. Here is the part where I call the create AsyncTask:
new SignupAsyncTask(getBaseContext()).execute(userModel);
if(SignupAsyncTask.successCheck == false){
Toast.makeText(getBaseContext(), "Failed", Toast.LENGTH_SHORT).show();
} else if(SignupAsyncTask.successCheck == true){
Toast.makeText(getBaseContext(), "Success", Toast.LENGTH_SHORT).show();
}
Inside my AsyncTask, I am getting all user. Then I perform a loop to check if there is any matching username or password. If there is, I set the successCheck to false.
public class SignupAsyncTask extends AsyncTask<User, Integer, Boolean> {
ArrayList<User> list = new ArrayList<User>();
DB_User userCtrl = new DB_User();
Context context;
public static boolean successCheck = false;
public SignupAsyncTask(){}
public SignupAsyncTask(Context context){
this.context = context;
}
#Override
protected Boolean doInBackground(User... params) {
try {
list = userCtrl.getAllUser();
for(int i = 0; i < list.size(); i++){
User userObj = list.get(i);
if(params[0].getUserName().equals(userObj.getUserName())){
successCheck = false;
break;
}
else if (params[0].getEmail().equals(userObj.getEmail())){
successCheck = false;
break;
} else{
successCheck = true;
break;
}
}
} catch (JSONException e) {
e.printStackTrace();
}
if(successCheck == true){
userCtrl.SignupUser(params[0]);
}
return successCheck;
}
#Override
protected void onPostExecute(Double result){
}
#Override
protected void onProgressUpdate(Integer... progress) {
}
}
The problem that I have encountered now is for the first time when I am testing with a non-duplicate username and email, it can insert into database but somehow the toast printed out 'Failed'.
Then, when I try with another duplicate record, it does not insert into database as I set my username and email to be UNIQUE but the toast is printing out 'Success'.
It is operated in the opposite way as my code logic. Any ideas?
Thanks in advance
EDIT
public class SignupAsyncTask extends AsyncTask<User, Integer, Boolean> {
ArrayList<User> list = new ArrayList<User>();
DB_User userCtrl = new DB_User();
Context lcontext;
public static boolean successCheck = false;
public SignupAsyncTask(){}
public SignupAsyncTask(Context context){
lcontext = context;
}
#Override
protected Boolean doInBackground(User... params) {
try {
list = userCtrl.getAllUser();
for(int i = 0; i < list.size(); i++){
User userObj = list.get(i);
if(params[0].getUserName().equals(userObj.getUserName())){
successCheck = false;
break;
}
else if (params[0].getEmail().equals(userObj.getEmail())){
successCheck = false;
break;
} else{
successCheck = true;
break;
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return successCheck;
}
#Override
protected void onPostExecute(Boolean result){
if(successCheck)
{
//userCtrl.SignupUser(userobject);
Log.d("Check","Ran Success");
Toast.makeText(lcontext, "Success", Toast.LENGTH_SHORT).show();
}
else {
Log.d("Check","Ran Fail");
Toast.makeText(lcontext, "Failed", Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onProgressUpdate(Integer... progress) {
}
It's because of AsyncTask, as its name, is an asynchronous task. You need to test the result in your SignupAsyncTask class.
Add the logic to your AsyncTask onPostExecute():
#Override
protected void onPostExecute(Boolean result){
if(result == false){
// Process if false
} else if(result == true){
// Process if true
}
}
Because you can't access UI thread from SignupAsyncTask (where your class is not a member class of your caller class), you need to define an interface as listener mechanism in your caller class to receive the result from your AsyncTask. So whenever there is a change in data, it will inform the caller who implements the interface.
Something like:
public interface OnSuccessCheckReceived{
void onSuccessCheckReceived(boolean isSuccess);
}
Then you add the callback interface to SignupAsyncTask:
public class SignupAsyncTask extends AsyncTask<User, Integer, Boolean> {
...
OnSuccessCheckReceived callBack;
public SignupAsyncTask(){}
public SignupAsyncTask(Context context, OnSuccessCheckReceived callBack){
this.context = context;
this.callBack = callBack;
}
...
#Override
protected void onPostExecute(Boolean result){
//if(result == false){
// // Process if false
// callBack.onSuccessCheckReceived(false); // Tell the caller
//} else if(result == true){
// // Process if true
//}
// a more compact code
callBack.onSuccessCheckReceived(result); // Tell the caller
}
Then you need to implement the listener interface to your caller class.
Something like:
public class YourCallerActivity implements OnSuccessCheckReceived {
...
#Override
public void onSuccessCheckReceived(boolean isSuccess) {
if(isSuccess){
Toast.makeText(getBaseContext(), "Failed", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getBaseContext(), "Success", Toast.LENGTH_SHORT).show();
}
}
...
}
Then you must call your AsyncTask with:
// this is pointing to your implemented interface.
new SignupAsyncTask(getBaseContext(), this).execute(userModel);
Suggestion,
Better if you don't add a context to an AsyncTask, because when your app terminated and AsyncTask not yet finished its job, your AsyncTask will throw an Error because the previous context its pointing is already gone.
So you need to change your SignupAsyncTask constructor to:
public SignupAsyncTask(OnSuccessCheckReceived callBack){
//this.context = context; Remove this.
this.callBack = callBack;
}
and call the SignupAsyncTask with:
new SignupAsyncTask(this).execute(userModel);
UPDATE
As #trooper pointing out, you need to change your:
#Override
protected void onPostExecute(Double result){
}
to
#Override
protected void onPostExecute(Boolean result){
}
So to tell the caller class, you need to tell about the result:
#Override
protected void onPostExecute(Boolean result){
// This is a more compact code that your previous code.
callBack.onSuccessCheckReceived(result); // Tell the caller
}
based on the other signatures in your AsyncTask.
Put your logic inside onPostExecute() :
protected void onPostExecute(Boolean result){
if(successCheck){
Toast.makeText(getBaseContext(), "Success", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getBaseContext(), "Failed", Toast.LENGTH_SHORT).show();
}
}
AsyncTask executes asynchronously i.e., It does not run on a Main thread. It spawns a separate thread known as Worker thread, executes its logic and then post back the results onto the Main thread.
Edit 1
Change your code as below :
public class SignupAsyncTask extends AsyncTask<User, Integer, Boolean> {
ArrayList<User> list = new ArrayList<User>();
DB_User userCtrl = new DB_User();
Context context;
public static boolean successCheck = false;
User user = null;
public SignupAsyncTask(){}
public SignupAsyncTask(Context context){
this.context = context;
}
#Override
protected Boolean doInBackground(User... params) {
try {
user = params[0];
list = userCtrl.getAllUser();
for(int i = 0; i < list.size(); i++){
User userObj = list.get(i);
if(user.getUserName().equals(userObj.getUserName())){
successCheck = false;
break;
}
else if (user.getEmail().equals(userObj.getEmail())){
successCheck = false;
break;
} else{
successCheck = true;
break;
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return successCheck;
}
#Override
protected void onPostExecute(Boolean result){
if(result){
Toast.makeText(getBaseContext(), "Success", Toast.LENGTH_SHORT).show();
//Call SignupUser Code Here...
if(user != null) {
userCtrl.SignupUser(user);
}
} else {
Toast.makeText(getBaseContext(), "Failed", Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onProgressUpdate(Integer... progress) {
}
}
Please modify your code like this
private ArrayList<User> list;
private DB_User userCtrl;
private Context context;
private SendResponse mRes;
public SignupAsyncTask(Context context,SendResponse res){
this.context = context;
userCtrl = new DB_User();
list = new ArrayList<User>();
mRes = res;
}
#Override
protected Boolean doInBackground(User... params) {
try {
list = userCtrl.getAllUser();
for(User userObj:userCtrl.getAllUser()){
if(params[0].getUserName().equals(userObj.getUserName())
|| params[0].getEmail().equals(userObj.getEmail()))
return false;
}else{
userCtrl.SignupUser(params[0]);
return true;
}
} catch (JSONException e) {
e.printStackTrace();
return false;
}
return true;
}
#Override
protected void onPostExecute(Boolean result){
//notify through interface to activity or fragment wherever you want to
//mRes.sendResponse(result);
}
#Override
protected void onProgressUpdate(Integer... progress) {
}

Android deelay between methods call

I have an aplication that gets the count of the user_id on the database to check if the user exists or not.
the code I am having problem:
registerBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
usernameR = usernameRgt.getText().toString();
emailR = emailRgt.getText().toString();
passwordR = passwordRgt.getText().toString();
repeatR = repeatPassRgt.getText().toString();
new userExistsTask().execute(new ApiConnector());
if ((usernameR == null || usernameR.isEmpty() == true) || (emailR == null || emailR.isEmpty() == true) || (passwordR == null || passwordR.isEmpty() == true) || (repeatR == null || repeatR.isEmpty() == true)) {
Toast.makeText(RegisterActivity.this, "One or more fields are empty!", Toast.LENGTH_SHORT).show();
} else {
if (userExistN == 0) {
Toast.makeText(RegisterActivity.this, "Não existe", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(RegisterActivity.this, "existe", Toast.LENGTH_SHORT).show();
}
}
}
});
It works the way I want to the problem is that the call to the new userExistsTask().execute(new ApiConnector());(method that set the variable userExistsN value) takes some time to execute and the if gets the wrong value to the variable userExistsN so there is a way to put a delay between the if and the method call?
Update:
userExistYask() code:
private class userExistsTask extends AsyncTask<ApiConnector,Long,JSONArray>
{
#Override
protected JSONArray doInBackground(ApiConnector... params) {
// it is executed on Background thread
return params[0].userExists(usernameR);
}
#Override
protected void onPostExecute(JSONArray jsonArray) {
if (jsonArray != null) {
JSONObject json = null;
try {
json = jsonArray.getJSONObject(0);
userExistN = json.getInt("userCount");
System.out.println(userExistN);
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Toast.makeText(RegisterActivity.this, "Null", Toast.LENGTH_SHORT).show();
}
}
}
Why don't you put the IF code in separate method and call this method from postExecute? This guarantees the method won't be called till the background method is done
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
}
}, 5000);
There's a couple issues here. You're calling your AsyncTask even if the text fields are empty, which is not needed.
To solve your main issue, just move the functionality that requires the result of the AsyncTask to onPostExecute().
Something like this:
registerBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
usernameR = usernameRgt.getText().toString();
emailR = emailRgt.getText().toString();
passwordR = passwordRgt.getText().toString();
repeatR = repeatPassRgt.getText().toString();
if ((usernameR == null || usernameR.isEmpty() == true) || (emailR == null || emailR.isEmpty() == true) || (passwordR == null || passwordR.isEmpty() == true) || (repeatR == null || repeatR.isEmpty() == true)) {
Toast.makeText(RegisterActivity.this, "One or more fields are empty!", Toast.LENGTH_SHORT).show();
} else {
new userExistsTask().execute(new ApiConnector());
}
}
});
Then your AsyncTask:
private class userExistsTask extends AsyncTask<ApiConnector,Long,JSONArray>
{
#Override
protected JSONArray doInBackground(ApiConnector... params) {
// it is executed on Background thread
return params[0].userExists(usernameR);
}
#Override
protected void onPostExecute(JSONArray jsonArray) {
if (jsonArray != null) {
JSONObject json = null;
try {
json = jsonArray.getJSONObject(0);
userExistN = json.getInt("userCount");
//change this to Lod.d(Tag, userExistN);
System.out.println(userExistN);
if (userExistN == 0) {
Toast.makeText(getApplicationContext(), "Não existe", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "existe", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Toast.makeText(RegisterActivity.this, "Null", Toast.LENGTH_SHORT).show();
}
}
}
Create an Interface
public interface AsyncResponse {
void processFinish(int userExistN);
}
In userExistsTask class:
private class userExistsTask extends AsyncTask<ApiConnector,Long,JSONArray>
{
public AsyncResponse delegate=null;
#Override
protected JSONArray doInBackground(ApiConnector... params) {
return params[0].userExists(usernameR);
}
:
:
:
}
#Override
protected void onPostExecute(JSONArray jsonArray) {
delegate.processFinish(userExistN);
}
In Activity onCreate()
userExistsTask existsTask = new userExistsTask();
existsTask.execute(new ApiConnector());
existsTask.delegate = this;
void processFinish(int userExistN){
if ((usernameR == null || usernameR.isEmpty() == true) || (emailR == null || emailR.isEmpty() == true) || (passwordR == null || passwordR.isEmpty() == true) || (repeatR == null || repeatR.isEmpty() == true)) {
Toast.makeText(RegisterActivity.this, "One or more fields are empty!", Toast.LENGTH_SHORT).show();
} else {
if (userExistN == 0) {
Toast.makeText(RegisterActivity.this, "Não existe", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(RegisterActivity.this, "existe", Toast.LENGTH_SHORT).show();
}
}
}

trying to find when CH34xAndroidDriver.isConnected() is becomes true

I am trying to find when and where CH34xAndroidDriver.isConnected() value becomes true.
I have tried to find out and display its value in a toast. can anybody explain it clearly.
public class UartLoopBackActivity extends Activity {
public static final String TAG = "com.wch.wchusbdriver";
private static final String ACTION_USB_PERMISSION = "com.wch.wchusbdriver.USB_PERMISSION";
/* thread to read the data */
public readThread handlerThread;
protected final Object ThreadLock = new Object();
/* declare UART interface variable */
public CH34xAndroidDriver uartInterface;
// byte timeout; // time out
public Context global_context;
public boolean isConfiged = false;
public boolean READ_ENABLE = false;
public SharedPreferences sharePrefSettings;
Drawable originalDrawable;
public String act_string;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/* create editable text objects */
readText = (EditText) findViewById(R.id.ReadValues);
// writeText = (EditText) findViewById(R.id.WriteValues);
global_context = this;
configButton = (Button) findViewById(R.id.configButton);
originalDrawable = configButton.getBackground();
readBuffer = new char[512];
baudRate = 9600;
stopBit = 1;
dataBit = 8;
parity = 0;
flowControl = 0;
configButton.setOnClickListener(new OpenDeviceListener());
// writeButton.setOnClickListener(new OnClickedWriteButton());
// writeButton.setEnabled(false);
//
uartInterface = new CH34xAndroidDriver(
(UsbManager) getSystemService(Context.USB_SERVICE), this,
ACTION_USB_PERMISSION);
act_string = getIntent().getAction();
if (-1 != act_string.indexOf("android.intent.action.MAIN")) {
Log.d(TAG, "android.intent.action.MAIN");
} else if (-1 != act_string
.indexOf("android.hardware.usb.action.USB_DEVICE_ATTACHED")) {
Log.d(TAG, "android.hardware.usb.action.USB_DEVICE_ATTACHED");
}
if (!uartInterface.UsbFeatureSupported()) {
Toast.makeText(this, "No Support USB host API", Toast.LENGTH_SHORT)
.show();
readText.setText("No Support USB host API");
uartInterface = null;
Toast.makeText(global_context,
"148k" + ((Boolean) uartInterface.isConnected()),
Toast.LENGTH_SHORT).show();
}
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
if (READ_ENABLE == false) {
READ_ENABLE = true;
handlerThread = new readThread(handler);
handlerThread.start();
Toast.makeText(global_context,"155k" + ((Boolean) uartInterface.isConnected()),Toast.LENGTH_SHORT).show();
}
}
public class OpenDeviceListener implements View.OnClickListener {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
boolean flags;
Toast.makeText(global_context,"170" + ((Boolean) uartInterface.isConnected()),Toast.LENGTH_SHORT).show();
Log.d("onClick", "12");
if (false == isConfiged) {
Log.d("onClick", "58");
isConfiged = true;
Log.d("onClick", "98");
// writeButton.setEnabled(true);
if (uartInterface.isConnected()) {
Log.d("onClick", "100");
flags = uartInterface.UartInit();
if (!flags) {
Log.d(TAG, "Init Uart Error");
Toast.makeText(global_context, "Init Uart Error",
Toast.LENGTH_SHORT).show();
} else {
if (uartInterface.SetConfig(baudRate, dataBit, stopBit,
parity, flowControl)) {
Log.d(TAG, "Configed");
}
}
}
if (isConfiged == true) {
Toast.makeText(global_context,"193" + ((Boolean) uartInterface.isConnected()),Toast.LENGTH_SHORT).show();
Log.d("onClick", "200");
configButton.setEnabled(false);
}
}
}
}
public void onHomePressed() {
onBackPressed();
}
public void onBackPressed() {
super.onBackPressed();
}
protected void onResume() {
super.onResume();
if (2 == uartInterface.ResumeUsbList()) {
uartInterface.CloseDevice();
Log.d(TAG, "Enter onResume Error");
}
}
protected void onPause() {
super.onPause();
}
protected void onStop() {
if (READ_ENABLE == true) {
READ_ENABLE = false;
}
super.onStop();
}
protected void onDestroy() {
if (uartInterface != null) {
if (uartInterface.isConnected()) {
uartInterface.CloseDevice();
}
uartInterface = null;
}
super.onDestroy();
}
final Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
if (actualNumBytes != 0x00) {
readText.append(String.copyValueOf(readBuffer, 0,
actualNumBytes));
Toast.makeText(global_context,"269k" + ((Boolean) uartInterface.isConnected()),Toast.LENGTH_SHORT).show();
actualNumBytes = 0;
}
}
};
/* usb input data handler */
private class readThread extends Thread {
Handler mHandler;
/* constructor */
Handler mhandler;
readThread(Handler h) {
mhandler = h;
this.setPriority(Thread.MIN_PRIORITY);
}
public void run() {
while (READ_ENABLE) {
Message msg = mhandler.obtainMessage();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
// Log.d(TAG, "Thread");
synchronized (ThreadLock) {
if (uartInterface != null) {
actualNumBytes = uartInterface.ReadData(readBuffer, 64);
if (actualNumBytes > 0) {
mhandler.sendMessage(msg);
}
}
}
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.uart_loop_back, menu);
return true;
}
}
upto line 74 (Toast.makeText(global_context,"155k" + ((Boolean) uartInterface.isConnected()),Toast.LENGTH_SHORT).show();) i found it returns false but when the onClick() is called it return true. why if any body has answer pls check it.
Thanks
the method ResumeUsbList() enables usb connection and changes isConnected() to true. if ResumeUsbList() fails it returns 2
Check your Activity's onResume()

Android RX Observer to SQLite Database not working

I am trying to add an RX observer to my SQLite database and I am surely missing something from my implementation as neither the onNext() and onCompleted() methods from my observer are not getting called.
Here is my observer:
private final Observer<List<Order>> mObjectiveObserver = new Observer<List<Order>>() {
#Override
public void onCompleted() {
System.out.println("Load completed");
}
#Override
public void onError(Throwable e) {
}
#Override
public void onNext(List<Order> objectives) {
System.out.println("On Next: " + objectives.size() + " elements found!");
orderAdapter.clear();
if (objectives != null) {
orderAdapter.addAll(objectives);
mCirclePulseView.setVisibility(View.INVISIBLE);
} else {
mCirclePulseView.setVisibility(View.VISIBLE);
}
orderAdapter.notifyDataSetChanged();
}
};
These are my LoaderCallback methods:
#Override
public Loader<Cursor> onCreateLoader(int loaderId, Bundle args) {
Loader<Cursor> loader = null;
switch (loaderId) {
case LOADER_ORDERS:
System.out.println("Create loader called");
loader = new CursorLoader(OrderManagerApplication.getAppContext(), OrderManagerContract.Order.CONTENT_URI,
QueryOrder.PROJECTION_SIMPLE, null, null, OrderManagerContract.Order.DATE_SORT);
break;
}
return loader;
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
if (getActivity() == null) {
return;
}
if (data != null && !data.isClosed()) {
System.out.println("Finished loading orders, data not null");
switch (loader.getId()) {
case LOADER_ORDERS:
if (subscription != null && !subscription.isUnsubscribed()) {
subscription.unsubscribe();
}
subscription = AndroidObservable
.bindFragment(this, DatabaseHelper.mainOrdersObservable(data))
.subscribeOn(Schedulers.computation())
.unsubscribeOn(AndroidSchedulers.mainThread())
.subscribe(mObjectiveObserver);
System.out.println("I should be here, onLoadFinished");
break;
}
}
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
}
The content observer code follows below:
class HomeOrdersContentObserver extends ContentObserver {
private int mLoaderId = 0;
public HomeOrdersContentObserver(Handler handler, int loaderId) {
super(handler);
mLoaderId = loaderId;
}
#Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
if (getActivity() == null) {
return;
}
Bundle bundle = new Bundle();
//bundle.putString(FILTER_TXT, lastFilterQ);
restartLoader(mLoaderId, bundle);
}
}
public void restartLoader(int loaderId, Bundle args) {
getLoaderManager().restartLoader(loaderId, args, this);
}
I have put logs everywhere in my code and they get printed as they should, except for this onNext and onCompleted methods. Any ideas what I might be missing from my implementation?
I see a few problems with the above code.
1st: you're not actually calling onNext/onCompleted anywhere. Since you're trying to connect the two paradigms (Loader & Rx), then you would need to put onNext in the onLoadFinished (with onError in case you want it called when there's no data, but that will close the subscription) and onCompleted in onLoaderReset
2nd: you're redoing the subscription in onLoadFinished, which I don't think you'd want - why would you want to resubscribe every time you have new data? You should do it when creating the loader, and unsubscribe when destroying the loader (onLoaderReset).
This is one possible implementation:
#Override
public Loader<Cursor> onCreateLoader(int loaderId, Bundle args) {
Loader<Cursor> loader = null;
switch (loaderId) {
case LOADER_ORDERS:
System.out.println("Create loader called");
loader = new CursorLoader(OrderManagerApplication.getAppContext(), OrderManagerContract.Order.CONTENT_URI,
QueryOrder.PROJECTION_SIMPLE, null, null, OrderManagerContract.Order.DATE_SORT);
if (subscription != null && !subscription.isUnsubscribed()) {
subscription.unsubscribe();
}
subscription = AndroidObservable
.bindFragment(this, DatabaseHelper.mainOrdersObservable(data))
.subscribeOn(Schedulers.computation())
.unsubscribeOn(AndroidSchedulers.mainThread())
.subscribe(mObjectiveObserver);
break;
}
return loader;
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
if (getActivity() == null) {
return;
}
if (data != null && !data.isClosed()) {
System.out.println("Finished loading orders, data not null");
switch (loader.getId()) {
case LOADER_ORDERS:
mObjectiveObserver.onNext(data);
System.out.println("I should be here, onLoadFinished");
break;
}
} else {
mObjectiveObserver.onError("No data available");
}
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
if (subscription != null && !subscription.isUnsubscribed()) {
subscription.unsubscribe();
}
}
Have in mind that structured like this, in case of no data it will actually close the subscription (onError does that) so you won't be able to receive any more data from the loader. If you don't want that, then in case of onError above, you would actually call onNext with null or new ArrayList and then take care of it in your observer.

TextToSpeech only works when button is pressed, not when called separately

I tried to do something extremely simple or I thought it was.
In my BluetoothChat, I set
public static boolean potato = false;
In the onCreateBundle of my MainActivity, I have
talker = new TextToSpeech(getApplicationContext(),new TextToSpeech.OnInitListener()
{
#Override
public void onInit(int status)
{
if(status != TextToSpeech.ERROR)
{
talker.setLanguage(Locale.US);
}
}
});
if(BluetoothChat.potato == false)
{
speakOut();
}
When speakOut(); is called by a button or separately by itself it works.
public void speakOut()
{
String original ="You will have a seizure in thirty seconds.";
talker.speak(original,TextToSpeech.QUEUE_FLUSH,null);
}
However, this does not work. Can someone explain why?
Thanks to the help from Payeli. Here is the solution! Place the if statement within the onInit.
talker = new TextToSpeech(getApplicationContext(),new TextToSpeech.OnInitListener()
{
#Override
public void onInit(int status)
{
if(status != TextToSpeech.ERROR)
{
talker.setLanguage(Locale.US);
}
if(BluetoothChat.potato == false)
{
speakOut();
}
}
});

Categories