Own app is loading infinitely with Quickblox - java

I made an android app just like this tutorial :
[https://www.youtube.com/watch?v=5AhghMG9Y1I I can register and sign in without any problems but after logging in it stays forever in the screen "Loading" and it doesnt open the next activity where I can start chatting with other users. The android monitor says:
FATAL EXCEPTION: main
Process: com.example.georg.chatapp, PID: 31740
java.lang.NullPointerException: Attempt to invoke virtual method
'java.lang.String com.quickblox.users.model.QBUser.getLogin()' on a
null object reference
at
com.example.georg.chatapp.ListUsersActivity$4.onSuccess(ListUsersActivity.java:160)
at
com.example.georg.chatapp.ListUsersActivity$4.onSuccess(ListUsersActivity.java:149)
Here is the code where its linked to:
private void retrieveAllUsers() {
QBUsers.getUsers(null).performAsync(new QBEntityCallback<ArrayList<QBUser>>() {
#Override
public void onSuccess(ArrayList<QBUser> qbUsers, Bundle bundle) {
//add cache
QBUsersHolder.getInstance().putUsers(qbUsers);
ArrayList<QBUser> qbUserWithoutCurrent = new ArrayList<QBUser>();
for (QBUser user : qbUsers)
{
if (!user.getLogin().equals(QBChatService.getInstance().getUser().getLogin()))
qbUserWithoutCurrent.add(user);
}
ListUsersAdapter adapter = new ListUsersAdapter(getBaseContext(),qbUserWithoutCurrent);
lstUsers.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
#Override
public void onError(QBResponseException e) {
Log.e("ERROR",e.getMessage());
}
});
}
User Login:
private void createSessionForChat() {
final ProgressDialog mDialog = new ProgressDialog(ChatDialogsActivity.this);
mDialog.setMessage("Verbindung wird hergestellt");
mDialog.setCanceledOnTouchOutside(false);
mDialog.show();
String user,password;
user = getIntent().getStringExtra("user");
password = getIntent().getStringExtra("password");
final QBUser qbUser = new QBUser(user,password);
QBAuth.createSession(qbUser).performAsync(new QBEntityCallback<QBSession>() {
#Override
public void onSuccess(QBSession qbSession, Bundle bundle) {
qbUser.setId(qbSession.getUserId());
try {
qbUser.setPassword(BaseService.getBaseService().getToken());
} catch (BaseServiceException e) {
e.printStackTrace();
}
QBChatService.getInstance().login(qbUser, new QBEntityCallback() {
#Override
public void onSuccess(Object o, Bundle bundle) {
mDialog.dismiss();
}
#Override
public void onError(QBResponseException e) {
Log.e("ERROR",""+e.getMessage());
}
});
}
#Override
public void onError(QBResponseException e) {
}
});
}
I hope you have an idea how to solve it. I use QuickBlox as server.
When I press the "back" button while its loading the next activity with the floating button appears for some secconds and then it crashes.

It happen because no user is logged in to the chat (maybe logged to the REST but not to chat). In your case you need login to the chat before loading users, for it use QBChatService.getInstance().login(qbUser);
qbUser - QBUser with id, login and password.

Related

Android Java: Speech Recognition App crashes whenever there are no results

I am developing an Android app that uses the Google speech recognition api. For some reason, when I start up the app (via USB debugging on my Android phone), starting the listening process works just fine, and the app works smoothly if I do actually say something after clicking the button to make the app start listening for audio. However, if I click the button to start listening, and then I don't say anything, then the app crashes for some reason. In other words, if the speech recognition gets no results, then the app just crashes. Does anyone have any idea as to why?
Below is an excerpt of my code. (Yes, I did account for the permissions. I just didn't include that code in the excerpt below).
I have tried putting try catch blocks in various places to see if I could catch the error that causes the crash, but it has yet to work. Furthermore, while there is an onResults method, there does not seem to be an onNoResults method.
speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
recognitionListener = new RecognitionListener() {
#Override
public void onReadyForSpeech(Bundle params) {
// Called when the speech recognition process is ready to begin
}
#Override
public void onBeginningOfSpeech() {
// Called when the user begins speaking
}
#Override
public void onRmsChanged(float rmsdB) {
// Called when the volume of the spoken input changes
}
#Override
public void onBufferReceived(byte[] buffer) {
// Called when the app receives a buffer of audio data
}
#Override
public void onEndOfSpeech() {
// Called when the user stops speaking
}
#Override
public void onError(int error) {
// Called when an error occurs during the speech recognition process
TextView textView = findViewById(R.id.errors);
textView.setText(error);
}
#Override
public void onResults(Bundle results) {
// Called when the speech recognition process has completed and the results are available
List<String> resultList = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
if (resultList != null && resultList.size() > 0) {
// Display the first result in the text field
TextView textView = findViewById(R.id.spokenWords);
textView.setText(resultList.get(0));
}
//speechRecognizer.startListening(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH));
}
#Override
public void onPartialResults(Bundle partialResults) {
// Called when the app receives partial results of the speech recognition process
}
#Override
public void onEvent(int eventType, Bundle params) {
// Called when the app receives other events from the speech recognition process
}
};
speechRecognizer.setRecognitionListener(recognitionListener);
Button startSpeech = findViewById(R.id.startSpeech);
startSpeech.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
TextView textView = findViewById(R.id.spokenWords);
textView.setText("Listening");
speechRecognizer.startListening(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH));
}
});

