How do I executed a function for specific seconds - android

So basically, I want to stream data from bluetooth but with on-off mode. Each on & off mode happened for a specific amount of time, i.e 5 seconds.
So,
I need to put a function to executed for a 5 seconds and then executed another function inside a button click method. But my code below doesn't work as it should be.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnOn = (Button) findViewById(R.id.btnOn); // button LED ON
btnOff = (Button) findViewById(R.id.btnOff); // button LED OFF
btnStart = (Button) findViewById(R.id.btnStart);
txtArduino = (TextView) findViewById(R.id.txtArduino); // for display the received data from the Arduino
h = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case RECIEVE_MESSAGE: // if receive massage
byte[] readBuf = (byte[]) msg.obj;
String strIncom = new String(readBuf, 0, msg.arg1); // create string from bytes array
sb.append(strIncom); // append string
int endOfLineIndex = sb.indexOf("\r\n"); // determine the end-of-line
if (endOfLineIndex > 0) { // if end-of-line,
String sbprint = sb.substring(0, endOfLineIndex); // extract string
sb.delete(0, sb.length()); // and clear
txtArduino.setText("Data from Arduino: " + sbprint); // update TextView
btnOff.setEnabled(true);
btnOn.setEnabled(true);
}
//Log.d(TAG, "...String:"+ sb.toString() + "Byte:" + msg.arg1 + "...");
break;
}
};
};
btAdapter = BluetoothAdapter.getDefaultAdapter(); // get Bluetooth adapter
checkBTState();
btnOn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
btnOn.setEnabled(false);
bluetoothConnect();
}
});
btnOff.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
btnOff.setEnabled(false);
bluetoothDisconnect();
}
});
btnStart.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
bluetoothDisconnect();
//Starts from here the code doesn't work
//I want to perform these functions over and over
while (true){
//I want method executed for 5 seconds here
h.postDelayed(new Runnable() {
#Override
public void run(){
bluetoothConnect();
}
}, 5000);
//I want method executed for 5 seconds here
h.postDelayed(new Runnable() {
#Override
public void run(){
bluetoothDisconnect();
}
}, 5000);
}
}
});
}

You can try the following way...
private boolean canExecute;
private void callYourMethod() {
canExecute = true;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
canExecute = false;
}
}, 5000);
yourMethodToExecuteForFiveSeconds();
}
private void yourMethodToExecuteForFiveSeconds() {
// Your code goes here
if (canExecute) {
//This will be true for five seconds only.
yourMethodToExecuteForFiveSeconds();
}
}

Related

Thread dosen't interrupted

