Android: Listener for Boolean change - java

I know that there is a lot of examples, but I can't still make it work.
I need to monitor Boolean value, which change to True, when phone is connected to proper wifi.
Wifi connection and check is done in second thread. Maybe there is problem? I've tried many solutions, and can't get it done.
Wrapper class for variable:
import java.util.ArrayList;
import java.util.List;
public class ConnectivityStatus {
private Boolean status = Boolean.FALSE;
private ConnectivityListener listener;
public Boolean getStatus(){
return status;
}
public void setStatus(Boolean status){
this.status = status;
if(status) {
listener.onChange();
}
}
public void addConnectivityListener(ConnectivityListener l) {
this.listener = l;
}
interface ConnectivityListener{
void onChange();
}
}
MainActivity:
public class MainActivity extends AppCompatActivity {
...
private ConnectivityStatus mConnectionStatus;
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
mConnectionStatus = new ConnectivityStatus();
...
connectButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startLoadingScreen();
connectToCamera(mWifiManager);
new Thread(new Runnable() {
public void run() {
long startTime = System.currentTimeMillis();
for(int i = 0; i<=6; i++) {
mConnectionStatus.setStatus(checkWifiSsid(mWifiManager, startTime));
if(mConnectionStatus.getStatus()) {
break;
}
}
}
});
}
});
mConnectionStatus.addConnectivityListener(new ConnectivityStatus.ConnectivityListener() {
#Override
public void onChange(){
openWebView();
}
});
}

I didn't notice earlier but, yes, you're missing something from your threading. You're creating a new thread but you're not telling it to start:
new Thread(new Runnable(){
public void run(){
// Optionally, you can also use log messages for debugging
Log.d("MY_LOG_TAG", "Some message to look for in the log.");
// ...
}
}).start(); // Make sure to tell it to start

Related

Updating main thread from new Runnable class [duplicate]

This question already has answers here:
Running code in main thread from another thread
(17 answers)
Closed 5 years ago.
I'm trying to dynamically update an android LinearLayout in the main thread.
Unfortunately I'm having a lot of trouble ascertaining anything from the tutorials online. None of them seem to provide a complete picture of how to communicate between threads.
My idea is something like this:
public class MainActivity extends AppCompatActivity {
private LinearLayout layout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
layout = new LinearLayout(this);
setContentView(layout);
Updater updater = new Updater();
Thread workerThread = new Thread(updater);
//somehow update layout
The updater class would look something like this:
public class Updater implements Runnable {
private int count = 0;
public Updater() {}
#Override
public void run()
{
for (int i = 0; i < 10; i ++){
try {
count++;
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
I know I need a Handler in order to communicate messages between the threads, but I don't know how to set that up.
I would like to avoid anonymous classes, and dynamically create new TextViews whenever Updater has a new message.
create WorkerThreadListener interface:
public interface WorkerThreadListener {
void onUpdate(int counter);
}
Change your Updater class:
public class Updater implements Runnable {
private final WorkerThreadListener mWorkerThreadListener;
private final Handler mHandler;
private int count = 0;
public Updater(final WorkerThreadListener workerThreadListener) {
this.mWorkerThreadListener = workerThreadListener;
this.mHandler = new Handler();
}
#Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
count++;
mHandler.post(new Runnable() {
#Override
public void run() {
mWorkerThreadListener.onUpdate(count);
}
});
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Change MainActivity class:
public class MainActivity extends AppCompatActivity {
private LinearLayout layout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
layout = new LinearLayout(this);
setContentView(layout);
Updater updater = new Updater(new WorkerThreadListener() {
#Override
public void onUpdate(int counter) {
//update layout here
}
});
Thread workerThread = new Thread(updater);
workerThread.start();
}
}
Hi please check my below answer hope it helps you.
public class ProgressTestActivity extends Activity {
private ProgressBar progress;
private TextView text;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
progress = (ProgressBar) findViewById(R.id.progressBar1);
text = (TextView) findViewById(R.id.textView1);
}
public void startProgress(View view) {
// do something long
Runnable runnable = new Runnable() {
#Override
public void run() {
for (int i = 0; i <= 10; i++) {
final int value = i;
doFakeWork();
progress.post(new Runnable() {
#Override
public void run() {
// here you can add any view or anyof your logic which is related to UI put it into here.
text.setText("Updating");
progress.setProgress(value);
}
});
}
}
};
new Thread(runnable).start();
}
// Simulating something timeconsuming
private void doFakeWork() {
SystemClock.sleep(5000);e.printStackTrace();
}
}
Other ways are also possible.if you have any doubt please comment below post i will explain you in details.
If you just want to use a tick timer and set progress to ui thread . You can use CountDownTimer.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private TextView textView;
private CountDownTimer countDownTimer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new);
textView = (TextView) findViewById(R.id.textView);
findViewById(R.id.b2).setOnClickListener(this);
}
public void processData() {
countDownTimer = new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
textView.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
textView.setText("done!");
}
}.start();
}
#Override
protected void onStop() {
super.onStop();
if (countDownTimer != null) {
countDownTimer.cancel();
}
}
#Override
public void onClick(View v) {
processData();
}
}
Apart from that to post a callback on UI thread you can use Handler .
Handler mainThreadHandler = new Handler(Looper.getMainLooper());
mainThreadHandler.post(new Runnable() {
#Override
public void run() {
}
});