Data Auto sync does not work well in android app fragment when app is exited and resumed

I am using navigation component in my android app and I have a fragment that I need to auto sync data from server and store in room database which works fine (My idea is to make sure the room database at all time it has updated products that is incase a product was updated from the server it should pick when user start using the app) but I have this weird behavior when application start sync and i put it to background and resume again. If I leave the sync process to complete without from from the app it works perfectly but if I exit the app and come back again its messed up here is what I mean.
When I sync data without exiting the app here is the output.
and when I exit the app while syncing data then resume again here is what am getting
it like when I resume the app the thread is restarting again instead of picking where it left.
This is how am calling my sync fragment from main activity on Resume method.
and here is my fragment code that sync data. NB I dont want to use AsyncTask as I saw it looks deprecated.
public class FragmentAutoSync extends Fragment {
FragmentAutoSyncBinding binding;
public FragmentAutoSync() {
// Required empty public constructor
}
List<ProductEntity> new_products;
List<ProductEntity> deleted_products;
private ProductRepository repository;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding=FragmentAutoSyncBinding.inflate(inflater);
repository=new ProductRepository(getActivity());
try {
progress_dialog= AlertUtil.getCustomDialog(getActivity(), R.layout.progress_layout);
progress_dialog.setCancelable(false);
progress_dialog.show();
handler=new Handler();
autoSyncService= Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
autoSyncService.execute(new ProductSyncTask());
} catch (Exception e) {
ExceptionHandler.logException(e);
ExceptionHandler.showToast(getActivity(),"Error occurred while syncing data");
}
return binding.getRoot();
}
Dialog progress_dialog;
private ExecutorService autoSyncService;
private Handler handler;
private class ProductSyncTask implements Runnable
{
#Override
public void run() {
startAutoSync();
}
}
void startAutoSync()
{
try{
if(new_products==null)
{
new_products=new ArrayList<>();
}
if(deleted_products==null)
{
deleted_products=new ArrayList<>();
}
TextView textView=progress_dialog.findViewById(R.id.text_progress);
textView.setVisibility(View.VISIBLE);
TextView text_processing=progress_dialog.findViewById(R.id.text_processing);
startSync(textView,text_processing);
}
catch (Exception e)
{
ExceptionHandler.logException(e);
ExceptionHandler.showToast(getActivity(),"Error Occurred while Syncing products");
}
finally {
handler.post(()->
{
close();
});
}
}
volatile int counter=0;
volatile int total;
void startSync(TextView textView,TextView text_processing) throws Exception
{
counter=1;
handler.post(()->{
text_processing.setText("Reading data...");
});
new_products=loadList(textView);
total=new_products.size()+deleted_products.size()+1;
handler.post(()->{
text_processing.setText("Syncing Data Please wait...");
});
repository.deleteAll();
;
for(ProductEntity p:new_products)
{
Thread.sleep(5);
repository.insertProduct(p);
handler.post(() -> {
textView.setText(counter+"/"+total);
counter++;
});
}
//deleted_products=AppUtil.deleted_products
for(ProductEntity e:deleted_products)
{
repository.deleteOneProduct(e);
textView.setText(counter+"/"+total);
counter++;
}
}
int i=0;
List<ProductEntity> loadList(TextView textView)
{
new_products= new ArrayList<>();
ProductEntity p;
i=0;
int counter=0;
for(int x=1;x<5000;x++) {
if(counter>=1000)
{
System.gc();
counter=0;
}
counter++;
p= new ProductEntity();
p.setBuying_price_per_item(0);
p.setMake("NA");
p.setName(randomName());//method to generate random name for simulating
p.setProduct_description(randomName());
p.setRetail_selling_price(450);
p.setTax(0);
p.setUnits("NA");
p.setQuantity_to_sell_wholesale(0);
p.setStatus("A");
p.setProduct_id(x);
new_products.add(p);
handler.post(()->
{
i++;
textView.setText("Read :"+String.valueOf(i));
}
);
}
return new_products;
}
}