I'm work on crate server and android client
but thread doesn't interrupted by android client
My android Client has request for the RoomList from server
and Server receive, Client Accept
and fill in my ListView used the Adapter
here's problem if Click backButton,
than RoomListAcitivity was close and thread was stop
but thread dosen't stop just alive in my app
first Enter has work on sucessfully
but Press BackButton on and re-Enter this Activity
MyApp just White, No Action
how can i stop this thread?
(and sorry for my English skill...)
i tried .interrupt() method , and handler.removeMessages(0)
but failed thread keep alive
upload this full java code just in case...
ListView roomList;
RoomAdapter roomAdapter;
Socketservice ss;
String msg,rtitle;
String msgs[];
String list[];
Thread listthread,EnterRoomThread,removeV;
boolean staterun = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_room);
roomList = findViewById(R.id.roomList);
roomAdapter = new RoomAdapter();
listthread = new Thread() {
public void run(){
ss.out.println("163|");
ss.out.println("100|");
try {
while (staterun == true) {
msg = ss.in.readLine();
handler.post(new Runnable() {
public void run() {
msgs = msg.split("\\|");
String protocol = msgs[0];
switch (protocol) {
case "163":
list = msgs[1].split(",");
for (int i = 0; i < list.length; i++) {
String list1[] = list[i].split("-");
String listT = list1[0];
int listC = Integer.parseInt(list1[1]);
int listI = Integer.parseInt(list1[2]);
roomAdapter.CreateRoom(listI, listT, listC);
}
roomList.setAdapter(roomAdapter);
msg = "";
msgs = null;
break;
case "200":
Intent i = new Intent(getApplicationContext(), GameWaitingActivity.class);
i.putExtra("tname", rtitle);
staterun = !staterun;
Toast.makeText(getApplicationContext(),""+listthread.isAlive(),Toast.LENGTH_SHORT).show();
startActivity(i);
finish();
break;
case "201":
Toast.makeText(getApplicationContext(), "방이 꽉 찼습니다.", Toast.LENGTH_SHORT).show();
break;
}
}
});
}
} catch (IOException e) {
}
}
};
listthread.start();
roomList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Room item = (Room) roomList.getItemAtPosition(position);
rtitle=item.getTitle();
EnterRoomThread = new Thread() {
public void run() {
ss.out.println("200|" + rtitle);
EnterRoomThread.interrupt();
}
};
EnterRoomThread.start();
}
});
}
Handler handler = new Handler();
#Override
public void onBackPressed() {
removeV = new Thread() {
public void run(){
ss.out.println("101|");
removeV.interrupt();
}
};
removeV.start();
handler.removeMessages(0);
staterun = false;
listthread.interrupt();
Toast.makeText(getApplicationContext(),""+listthread.isAlive(),Toast.LENGTH_SHORT).show();
finish();
}
}
Go ahead with this, write this inside run() method
//use this boolean value to keep track.
boolean shouldRunFlag = true;
while (shouldRunFlag) {
try {
Thread.sleep(10);
//Do your work............
} catch (Exception e) {
e.printStackTrace();
Log.v(TAG, "Interrupted Exception caught");
// change the flag, so that while loop can be broken.
shouldRunFlag = false;
Log.v(TAG, "run: breaking the loop");
break;
}
}
and this is how you interrupt and clean the thread
private void interrupt(Thread currentThread) {
Log.i(TAG, "interrupt");
if (currentThread != null) {
Thread dummyThread = currentThread;
dummyThread.interrupt();
currentThread = null;
}
}

android, disabling the save button for one hour

i am trying to disable the save button for exactly 1 hour, before the user can save data again. I have come up with some code but since i am still really new to programming i am kind of stuck and any help would be appritiated.
The problem is the button does not lock when i click save.
public void AddData(){
gumb_poslji.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Activity activity = getActivity();
Calendar calander = Calendar.getInstance();
Integer cDay = calander.get(Calendar.DAY_OF_MONTH);
Integer cHour = calander.get(Calendar.HOUR_OF_DAY);
Integer cDayOfTheWeek = calander.get(Calendar.DAY_OF_WEEK)-1;
Integer cMonth = calander.get(Calendar.MONTH)+1;
int seekBarProgressValue = seekBar.getProgress();
String strI = String.valueOf(seekBarProgressValue);
String poslji_data = strI;
boolean pregled_vnosa = myDb.insertData(poslji_data,cHour,cDay,cDayOfTheWeek,cMonth);
if (pregled_vnosa==true)
Toast.makeText(activity, "Vnos uspešen",Toast.LENGTH_LONG).show();
else
Toast.makeText(activity, "Vnos neuspešen!!!",Toast.LENGTH_LONG).show();
}
});
gumb_poslji.setEnabled(true);
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(3600000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
gumb_poslji.setEnabled(false);
}
});
}
}).start();
}
Handler mHandler= new Handler();
static Runnable mUpdateTimeTask = new Runnable() {
public void run() {
gumb_poslji.setEnabled(false);
mHandler= .removeCallbacks(mUpdateTimeTask);
}
};
mHandler.postDelayed(this, 3600000);

Using handler to change ui, still "only the original thread that created a view hierarchy can touch its views." error