IOIOActivity and AppCompactActivity

I'm not experienced in Java development and migrating from Eclipse. I don't know how to use the nested classes in my case where I need to extend AppCompactActivity and IOIOActivity. Considering, I have another inner class Looper already extending another class. The code below isn't running what is inside Testing class. Can someone help me about how to execute my inner class, which is Testing class.
My code:
public class MainActivity extends AppCompatActivity {
private class Testing extends IOIOActivity {
private ToggleButton button_;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button_ = (ToggleButton) findViewById(R.id.toggleButton);
}
class Looper extends BaseIOIOLooper {
/** The on-board LED. */
private DigitalOutput led_;
#Override
protected void setup() throws ConnectionLostException {
showVersions(ioio_, "IOIO connected!");
led_ = ioio_.openDigitalOutput(0, true);
enableUi(true);
}
#Override
public void loop() throws ConnectionLostException, InterruptedException {
led_.write(!button_.isChecked());
Thread.sleep(100);
}
#Override
public void disconnected() {
enableUi(false);
toast("IOIO disconnected");
}
#Override
public void incompatible() {
showVersions(ioio_, "Incompatible firmware version!");
}
}
#Override
protected IOIOLooper createIOIOLooper() {
return new Looper();
}
private void showVersions(IOIO ioio, String title) {
toast(String.format("%s\n" +
"IOIOLib: %s\n" +
"Application firmware: %s\n" +
"Bootloader firmware: %s\n" +
"Hardware: %s",
title,
ioio.getImplVersion(IOIO.VersionType.IOIOLIB_VER),
ioio.getImplVersion(IOIO.VersionType.APP_FIRMWARE_VER),
ioio.getImplVersion(IOIO.VersionType.BOOTLOADER_VER),
ioio.getImplVersion(IOIO.VersionType.HARDWARE_VER)));
}
private void toast(final String message) {
final Context context = this;
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
});
}
private int numConnected_ = 0;
private void enableUi(final boolean enable) {
// This is slightly trickier than expected to support a multi-IOIO use-case.
runOnUiThread(new Runnable() {
#Override
public void run() {
if (enable) {
if (numConnected_++ == 0) {
button_.setEnabled(true);
}
} else {
if (--numConnected_ == 0) {
button_.setEnabled(false);
}
}
}
});
}
}
}
Thankss
I found my answer and I would like to share it with you all for the future. This is for starting a new IOIOActivity in Android Studio. IOIO developers haven't written the official IOIO code for AppCompactActivity yet. After couple of days trying, its finally tested and working with IOIO led.
Create a new Class file called AppCompactIOIOActivity (I just like that name) in your package. Note: all credits to Ytai. IOIO code from App507
public class AppCompactIOIOActivity extends AppCompatActivity implements IOIOLooperProvider {
private final IOIOAndroidApplicationHelper helper_ = new IOIOAndroidApplicationHelper(this, this);
public AppCompactIOIOActivity() {
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.helper_.create();
}
protected void onDestroy() {
this.helper_.destroy();
super.onDestroy();
}
protected void onStart() {
super.onStart();
this.helper_.start();
}
protected void onStop() {
this.helper_.stop();
super.onStop();
}
#SuppressLint("WrongConstant")
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if((intent.getFlags() & 268435456) != 0) {
this.helper_.restart();
}
}
protected IOIOLooper createIOIOLooper() {
throw new RuntimeException("Client must override one of the createIOIOLooper overloads!");
}
public IOIOLooper createIOIOLooper(String connectionType, Object extra) {
return this.createIOIOLooper();
}
}
Then in your MainActivity
public class MainActivity extends AppCompactIOIOActivity {
private ToggleButton button_;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button_ = (ToggleButton) findViewById(R.id.toggleButton);
}
class Looper extends BaseIOIOLooper {
/** The on-board LED. */
private DigitalOutput led_;
#Override
protected void setup() throws ConnectionLostException {
showVersions(ioio_, "IOIO connected!");
led_ = ioio_.openDigitalOutput(0, true);
enableUi(true);
}
#Override
public void loop() throws ConnectionLostException, InterruptedException {
led_.write(!button_.isChecked());
Thread.sleep(100);
}
#Override
public void disconnected() {
enableUi(false);
toast("IOIO disconnected");
}
#Override
public void incompatible() {
showVersions(ioio_, "Incompatible firmware version!");
}
}
#Override
protected IOIOLooper createIOIOLooper() {
return new Looper();
}
private void showVersions(IOIO ioio, String title) {
toast(String.format("%s\n" +
"IOIOLib: %s\n" +
"Application firmware: %s\n" +
"Bootloader firmware: %s\n" +
"Hardware: %s",
title,
ioio.getImplVersion(IOIO.VersionType.IOIOLIB_VER),
ioio.getImplVersion(IOIO.VersionType.APP_FIRMWARE_VER),
ioio.getImplVersion(IOIO.VersionType.BOOTLOADER_VER),
ioio.getImplVersion(IOIO.VersionType.HARDWARE_VER)));
}
private void toast(final String message) {
final Context context = this;
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
});
}
private int numConnected_ = 0;
private void enableUi(final boolean enable) {
// This is slightly trickier than expected to support a multi-IOIO use-case.
runOnUiThread(new Runnable() {
#Override
public void run() {
if (enable) {
if (numConnected_++ == 0) {
button_.setEnabled(true);
}
} else {
if (--numConnected_ == 0) {
button_.setEnabled(false);
}
}
}
});
}
}
Don't forget to add your resources and dependances from IOIO developers. Good luck!