How to avoid android application crash, when setOwnerActivity(Activity activity) in custom DialogFragment causes nullpointerException?

I got a very strange exception while using Sharedpreferences and DialogFragment:
Unable to start activity ComponentInfo{com.example.barta1.site_patrol/com.example.barta1.site_patrol.MainActivity}:
java.lang.NullPointerException: Attempt to invoke virtual method
'void android.app.Dialog.setOwnerActivity(android.app.Activity)'
on a null object reference -
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2679)
I really do not have a clue what causes this error, but after this happened, I never be able to start
my application again, it continuosly crashed with the same exception above. The MainActivity is my launching activity in my application with a DialogFragment attached which I use to login users. I show this dialogfragment if the users not logged in (the "logged in" status saved in a sharedpreference object).
My MainActivity is like this:
public class MainActivity extends AppCompatActivity implements LoginDialogFragment.NoticeDialogListener {
//...
private LoginDialogFragment dialogFragment;
SharedPreferences pref;
SharedPreferences.Editor edit;
//...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pref = getSharedPreferences("Globals", MODE_PRIVATE);
edit = pref.edit();
boolean isloggedin = pref.getBoolean("Loggedin", false);
if (!isloggedin) {
//if not logged in show the login dialog
showLoginDialog();
}
else {
//... doing some network calls...
}
}
public void showLoginDialog() {
dialogFragment = new LoginDialogFragment();
dialogFragment.show(getFragmentManager(), "LoginDialogFragment");
}
/***
* Network calls if dialog dismissed
* Login dialog can only be closed if logging in is successful
* (if loginname and password matches).
*/
#Override
public void onDismiss() {
//... some network related jobs
}
}
And here is the fragment class:
public class LoginDialogFragment extends DialogFragment {
public interface NoticeDialogListener{
void onDismiss();
}
NoticeDialogListener mListener;
Activity activity;
AlertDialog dialog;
SharedPreferences pref;
SharedPreferences.Editor edit;
#Override
public void onAttach(Context context) {
super.onAttach(context);
try{
activity = (Activity) context;
mListener = (NoticeDialogListener) activity;
pref = activity.getSharedPreferences("Globals", MODE_PRIVATE);
edit = pref.edit();
} catch (ClassCastException e){
throw new ClassCastException(activity.toString() + "must implement NoticeDialogListener");
}
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
String username = pref.getString("Username", null);
if(username==null) {
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.dialog_signin, null);
final AutoCompleteTextView actv_username = view.findViewById(R.id.username);
final EditText password = view.findViewById(R.id.password);
dialog = new AlertDialog.Builder(new ContextThemeWrapper(getContext(), R.style.AlertDialogCustom))
.setView(view)
.setTitle("Bejelentkezés")
.setPositiveButton("OK", null)
.create();
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialogInterface) {
final Button button = ( dialog).getButton(AlertDialog.BUTTON_POSITIVE);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String passw = password.getText().toString();
String user = actv_username.getText().toString();
try {
if (user.length() < 4 || passw.length() < 4) {
Toast.makeText(getContext(), "Too short user/pass.", Toast.LENGTH_SHORT).show();
dialog.show();
} else {
//login to account, if success dismiss.
login(user, passw, dialog);
}
} catch (Exception e) {
e.printStackTrace();
}
// dialog.dismiss();
}
});
}
});
dialog.setCanceledOnTouchOutside(false);
// set the DialogFragment to make the dialog unable to dismiss with back button
// (because not working if called on the dialog directly)
this.setCancelable(false);
return dialog;
} // end of - if username == null.
return null;
}
public void login(final String username, String password, final AlertDialog dialog){
//... some network call
//... if successful:
// edit.putString("Username", username);
// edit.commit();
// edit.putBoolean("Loggedin", true);
// edit.commit();
// dialog.dismiss();
// dialog.setOnShowListener(null);
//
// else
// Toast.makeText(getContext(),"Wrong login credentials",
// Toast.LENGTH_SHORT).show();
}
#Override
public void onDismiss(DialogInterface dialog) {
mListener.onDismiss();
dismissAllowingStateLoss();
}
After reinstalling the package, I could not recreate this exception (even when I killed app process, and start it from the recent apps), end users somehow managed to do this and that time, restarting the application was an instant crash (see the exception above.). It looks like parent activity becomes null somehow ( possible after saving the state and after cannot recover).
How to avoid this in the future? Is there a simple way to deal with this situation?
It would be also a great help if someone can explain to me when this "setOwnerActivity(Activity activity)" from the android library called, that way maybe I can identify what went wrong.
Thanks for any help.
As Mike M. stated out,
You cannot return null from onCreateDialog(). That's too late to be canceling or aborting the Dialog showing.
And the username check before creating the fragment will obviously solve the problem. Also, the LoggedIn field looks redundant now.

