Creating Threads results in force close in android app - java

I am trying to create a thread to handle a login function that is executed when the login button is pushed, so that I can show a progressDialog.
btnLogin.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Check Login
ProgressDialog.show(Activity.this, "", "Loading...");
new Thread(new Runnable(){
public void run(){
try{
int duration;
Toast toast;
Context context;
String username = etUsername.getText().toString();
String password = etPassword.getText().toString();
JSONArray jsonArray=null;
password=ServerConnection.encryptPassword(password);
//Log.i("login hash",password);
jsonArray=ServerConnection.login(username, password);
if(jsonArray!=null) //login successful
{
context=getApplicationContext();
duration=Toast.LENGTH_SHORT;
toast=Toast.makeText(context, "Login Successful!", duration);
toast.show();//Shows the little pop up right at the bottom of the screen
Intent i = new Intent(getApplicationContext(), MapWithFriends.class);
startActivity(i);
}
else
{
context=getApplicationContext();
duration=Toast.LENGTH_SHORT;
toast=Toast.makeText(context, "Login Fail", duration);
toast.show();//Shows the little pop up right at the bottom of the screen
//lblResult.setText("Login failed. Username and/or password doesn't match.");
}
}catch(Exception e)
{
Log.e("tag", e.getMessage());
}
progressDialog.dismiss();
}
}).start();
}
});
However when the thread is created, it force closes. If I change back to no threads, it works fine.
Thanks
Edit:
LogCat of crash:
Can't create handler inside thread that has not called Looper.prepare()
FATAL EXCEPTION: Thread-10
java.lang.NullPointerException
.....
would you guys need more than this?

You shouldn't modify the UI from any thread except the main thread , as you do in: progressDialog.dismiss();
Consider using Handler or AsyncTask instead. And I would also recommend reading this article.

From a non-UI thread use something like
runOnUiThread(new Runnable() {
// Your UI modifications here
});
or
yourUIControl.post(new Runnable() {
// something like
yourUIControl.setText("new text");
});

Related

One timer, multiple intents

I'm working on an app, where you have multiple cardviews on when you click on them it shows you a intro then after 10 seconds redirects to you to the activity, but i only know how to do one, but with multiple activities idk how to do that.
heres de code
TextView textView = findViewById(R.id.textView);
textView.setText(getIntent().getStringExtra("param"));
Animation myamin = AnimationUtils.loadAnimation(this, R.anim.transition);
textView.startAnimation(myamin);
final Intent a = new Intent(this, phonensmar.class);
Thread timer = new Thread()
{
public void run()
{
try
{
sleep(3000);
}catch (InterruptedException e)
{
e.printStackTrace();
}
finally {
startActivity(a);
finish();
}
}
};
timer.start();

Method failed to loop in onStart() and onCreate() thread

I'm following this tutorial.Right now, I'm trying to loop the fingerprint authentication part so that I can keep reauthenticate user fingerprint. I've tried to use thread in onStart() and onCreate() to while loop the authentication but the app is stuck in both cases.
Original code that can authenticate only one time
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);
keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
if (!keyguardManager.isKeyguardSecure()){
Toast.makeText(this,
"Lock screen security is not enable in Settings", Toast.LENGTH_LONG).show();
return;
}
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED){
Toast.makeText(this,
"Fingerprint authentication permission is not enabled", Toast.LENGTH_LONG).show();
return;
}
if (!fingerprintManager.hasEnrolledFingerprints()){
Toast.makeText(this, "Register at least one fingerprint in Settings", Toast.LENGTH_LONG).show();
return;
}
generateKey();
if (cipherInit()){
cryptoObject = new FingerprintManager.CryptoObject(cipher);
FingerprintHandler helper = new FingerprintHandler(this);
helper.startAuth(fingerprintManager, cryptoObject);
}
}
Thread in onStart() / onCreate() that failed
#Override
protected void onStart() {
super.onStart();
new Thread(new Runnable(){
public void run() {
while(true)
{
try {
Thread.sleep(50);
if (cipherInit()) {
cryptoObject = new FingerprintManager.CryptoObject(cipher);
FingerprintHandler helper = new FingerprintHandler(MainActivity.this);
helper.startAuth(fingerprintManager, cryptoObject);
}} catch (InterruptedException e){
e.printStackTrace();
}
}
}
}).start();}
Other than using thread, I also tried to use AsyncTask to do the while loop for me. This is my attempt in creating the class. My problem is that the cipherInit() resides in MainActivity.java and how can I invoke the method from my Looping class?
Looping.java
import android.hardware.fingerprint.FingerprintManager;
import android.os.AsyncTask;
public class Looping extends AsyncTask<Object,Void,Void> {
FingerprintManager fingerprintManager;
FingerprintManager.CryptoObject cryptoObject;
Cipher cipher;
#Override
protected Void doInBackground(Void... arg0) {
cipher = (Cipher) arg0[0];
while(true) {
if (cipherInit()) {
cryptoObject = new FingerprintManager.CryptoObject(cipher);
FingerprintHandler helper = new FingerprintHandler(MainActivity.this);
helper.startAuth(fingerprintManager, cryptoObject);
}
}
}}
MainActivity
Looping loop = new Looping();
loop.execute(cipher, null, null);
This is my first personal project and I'm still relatively new with the whole Android structure. I'll really appreciate any input from you all. Thanks in advance
You should not need the secondary thread or loop to do the authentication. The call to FingerprintManager.authenticate() is done in your FingerprintHandler (assuming you have the same code as the tutorial you cited). This is an asyc operation and the handler (FingerprintManager.AuthentciationCallback) is called back when the auth succeeds or fails. You need to take action based on that success/failure rather than poll in a while loop. That callback will occur on your main thread.