AsyncTask data communication with nested Classes

I have a specific scenario and I need your help.
I'm trying to build an App in Android that involves network communication.
I am using AsyncTask for the http POST requests.
I have another class called Proxy (not a good one.. will be changed) which holds different kinds of functionalities (registerUser, setUserName, getUserPermission...)
And Of course, I have an Activity.
My Activity holds an instance of Proxy class.
My goal, is to push a button in the activity, it will call a method from Proxy class, which in its turn calls the AsyncTask's execute() method that actually run the http POST.
I was wondering how to get the data from AsyncTask's onPostExecute to my activity.
What I have in mind is to have an interface in AsyncTask, which will be implemented in Proxy class, and another interface in Proxy class which will be implemented in my Activity class.
Roll the data all the way to my Activity.
I want to hear your thoughts about whether this is the way to go, or another approach is preffered.
Thanks a lot for your help.
Adding some code
public class RegisterActivity extends FragmentActivity implements Proxy.OnProxyHttpPostResponseListener {
private Proxy proxy;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
this.proxy = new Proxy();
this.proxy.setHttpPostResponseListener(this);
}
#Override
public void onProxyHttpPostResponse(String response) {
//Do something when http post returns
}
}
public class Proxy {
public interface OnProxyHttpPostResponseListener {
void onProxyHttpPostResponse(String response);
}
private OnProxyHttpPostResponseListener httpPostResponseListener;
public void setHttpPostResponseListener(OnProxyHttpPostResponseListener listener) {
this.httpPostResponseListener = listener;
}
private class HttpPostAsync extends AsyncTask<Pair<String, ArrayList<Pair<String, String>>>, Void, String> {
#Override
protected String doInBackground(Pair<String, ArrayList<Pair<String, String>>>... params) {
return this.httpPost(params[0].first, params[0].second);
}
protected void onPostExecute(String response) {
httpPostResponseListener.onProxyHttpPostResponse(response);
}
}
If you're just needing HTTP POST functionality then an AsyncTask might not be the best choice. AsyncTask really shines if you need to get progress updates as the task is executing (with onProgressUpdate(Progress... progress)). If you'd like to use AsyncTask nonetheless, iroiroys' reply should help.
A bit more simply, you could just use a Handler thread straight up. Something like this:
public class HandlerExampleActivity extends Activity {
private Button postButton;
private Button getButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler_example);
backgroundThread = new BackgroundThread();
backgroundThread.start();
postButton = (Button) findViewById(R.id.button_post);
postbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
backgroundThread.post("DATA_HERE");
}
});
getButton = (Button) findViewById(R.id.button_get);
getbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
backgroundThread.get("URL_HERE");
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
backgroundThread.exit();
}
private class BackgroundThread extends Thread {
private Handler backgroundHandler;
public void run() {
Looper.prepare();
backgroundHandler = new Handler();
Looper.loop();
}
public void post(DataType data) {
backgroundHandler.post(new Runnable() {
#Override
public void run() {
// pull data and do the POST
uiMsg = uiHandler.obtainMessage(POST_COMPLETE, whatever_data_passing_back, 0, null);
uiHandler.sendMessage(uiMsg);
}
});
}
public void get(URL data) {
backgroundHandler.post(new Runnable() {
#Override
public void run() {
// GET data
uiMsg = uiHandler.obtainMessage(GET_COMPLETE, whatever_data_passing_back, 0, null);
uiHandler.sendMessage(uiMsg);
}
});
}
public void exit() {
backgroundHandler.getLooper().quit();
}
}
private final Handler uiHandler = new Handler() {
public void handleMessage(Message msg) {
switch(msg.what) {
case POST_COMPLETE:
// handle it
break;
case GET_COMPLETE:
// handle it
break
case MESSAGE_BACK_TO_UI_THREAD:
// do something
break;
case OPERATION_FAIL:
// oh no!
break;
case OPERATION_SUCCESS:
// yay!
break;
}
}
};
}
I suggest you try Handler and Handler.Callback.
Below I made it simple example..
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
public class MainActivity extends Activity implements Callback {
Handler handler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler = new Handler(this);
Proxy proxy = new Proxy(handler);
proxy.foo();
}
private class Proxy {
Handler handler;
public Proxy(Handler handler) {
this.handler = handler;
}
private void foo() {
new myAsync().execute();
}
private class myAsync extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
Message msg = handler.obtainMessage();
msg.obj = result;
handler.sendMessage(msg);
}
}
}
#Override
public boolean handleMessage(Message msg) {
// Handle Message here!
return false;
}
}