How to implement Reward video with Startapp

Recently I'm facing issue related to Startapp platform for Android.
When I implemented the reward video it returns an error with:
FailledError execute Exception Error sendGetWithResponse code = [204]
Here is my function:
public void rewardAd() {
Log.i("TAG", "Test");
startAppAd.setVideoListener(new VideoListener() {
#Override
public void onVideoCompleted() {
Log.i("TAG", "Grant User");
}
});
startAppAd.loadAd(StartAppAd.AdMode.REWARDED_VIDEO, new AdEventListener() {
#Override
public void onReceiveAd(com.startapp.android.publish.adsCommon.Ad ad) {
startAppAd.showAd();
}
#Override
public void onFailedToReceiveAd(com.startapp.android.publish.adsCommon.Ad ad) {
Log.i("TAG", "Failled"+ ad.getErrorMessage());
startAppAd.showAd(new AdDisplayListener() {
#Override
public void adHidden(com.startapp.android.publish.adsCommon.Ad ad) {
Log.i("TAG", "adHidden");
}
#Override
public void adDisplayed(com.startapp.android.publish.adsCommon.Ad ad) {
Log.i("TAG", "adDisplayed");
}
#Override
public void adClicked(com.startapp.android.publish.adsCommon.Ad ad) {
Log.i("TAG", "adClicked");
}
#Override
public void adNotDisplayed(com.startapp.android.publish.adsCommon.Ad ad) {
Log.i("TAG", "adNotDisplayed"+ ad.getErrorMessage());
}
});
//startAppAd.showAd(getApplicationContext());
}
});
}
Here is the logs that shows:
TAG: Test
TAG: FailledError execute Exception Error sendGetWithResponse code = [204]
TAG: adNotDisplayed
When I comment the function startAppAd.showAd(), and uncomment the last commented one startAppAd.showAd(), it's working fine.
This is the expected working scheme:
Try to load a Video Reward Ad => startAppAd.loadAd();
if failed (like my case) => onFailedToReceiveAd();
Try to show an Ad that I can get listeners of it => startAppAd.showAd()
Thank You very much
It's solved, the script itself is not bad and works fine, the problem was with Startapp they don't show a video ad because it doesn't exist any video to show.
Now if someone is facing the same problem i suggest to use a vpn on testing device with a country that startapp should have a video ad usually US.

Exception "Can't create handler inside thread that has not called looper prepare" in android app