Cant get ProgressDialog to show up in android

I cant get a progress dialog to show when I need it to. I have tried putting it in my asyncTask the ui class and the its own thread that runs on the ui and none have worked. Can anyone help me?
the method where the progressDialog method is called:
public void shareTest(View view){ //method called to jump to share activity if criteria matched
if(checkInputs()) { //call to check inputs
Share start = new Share();
boolean isConnected=start.connectToServer(); //connectToServer
Intent intent = new Intent(HomeScreen.this, Share.class); //create intent to move to share class from this activity
startProgressDialog();
if (isConnected) { //check to see if isconnected was succesful
if (Share.matchFound ){ //check to see if a match was found
progress.dismiss();
startActivity(intent); //if true jump to share activity
} else {
while (!Share.timedOut) { //While the time has not timedOut
if (Share.matchFound) { //if a share has been found
startActivity(intent); //start share activity
break; //if true then break
}
}
if (Share.timedOut) {
//send an notice that a match wasn't found
sendToast(getString(R.string.noShare)); //if not true then send Toast
}
}
}
else sendToast(getString(R.string.errServCon)); //if connection to server failed then send toast
}
}
this is the method:
void startProgressDialog() {
new Thread(new Runnable() {
#Override
public void run() { //creates a new runnable thread
// Issue command() on a separate thread
while (!Share.matchFound) { //while havent been asked to disconnect //if a new location has been recieved
activity.runOnUiThread(new Runnable() {
#Override
public void run() { //run on the ui thread act
progress.show(); //call the method that does the update
}
});
}
progress.dismiss();
}
}).start();
}
Declare a global variable like this:
ProgressDialog progress;
Wherever you want to show the progress, paste this code:
progress = ProgressDialog.show(this, "Please wait",
"Loading..", true);
When you are done, simply dismiss it:
progress.dismiss();

in app billing handler, and handlers/services/receivers

Here is my code, I have a few questions as I am completely new to this whole service receiver thing.
It works fine. I get to checkout,I purchase, google says I will receive my item soon.
My question is that after the application gets closed, or after the activity that contains the handler is closed, will my app still receive the notification, and the gems be updated?
Any pointers or clues to better help me understand this would be awesome =D
I checked and my service is still running in the background, so this is good :)
But it is taking forever to update, or to receive
does anyone know?
Button bPurchase = (Button) findViewById(R.id.bPurchase);
bPurchase.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CheckBox confirm = (CheckBox) findViewById(R.id.bConfirm);
if (!confirm.isChecked()) {
Toast msg = Toast.makeText(PurchaseActivity.this, "Please Check Confirmation box", Toast.LENGTH_SHORT);
msg.setGravity(Gravity.CENTER, msg.getXOffset() / 2, msg.getYOffset() / 2);
msg.show();
return;
}
if(BillingHelper.isBillingSupported()){
BillingHelper.requestPurchase(mContext, "android.test.purchased");
// android.test.purchased or android.test.canceled or android.test.refunded
} else {
Log.i("","Can't purchase on this device");
}
}
});
}
public Handler mTransactionHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
Log.i("", "Transaction complete");
Log.i("", "Transaction status: "+BillingHelper.latestPurchase.purchaseState);
Log.i("", "Item attempted purchase is: "+BillingHelper.latestPurchase.productId);
if(BillingHelper.latestPurchase.isPurchased()){
long g = GemUpgrades.getGems();
g = g + 1000;
GemUpgrades.setGems(g);
Toast msg1 = Toast.makeText(PurchaseActivity.this, "Received", Toast.LENGTH_SHORT);
msg1.setGravity(Gravity.CENTER, msg1.getXOffset() / 2, msg1.getYOffset() / 2);
msg1.show();
} else {
// Failure
}
};
};
SO I discovered that i was not receiving my calls because I forgot to set the Handler as the Handler. Also It seemed it updated outside the activity, and pretty quick too. But would it still update if the app has been closed before it gets its updat

Splash screen with background tasks

I am trying to make my application launcha splash screen for 5 seconds while initializing various web services in the background. Here is my code:
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Splash screen view
setContentView(R.layout.splashscreen);
final SplashScreen sPlashScreen = this;
// The thread to wait for splash screen events
mSplashThread = new Thread()
{
#Override
public void run()
{
try {
synchronized(this){
// Wait given period of time or exit on touch
wait(5000);
}
}
catch(InterruptedException ex)
{
}
finally
{
finish();
// Run next activity
Intent intent = new Intent();
intent.setClass(sPlashScreen, Splash_testActivity.class);
startActivity(intent);
stop();
}
}
};
mSplashThread.start();
for (int i=0;i<100;i++)
Log.d("splash test", "initialize web methods");
}
Now what I think should happen is that while the splash screen is displayed, the application should log "initialize web methods."
But what actually happens is that the log is added only after the slash screen disappears.
What am I doing wrong??
Try to do it this way. This tutorial is simple and flexible. This is what you need:
// You initialize _splashTime to any value
// thread for displaying the SplashScreen
Thread splashTread = new Thread() {
#Override
public void run() {
try {
int waited = 0;
while(waited < _splashTime)) {
sleep(100);
waited += 100;
}
}
} catch(InterruptedException e) {
// do nothing
} finally {
finish();
startActivity(new Intent("com.droidnova.android.splashscreen.MyApp"));
stop();
}
}
};
splashTread.start();
Note: This code is adopted from the above url.
Run your Thread Using Handler or AsyncTask.

Categories

Resources