I have two threads, two handlers. From thread i check a random number and send result to handle to update ui. But i am getting the error "only the original thread that created a view hierarchy can touch its views.". I searched some articles, they tell to use handler. I am doing that, yet can not avoid the errors.
After some checking, I found that it crashes when A sends the result. In case of B, it works
Also, can i use one handler for two thread?
public class MainActivity extends Activity implements View.OnClickListener{
Button start;
TextView status_B, status_A;
Boolean isRunning;
Thread Athread, Bthread;
int a, b;
Handler a_Handler, b_Handler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Initialize variables
start = (Button) findViewById(R.id.button);
start.setOnClickListener(this);
status_B = (TextView) findViewById(R.id.textView);
status_A = (TextView) findViewById(R.id.textView1);
a_Handler = new Handler() {
public void handleMessage(Message msg)
{
int number = msg.getData().getInt("number");
String winner = msg.getData().getString("winner");
start.setEnabled(true);
isRunning = false;
status_A.setText(winner + number);
}
};
b_Handler = new Handler() {
public void handleMessage(Message msg)
{
int number = msg.getData().getInt("number");
String winner = msg.getData().getString("winner");
start.setEnabled(true);
isRunning = false;
status_B.setText(winner + number);
}
};
}
#Override
protected void onStart() {
super.onStart();
isRunning = false;
}
#Override
public void onClick(View v) {
start.setEnabled(false);
status_B.setText("Guessing...");
if (!isRunning)
{
Athread = new Thread(new Runnable() {
#Override
public void run() {
while (isRunning)
{
try
{
Athread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
a = (int) (Math.random()*1000);
System.out.println("a "+ a);
if(a%7 == 0) {
isRunning = false;
Bundle bundle = new Bundle();
bundle.putString("winner", "A");
bundle.putInt("number", a);
Message msg = a_Handler.obtainMessage();
msg.setData(bundle);
a_Handler.handleMessage(msg);
}
}
}
});
Bthread = new Thread(new Runnable() {
#Override
public void run() {
while(isRunning)
{
try
{
Bthread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
b = (int) (Math.random()*1000);
System.out.println("b "+ b);
if(b%7 == 0) {
isRunning = false;
Bundle bundle = new Bundle();
bundle.putString("winner", "B");
bundle.putInt("number", b);
Message msg = b_Handler.obtainMessage();
msg.setData(bundle);
b_Handler.sendMessage(msg);
}
}
}
});
isRunning = true;
Athread.start();
Bthread.start();
}
}
}
You need put your code to modify views on UI thread:
a_Handler = new Handler() {
public void handleMessage(Message msg)
{
final int number = msg.getData().getInt("number");
final String winner = msg.getData().getString("winner");
runOnUiThread(new Runnable() {
#Override
public void run() {
start.setEnabled(true);
status_A.setText(winner + number);
}
});
isRunning = false;
}
};
b_Handler = new Handler() {
public void handleMessage(Message msg)
{
final int number = msg.getData().getInt("number");
final String winner = msg.getData().getString("winner");
runOnUiThread(new Runnable() {
#Override
public void run() {
start.setEnabled(true);
status_B.setText(winner + number);
}
});
isRunning = false;
}
};

Pass a variable from public void OnCreate

I wanted to know how can I pass a variable from private void to OnCreate?
public final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
switch (msg.arg1) {
case BluetoothChatService.STATE_CONNECTED:
setStatus(getString(R.string.title_connected_to, mConnectedDeviceName));
mConversationArrayAdapter.clear();
break;
case BluetoothChatService.STATE_CONNECTING:
setStatus(R.string.title_connecting);
break;
case BluetoothChatService.STATE_LISTEN:
case BluetoothChatService.STATE_NONE:
setStatus(R.string.title_not_connected);
break;
}
break;
case MESSAGE_WRITE:
byte[] writeBuf = (byte[]) msg.obj;
// construct a string from the buffer
String writeMessage = new String(writeBuf);
mConversationArrayAdapter.add("Me: " + writeMessage);
break;
case MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
// construct a string from the valid bytes in the buffer
String readMessage = new String(readBuf, 0, msg.arg1);
int k=Integer.parseInt(readMessage.replaceAll("[\\D]",""));
mConversationArrayAdapter.add(readMessage);
Toast.makeText(getApplicationContext(),"ciao"+k ,Toast.LENGTH_SHORT).show();
break;
case MESSAGE_DEVICE_NAME:
// save the connected device's name
mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
Toast.makeText(getApplicationContext(), "Connected to "
+ mConnectedDeviceName, Toast.LENGTH_SHORT).show();
break;
case MESSAGE_TOAST:
Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),
Toast.LENGTH_SHORT).show();
break;
}
}
};
This is OnCreate:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mvc = (Button) findViewById(R.id.button1);
mvc.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
new Thread(new Runnable() {
public void run() {
while (progressStatus < 1000) {
Random r = new Random();
int i1 = r.nextInt(1000);
if (i1 > progressStatus){
progressStatus = i1;
}
else {
progressStatus = progressStatus;
}
// Update the progress bar and display the current value in the text view
handler.post(new Runnable() {
public void run() {
progressBar.setProgress(progressStatus);
}
});
try {
// Sleep for 200 milliseconds. Just to display the progress slowly
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
});
res = (Button) findViewById(R.id.button2);
res.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
progressBar.setProgress(0);
progressStatus=0;
}
});
if(D) Log.e(TAG, "+++ ON CREATE +++");
// Set up the window layout
progressBar = (ProgressBar) findViewById(R.id.progressBar1);
// Get local Bluetooth adapter
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// If the adapter is null, then Bluetooth is not supported
if (mBluetoothAdapter == null) {
Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
finish();
return;
}
}
I pass the variable k, is there a method? or I have to go to a public int? I do not know how to solve. Thank you in advance!
Umm, why not make k a Global Variable?
Add int k inside starting of your class
For example :
...
public class MainActivity extends Activity {
int k;
//onCreate and other methods
}
...
Change
int k = =Integer.parseInt (readMessage.replaceAll.replaceAll("[\\D]",""));
to
k = =Integer.parseInt(readMessage.replaceAll.replaceAll("[\\D]",""));
as you've already made k an integer.
Then you can use k anywhere in your class