I'm working on my first android app and I'm trying to use Quickblox.com as my backend.
In order to use it, I need to authorize the app by creating a session using their SDK.
So, I have the following code:
// Initialize QuickBlox application with credentials.
QBSettings.getInstance().fastConfigInit(Consts.APP_ID, Consts.AUTH_KEY, Consts.AUTH_SECRET);
// Authorize application
QBAuth.createSession(new QBCallback() {
#Override public void onComplete(Result result) {}
#Override
public void onComplete(Result result, Object context) {
if (result.isSuccess()) {
showMainScreen();
} else {
// print errors that came from server
Toast.makeText(getBaseContext(), result.getErrors().get(0), Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.INVISIBLE);
}
}
}, QBQueries.QB_QUERY_AUTHORIZE_APP);
This code works well with an emulator, but it doesn't work if I try with a real android phone. I have a connection timeout error. I think I need to make this kind of requests (Web Services) in the background right?
So I tried to use the AsyncTask to make the request to QB in the background, and changed the code to this:
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
// Initialize QuickBlox application with credentials.
QBSettings.getInstance().fastConfigInit(Consts.APP_ID, Consts.AUTH_KEY, Consts.AUTH_SECRET);
// Authorize application
QBAuth.createSession(new QBCallback() {
#Override public void onComplete(Result result) {}
#Override
public void onComplete(Result result, Object context) {
if (result.isSuccess()) {
showMainScreen();
} else {
// print errors that came from server
Toast.makeText(getBaseContext(), result.getErrors().get(0), Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.INVISIBLE);
}
}
}, QBQueries.QB_QUERY_AUTHORIZE_APP);
return null;
}
}.execute();
I've seen a lot of similar questions here at SO, but I can't seem to find an answer that works with my code. I saw that functions that deal with the UI need to be called from the main thread, so I suppose that the code I have inside
onComplete(Result result, Object context)
should be inside a block like this right?
runOnUiThread(new Runnable()
{
public void run()
{
// code here
}
});
But I tried that as well and it didn't work. Any guesses?
I believe the problem is not because of the Toast and showMainScreen(). It still fails with this code:
// Initialize QuickBlox application with credentials.
QBSettings.getInstance().fastConfigInit(Consts.APP_ID, Consts.AUTH_KEY, Consts.AUTH_SECRET);
QBAuth.createSession(new QBCallback() {
#Override
public void onComplete(Result arg0, Object arg1) {
// TODO Auto-generated method stub
}
#Override
public void onComplete(Result arg0) {
// TODO Auto-generated method stub
}
}, QBQueries.QB_QUERY_AUTHORIZE_APP);
But it doesn't fail if I just create the QBCallback object, without passing it to the QBAuth.createSession function.
You can't show a Toast in doInBackground of AsyncTask as it is a different threat and not the main UI thread.
To show a toast or any UI related task you have to do it in onPostExecute method of AsyncTask.
What you can do is
new AsyncTask<Void, Void, boolean>() {
#Override
protected boolean doInBackground(Void... params) {
// Initialize QuickBlox application with credentials.
QBSettings.getInstance().fastConfigInit(Consts.APP_ID, Consts.AUTH_KEY, Consts.AUTH_SECRET);
boolean res = false;
// Authorize application
QBAuth.createSession(new QBCallback() {
#Override public void onComplete(Result result) {}
#Override
public void onComplete(Result result, Object context) {
if (result.isSuccess()) {
//showMainScreen();
res = true
}
//else {
// print errors that came from server
//Toast.makeText(getBaseContext(), result.getErrors().get(0), //Toast.LENGTH_SHORT).show();
//progressBar.setVisibility(View.INVISIBLE);
//}
}
}, QBQueries.QB_QUERY_AUTHORIZE_APP);
return res;
}
protected void onPostExecute(boolean result) {
if(result) {
showMainScreen();
} else {
Toast.makeText(getBaseContext(), result.getErrors().get(0), Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.INVISIBLE);
}
}
}.execute();
You don't need to use AsyncTasks, because all operations already perform in background.
And also this one
QBAuth.createSession(new QBCallback() {
it performs request in background to QB and call callback in Main thread.
Could you explain what 'connection timeout error' you got.
Is there anything in log?

Categories

Resources