Android: Why does my String value not persist when I rotate Android device? However the countdown portion does

I am extending the Application class to do 2 things. 1) Make onPause() stop the CounterThread until onResume() is pressed. 2) To make the threads continue working while I change orientation of the phone from portrait mode to landscape. Both of the above statements work, however the MakingFileThread when it returns a string value to set the TextView does not persist the orientation changes. Help!!
public class MainActivity extends Activity {
private TextView mText;
private EditText mUserInput;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mText = (TextView)findViewById(R.id.text);
mUserInput = (EditText)findViewById(R.id.userInput);
}
#Override
public void onPause(){
super.onPause();
MyApplication app = (MyApplication)getApplication();
app.pause(null);
}
#Override
public void onResume(){
super.onResume();
MyApplication app = (MyApplication)getApplication();
app.resume(this);
}
public void button_handler(View v){
String val = mUserInput.getText().toString();
String file = "myfile.txt";
MyApplication app = (MyApplication)getApplication();
app.MakeFileThread(val,file);
app.startCounterThread();
}
public void updateCountDown(final int seconds){
String secondText = String.valueOf(seconds);
mText.setText(secondText);
}
public void updateFileOutput(final String userText){
mText.setText(userText);
}
}
public class CounterApplication extends Application {
private MainActivity currentActivity = null;
private CounterThread myThread;
public synchronized void resume(MainActivity update){
this.currentActivity = update;
myThread.interrupt();
}
public synchronized void pause(MainActivity update){
this.currentActivity = update;
myThread.interrupt();
}
public synchronized void update(final long seconds){
Runnable notifyAction = new Runnable(){
public void run(){
if(currentActivity != null){
currentActivity.updateResult(seconds);
}
}
};
currentActivity.runOnUiThread(notifyAction);
}
public void onCreate(){
super.onCreate();
myThread = new CounterThread();
myThread.start();
}
private class CounterThread extends Thread{
private long seconds = 0;
private boolean running = false;
#Override
public void run(){
while(true){
try{
Thread.sleep(running?1000:100000);
}
catch(InterruptedException e){
running = !running;
}
if(interrupted()){
running = !running;
}
if(running){
update(++seconds);
}
}
}
}
}
I am not sure, this might help you, add the following line in your manifest file for the activities you need to work in both portrait and landscape:
android:configChanges="orientation|screenSize"