Android backgroud thread cannot change textview through handler

I am unable to understand why my background thread is not able to change the content of textView(txtName) after screen orientation is changed.
If I make txtname as static it works, but without static it does not work. It just has its initial value not getting updated by the background thread.
private TextView txtName;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.screen2);
txtName = (TextView) findViewById(R.id.txtName);
TextView txtEmail = (TextView) findViewById(R.id.txtEmail);
Button btnClose = (Button) findViewById(R.id.btnClose);
Button btnBack = (Button) findViewById(R.id.btnBack);
Intent i = getIntent();
// Receiving the Data
String name = i.getStringExtra("name");
String email = i.getStringExtra("email");
// String data = i.getStringExtra("data");
// Displaying Received data
txtName.setText("HI");
txtEmail.setText(email);
// Binding Click event to Button
btnClose.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
//Closing SecondScreen Activity
Thread background = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 30; i++) {
try {
Thread.sleep(1000);
Message msg = new Message();
Bundle b = new Bundle();
b.putString("My Key", "My Value: " + String.valueOf(i));
msg.setData(b);
// send message to the handler with the current message handler
handler.sendMessage(msg);
Log.e("Error", "IN THREAD");
} catch (Exception e) {
Log.d("Error", e.toString());
}
}
}
});
background.start();
}
});
btnBack.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
Intent returnIntent = getIntent();
returnIntent.putExtra("returnResult","i want to back page.");
setResult(RESULT_OK,returnIntent);
finish();
}
});
}
Handler handler = new Handler() {
public void handleMessage(Message msg) {
// get the bundle and extract data by key
Bundle b = msg.getData();
String key = b.getString("My Key");
txtName.setText( "Item " + key);
txtName.setVisibility(View.VISIBLE);
Log.e("TEST MESSAGE", txtName.getText().toString());
}
};
Try runOnUiThread:
#Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
Handler handler = new Handler() {
public void handleMessage(Message msg) {
runOnUiThread(new Runnable() {
#Override
public void run() {
// get the bundle and extract data by key
Bundle b = msg.getData();
String key = b.getString("My Key");
txtName.setText( "Item " + key);
txtName.setVisibility(View.VISIBLE);
Log.e("TEST MESSAGE", txtName.getText().toString());
}
});
}
};
}
Create your OnClickListener as a fixed Class and then apply it as:
MyListener myListener = new MyListener();
btnClose.setOnClickListener(myListener);
In this way the txtName variable musn't be set as final
Your UI can only be updated by the UI thread. Try something like this to ask your UI thread to update the interface as soon as possible. This way i think you can avoid using a handler.
btnClose.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
//Closing SecondScreen Activity
Thread background = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 30; i++) {
try {
Thread.sleep(1000);
final String val = "My Value: " + String.valueOf(i);
// ask UI thread to make the changes as soon as possible
txtName.post(new Runnable(){
public void run(){
txtName.setText( "Item " + val);
txtName.setVisibility(View.VISIBLE);
});
} catch (Exception e) {
Log.d("Error", e.toString());
}
}
}
});
background.start();
}
});

Categories

Resources