cant connect to facebook with a network thread

I need to connect to facebook so I use a Tread when using the network. but I have a problem:
Thread t = new Thread(new Runnable() {
#Override
public void run() {
FacebookConnectTask task = new FacebookConnectTask("facebookId", "token", "email", facebookGender,0, 0);
task.setOnPreExecuteListener(this);
task.setOnDoneListener(this);
task.execute();
}
});
t.start();
}
I cant do
task.setOnPreExecuteListener(this);
task.setOnDoneListener(this);
eclipse gives me this error: "The method setOnDoneListener(Task.OnDoneListener) in the type Task is not applicable for the arguments (new Runnable(){})"
How can i fix this?
Thanks!
You've changed context's by being in a Thread your in an Annoyomous class, this is now your annonomous class and not the outer class.
Try this (pun intended):
task.setOnPreExecuteListener(YourOuterClass.this);
task.setOnDoneListener(YourOuterClass.this);
i.e.
public class YourClass implements OnDoneListener {
public doFacebook(){
new Thread(new Runnable(){
#Override
public void run(){
task.setOnDoneListener(YourClass.this);
}
}.start();
}
#Override
public void onDone(){
}
}
or alternatively pull your Threaded class out:
public class DoSomething implements Runnable {
private final OnDoneListener listener;
public DoSomething(OnDoneListener listener){
this.listener = listener;
}
#Override
public void run(){
FacebookConnectTask task = ... ;
task.setOnDoneListener(listener);
}
}
public class YourActivity extends Activity implements OnDoneListener {
public void onCreate(Bundle b){
new Thread(new DoSomething(this)).start();
}
#Override
public void onDone(){
// Tada
}
}
A further step if you wanted to be cooler is create your own interface and keep all the Facebook stuff in the runnable class:
public class DoSomething implements Runnable, OnDoneListener {
public interface OnFacebookFinished {
void onFacebookFinished();
}
private final OnFacebookFinished listener;
public DoSomething(OnFacebookFinished listener){
this.listener = listener;
}
#Override
public void run(){
FacebookConnectTask task = ... ;
task.setOnDoneListener(this);
}
#Override
public void onDone(){
if(listener != null){
listener.onFacebookFinished();
}
}
}
public class YourActivity extends Activity implements OnFacebookFinished {
#Override
public void onCreate(Bundle b){
new Thread(new DoSomething(this)).start();
}
#Override
public void onFacebookFinished(){
// Tada
}
}

Categories

Resources