Activity A starts Activity B, how to close Activity A - android

I seem to be here quite a bit!!
I know this question has been asked already on here and in other places and I have tried to implement answers posted but it's not working for me
I have an activity, (Activity A) based on an if statement, it starts Activity B. My problem is Activity A keeps running, and in Activity A I play an alarm and vibrate the phone, both keep going and while Activity B starts and runs (I can see in the logcat) it never comes to the front because of that.
Here is my code of my if statement
if (dynamicActivation > threshold) {
alarmHandler.post(new Runnable() {
public void run() {
int duration = Toast.LENGTH_SHORT;
CharSequence text = "YOUR CHILD HAS TRAVELLED OUTSIDE PROXIMITY";
Context context = getApplicationContext();
proximityAlert = Toast.makeText(context, text,
duration);
proximityAlert.show();
alarmSound.start();
//v.vibrate(3000);
try {
Thread.sleep(5000);
openMaps();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
And here is the code from the openMaps() function
public void openMaps() {
Class track = ParentReal.class;
Intent PRealIntent = new Intent(this, track);
PRealIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(PRealIntent);
ANN.this.finish();
}
I should add in case it causes problems is that there is another activity, a menu, once a button is clicked it opens Activity A...should I be closing the menu activity as well once I start Activity A?
Thanks in advance!
EDIT
I'm not to sure why the downvote, but I'll try and explain my problem, I have three activities A, B, C. A is my menu, upon button click it starts Activity B, in activity B, based on the outcome of an if statement Activity C is started.
The problem is C runs, the processes can be see in the logcat but doesn't open. B continues to play the alarm and vibrate and then the phone stalls and the alarm and vibrate continue. I have the code for the if statement above and the code for the openMaps() function as well, this is called based on the outcome of the if, in which I try to open Activity C and close B
I hope that is clearer ;)
ANOTHER EDIT
ok, I have an idea what the problem is, I just don't know how to solve it. I have a thread, inside that thread is an infinate while loop, inside this infinite while loop I check the distance between two coordinates (i want them constantly updating).
The problem is, variables I have declared globally are initialized within the loop so I have to run my if statement within that, to access those...I tried using a boolean 'test' that if it's true execute the if statement then set test to false but that doesn't work I'm afraid.
here's my code
Thread dist = new Thread(new Runnable() {
public void run() {
while (true) {
child = new Location("point A");
child.setLatitude(Clatitude);
child.setLongitude(Clongitude);
parent = new Location("point B");
parent.setLatitude(Platitude);
parent.setLongitude(Plongitude);
distance = child.distanceTo(parent);
DisRound = 550;
dynamicActivation = DisRound * weight;
try {
Thread.sleep(1000);
if (test)
{
if(dynamicActivation > threshold)
{
finish();
new Timer().schedule(new MapsTimer(), 5000);
test = false;
}
Log.d("ACTIVATION", Boolean.toString(test));
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
dist.start();
and heres the MapsTimer task
private class MapsTimer extends TimerTask {
#Override
public void run() {
runOnUiThread(new Runnable() {
public void run() {
int duration = Toast.LENGTH_SHORT;
CharSequence text = "YOUR CHILD HAS TRAVELLED OUTSIDE PROXIMITY";
Context context = getApplicationContext();
proximityAlert = Toast.makeText(context, text, duration);
proximityAlert.show();
alarmSound.start();
openMaps();
}
});
}
}
I am calling finish within the if statement. I've been at this for 10 hrs now and it's melting my head, I'm sure it's simple, but only when you know how!!
Regards,
Gary

Your question and your code are not clear, but in general after the code which switch you to activity B you should call finish() which finish activity A

Thank you everyone for all your help, I sorted it myself. I just inserted a break in the while loop. As follows:
Thread dist = new Thread(new Runnable() {
public void run() {
while (true) {
child = new Location("point A");
child.setLatitude(Clatitude);
child.setLongitude(Clongitude);
parent = new Location("point B");
parent.setLatitude(Platitude);
parent.setLongitude(Plongitude);
distance = child.distanceTo(parent);
// DisRound = Math.round(distance * 100.0) / 100.0;
DisRound = 550;
dynamicActivation = DisRound * weight;
try {
Thread.sleep(1000);
if(dynamicActivation > threshold)
{
proximityAlert.show();
alarmSound.start();
new Timer().schedule(new MapsTimer(), 5000);
break;
}
Log.d("ACTIVATION", Boolean.toString(test));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
finish();
}
});
dist.start();
So once the alert is shown, the alarm is played, and the mapsTimer is called, it breaks out of the infinite loop, it isn't needed any more and then I call finish();

Related

Stop method from executing on button press

I have written a menu for an application with multiple buttons. Two of these buttons trigger two separate Bluetooth methods. The problem is that on multiple quick presses of these buttons the app crashes because each method is attempting to manage the Bluetooth connection (while another may close that connection). I have tried setting a variable 'true' while any of the methods is running and checking for that but it does not work. I am unsure of whether the system runs each method concurrently in different threads or if it enqueues the methods .
The question is how exactly do I stop a button press to run a method while another method is executing? I don't need it enqueued after the executing one finishes, I only need it blocked.
EDIT: Added code of one of the methods below, as requested (the other one is identical, with the exception of two strings, which are irrelevant in this context):
public void lock(View button_lock) {
if(ok)
return;
if (btAdapter == null) {
Context context = getApplicationContext();
CharSequence text = "Bluetooth not supported!";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
return;
}
else if (address == null) {
Context context = getApplicationContext();
CharSequence text = "Please pair your phone with SmartLock.";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
return;
}
if (!btAdapter.isEnabled()) {
btAdapter.enable();
ok=true;
}
mHandler.postDelayed(new Runnable() {public void run() {
BluetoothDevice device = btAdapter.getRemoteDevice(address);
ParcelUuid[] uuids = device.getUuids();
BluetoothSocket mmSocket;
try {
mmSocket = device.createRfcommSocketToServiceRecord(uuids[0].getUuid());
mmSocket.connect();
OutputStream out = mmSocket.getOutputStream();
InputStream in = mmSocket.getInputStream();
out.write("1".getBytes());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
in.close();
out.close();
mmSocket.close();
in = null;
out = null;
mmSocket = null;
} catch (IOException e) {
e.printStackTrace();
}
}}, 1000);
Context context = getApplicationContext();
CharSequence text = "Bike locked!";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
mHandler.postDelayed(new Runnable() {public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
btAdapter.disable();
ok=false;
}}, 2000);
}
As you already tried it with a boolean, a semaphore could do the trick here.
You can't solve this problem by disabling the button in onClick(), because of the way Android's event system works. When the user presses the button, a "click" event is queued to the event queue. If the user presses the button twice in rapid succession (especially on low-end devices or when the UI thread is busy), 2 "click" events will be inserted into the queue. You cannot prevent this.
What you need to do is to remember that you've processed the "click" event and ignore any that arrive after that (until you want to allow the user to click again). It sounds like you have already tried this. Please post your code so we can see what is wrong.
After seeing your code I have the following input:
If mHandler has been created on the main (UI) thread, you have a problem You have code here that is doing network I/O and sleeping. You absolutely can not do that on the main (UI) thread. Make sure this stuff is running in a background thread. To do this, either create your own Thread or make sure that your Handler is created on a background thread (see HandlerThread as one example).
Before you call postDelayed(), set a boolean variable running to true. This flag should be cleared to false when the posted Runnable completes. To make sure of this, wrap your whole run() method in a try/catch and clear the variable in a finally block.
In lock(), first check if the boolean variable running is true. If it is, you should just return immediately, which will ignore click events that occur when you aren't ready for them.
Try this:
bluetoothMethod();
bluetoothButton.setEnabled(false);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
bluetoothButton.setEnabled(true);
}
}, duration);
(duration in milis)

Timer not working in app

I have written schedule task by using timer. It is working fine withing single activity.But when i am going to another activity it is not working.My intention is to send data to the server some particular time interval. I am giving the code snippet. I am sorry for the format.
private void login()
{
try {
EditText userNameET = (EditText)findViewById(R.id.userName);
EditText passwordET = (EditText)findViewById(R.id.password);
String userName = userNameET.getText().toString();
String password = passwordET.getText().toString();
boolean isLoginOK = isValidUser(userName, password);
String autoSynchStrVal = "";
String autoSyncFreqStr = "";
long autoSyncFreqInMiliSec = 3600000; // default 1 hrs
if (isLoginOK) {
//added by anirban
CommonUtils.IS_NEW_VERSION_AVAILABLE = isNewVersionAvailable();
CommonUtils.IS_NEW_Notification_AVAILABLE = isNewNotificationAvailable();
autoSynchStrVal = CommonUtils.getPolicyValue(appInstance, "IS_MOBI_AUTO_SYNCH_REQ", 0, 0);
if(autoSynchStrVal != null && !"".equals(autoSynchStrVal) && "1".equals(autoSynchStrVal)){
//boolean isAllTransactionsUploaded = false;
// boolean isAllTransactionsUploaded = VersionCheckingActivity.isAllTransactionsUploaded();
// boolean isMobiEligibleForAutoSync = UploadDownload.isMobiEligibleForAutoSync(appInstance ,isAllTransactionsUploaded);
// if(isMobiEligibleForAutoSync){
autoSyncFreqStr = CommonUtils.getPolicyValue(appInstance, "MOBI_AUTO_SYNCH_FREQUENCY", 0, 0);
if(autoSyncFreqStr != null && !"".equals(autoSyncFreqStr)){
autoSyncFreqInMiliSec = (long) (Double.valueOf(autoSyncFreqStr) * 60 * 60 * 1000); // in millisecond
}
/* boolean isMobiEligibleForAutoSync = false;
try {
isMobiEligibleForAutoSync = UploadDownload.isMobiEligibleForAutoSync(appInstance ,
VersionCheckingActivity.isAllTransactionsUploaded());
if(isMobiEligibleForAutoSync){
_doSynch();
}
} catch (UDBAccessException e) {
e.printStackTrace();
} */
myTimer = new Timer();
myTimer.schedule(new TimerTask() {
#Override
public void run() {
ULoginActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// here we are checking again for eligibility for auto synch
boolean isMobiEligibleForAutoSync = false;
try {
isMobiEligibleForAutoSync = UploadDownload.isMobiEligibleForAutoSync(appInstance ,
VersionCheckingActivity.isAllTransactionsUploaded());
Log.d("inside Run : ", "before Synch");
if(isMobiEligibleForAutoSync){
_doSynch();
Log.d("inside Run : ", "after Synch");
}
} catch (UDBAccessException e) {
e.printStackTrace();
}
}
});
}
}, 1000, autoSyncFreqInMiliSec); //here interval is autoSyncFreqInMiliSec
}
endAction(RESULT_LOGIN_OK, null); // it will finish the activity
} else {
// showing login error
TextView login_msg = (TextView)findViewById(R.id.login_screen_msg);
login_msg.setTextAppearance(this, R.style.error_msg);
//login_msg.setTextColor(Color.RED);
login_msg.setText("Login failed.");
}
} catch (UDBAccessException e) {
UUIHandlers.showErrorMessage(this, e.getMessage());
}catch (Exception e) {
UUIHandlers.showErrorMessage(this, e.getMessage());
}
}
To make it work when you leave the current activity, you have to run that code of snippet on the background service.
As you are executing on the current Activity it runs the code for the first time, but as you leave the activity the code wont be triggered itself unless it is registered to a background service.
Here and here you have examples on how to use them
If you want to execute something after some time, even when your activity is not currently in the foreground, you can use the AlarmManager.
Note: The Alarm Manager is intended for cases where you want to have your application code run at a specific time, even if your application is not currently running. For normal timing operations (ticks, timeouts, etc) it is easier and much more efficient to use Handler.
If you want to periodically send information to a server, I suggest you use a Service or an IntentService.
A Service is an application component representing either an application's desire to perform a longer-running operation while not interacting with the user or to supply functionality for other applications to use.
You can find a good example using a LocalService also here.
Finally got the solution .
Now from Async task( different thread), You are trying to insert data in the database which is locked by UI thread. This will throw an exception because the first write has a lock on the db.
If you hold your timer in a field of your activity (Activity subclass) it will probably go away once you launch another activity. Consider moving your timer to service (Service subclass). This will hold your timer going regardless of your activity flow.
Read this for reference about services:
https://developer.android.com/guide/components/services.html

If I finish an activity and call it again, it's attribute values still remain inside thread (RunOnUiThread)

In this case, I have 2 activities. I'm on Activity 1 and go to Activity 2. The application works as intended.
The problem starts when I go back to Activity 1, and start Activity 2 again.
See code below:
public class ScreenWActivity extends SerialComActivity {
private static final String tag = "ScreenWActivity";
private TextView mReception, m_tvDate, mtvPesoPercent, mtvState;
public String mCommand = null;
public int mActualProcess, mNextProcess;
private Commands mLastCommand;
public SettingsGlobal mSettings;
public int mAttempts = 0;
public long mStartTime, mTimeout;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_W);
this.mSettings = new SettingsGlobal(this); // get global settings
this.mtvState = (TextView) findViewById(R.id.tv_state); // label to update the current state
startSerialConnection(); // open serial port and start connection. inherited from SerialComActivity (the upper class)
this.mTimeout = 10; // timeout for commands response in seconds
this.mNextProcess = 1; // the next step in the process, its updated in the stepN() methods
this.mActualProcess = 1; // current step in the processo
this.mLastCommand = Commands.OPEN_DOOR; // the last command I've sent, to know what to expect in return
this.executeWorkflow(mNextProcess); // starts the workflow
}
private void step1(){
this.mtvState.setText("Closing door."); // update status
this.writeSerial(Commands.OPEN_DOOR.command("080").getBytes()); // sends the command to the outputstream, the external device reads the command, execute it and respond back
this.mNextProcess = 2; // the next step in the process is 2
this.mActualProcess = 1; // just tracking
this.mLastCommand = Commands.OPEN_DOOR;
startCounting(); // starts the timout, I've sent the command, now I wait for an answer
}
private void step2(){
this.mtvState.setText("Testando peso das balanças 1.");
this.writeSerial(Commands.GET_W.command().getBytes()); // get weight from weighing-machine
mLastCommand = Commands.GET_W; // the last command i sent i requested the weight - now I know what to expect
mNextProcess = 3; // next step in the sequence in case everything goes according to plan
this.mActualProcess = 2; // tracking
startCounting(); // starting timeout to get an answer
}
private void step3(){...}
private void step4(){...}
private void step5(){...}
private void step6(){...}
#Override
protected void writeSerial(byte[] buffer){...}
public void startCounting(){
mStartTime = System.currentTimeMillis();
timerHandler.postDelayed(timerRunnable, 0);
}
public void stopCounting(){
timerHandler.removeCallbacks(timerRunnable);
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
stopCounting();
timerRunnable = null;
if(this.mSerialPort != null)
this.mSerialPort.close();
this.mSerialPort = null;
if(AppConfig.DEBUG) Log.i(tag, "finishing!");
finish();
super.onDestroy();
}
public void executeWorkflow(int step) {
switch(step){
case 1:
step1();
break;
case 2:
step2();
break;
case 3:
step3();
break;
case 4:
step4();
break;
case 5:
step5();
break;
case 6:
step6();
break;
}
}
protected boolean validateReturn(String resposta) {
/// we check the command we've sent and the response we're given. if it matches, then we return true, else false
}
// overrided from SerialComActivity, called when the external equipment sends a message to us
// ITS CALLED WHEN THERE IS INPUT FROM THE EXTERNAL EQUIPMENT
#Override
protected void onDataReceived(final byte[] buffer, final int size) {
runOnUiThread(new Runnable() {
public void run() {
stopCounting(); // we remove the callbacks from the timeout thread
if( validateReturn(new String(buffer, 0, size).trim()) ){ // we check if the response is good
executeWorkflow(mNextProcess); // if its good, we move to the next step
}else{
mtvState.setText("invalid return"); // if not we message the user
executeWorkflow(mActualProcess); // we try again
}
}
});
}
// RESPONSIBLE FOR THE TIMEOUT
// the code below was created intending to implement a timeout timer for waiting a response from the external device
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
#Override
public void run() {
long millis = System.currentTimeMillis() - mStartTime;
long seconds = (millis / 1000);
timerHandler.postDelayed(this, 500);
if(mTimeout - seconds == 0 ){
mAttempts += 1;
if(mAttempts == 3){ // we make 3 attempts to get a response, if it is the third, we quit trying and give error
mAttempts = 0;
mtvState.setText("Could not communicate.");
stopCounting(); // we end the timer
}else{
executeWorkflow(mActualProcess); // if we can still try, we send the command again
}
}
}
};
}
Inside the method onDataReceived(), which is called everytime I get a response from the external equipment, I use the attribute mLastCommand (which indicates the last command I've sent), so this way I know how to validate the response I get.
When I go back to Activity 2, in the class scope the values of the attributes are the same as the ones I've defined in the onCreate() method. In the LogCat I saw that the attributes values are correctly defined as stated in OnCreate.
BUT, when the method onDataReceived (it's inside a Thread in the SerialComActivity class) is called (which is called when I get data from outside) the value of this same attribute mLastCommand is the same as the first time I started the activity, regardless of the value I define for it. As if the the runnable inside RunOnUiThread is still holding the old values from the first time I entered the activity, and outside of it the class has the values I have defined.
It's like having two different attributes with the same name in the ScreenWActivity.
I tried nulling the attributes inside the onDestroy() method, but to no avail.
Below is the code for the SerialComActivity class:
public abstract class SerialComActivity extends Activity{
SerialPort mSerialPort = null;
protected OutputStream mOutputStream;
protected InputStream mInputStream;
protected ReadThread mReadThread;
private class ReadThread extends Thread {
#Override
public void run() {
super.run();
while(!isInterrupted()) {
int size;
try {
byte[] buffer = new byte[64];
if (mInputStream == null) return;
size = mInputStream.read(buffer);
if (size > 0) {
onDataReceived(buffer, size);
}
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}
}
protected void startSerialConnection(){
try {
mSerialPort = new SerialPort(new File("/dev/ttyS2"), 38400, 0);
} catch (SecurityException e) {
// TODO Auto-generated catch block
if(AppConfig.DEBUG)
Log.e("SERIAL", "portopen ERR: " + e.getMessage());
} catch (IOException e) {
// TODO Auto-generated catch block
if(AppConfig.DEBUG)
Log.e("SERIAL", "portopen ERR: " + e.getMessage());
}
mOutputStream = mSerialPort.getOutputStream();
mInputStream = mSerialPort.getInputStream();
/* Create a receiving thread */
mReadThread = new ReadThread();
mReadThread.start();
}
protected abstract void onDataReceived(final byte[] buffer, final int size);
protected abstract void writeSerial(byte[] buffer);
#Override
protected void onDestroy() {
if (mReadThread != null){
mReadThread.interrupt();
if(AppConfig.DEBUG) Log.i("ThreadSerial", "interrupting");
}
if(mSerialPort != null)
mSerialPort.close();
mSerialPort = null;
finish();
super.onDestroy();
}
}
I'm still in the process of learning Java and Android programming, so please forgive me if I'm doing something wrong. I looked up around, and the thing that you can't use variables other than "final" inside the RunOnUiThred came up. But I think it's not the issue, since it works the first time I start the activity.
Try doing your clean up in onPause() instead of onDestroy(), onDestroy() may not be called immediately which means there may be a read conflict on SerialPort. Also if you are already in onDestroy(), calling finish() doesn't really do anything.
Lastly, for a finite resource like SerialPort connection, it's better to put it in a Service.
I'm a newbie in Java, but I think I found out what was happening. The thing is that I asked the wrong question.
The problem is in the mInputStream.read(). As I've come to know, it's a blocking operation. I'm creating a thread that stays blocked in that read() method. After I finish the Activity, (go back to the first one), the thread keeps running. I know that because when a send some information through the serial interface, that thread responds.
So what I did, and it's working for me, altough many people stated that this method is not recommended is use mInputStream.available():
try {
if (mInputStream == null){ Log.i(tag,"returning"); return null ;}
Log.i(tag,"reading");
mEmptyStream = true;
while(mEmptyStream && !mFinish){
Log.i(tag,"input while");
/// checking if there is info, so we don't block the thread
if(mInputStream.available() > 0){
Log.i(tag,"input avail : " + InputStream.available());
//stream not empty
mEmptyStream = false;
size = mInputStream.read(buffer); //
}
}
if (size > 0) {
Log.i(tag,"size > 0 = " + new String(buffer, 0, size));
return new String(buffer,0,size);
}else{
Log.i(tag,"size <= 0");
}
}
Basically I loop using available(). When I finish the activity, in the onPause() method I set the field mFinish to true, this way the thread finds it's way out of execution and can end properly. It's the way I found and it's working so far. I improved the code significantly after the original post, like not running non UI jobs in the RunOnUiThread :)
But I tested it and it's working.

How can I show the toast from the service in the specific activity

I have activity A, from this activity I start activity B, which have a button "ok". When the button is clicked some event happens, this event is processed by the service and the service shows toast in activity B, after that B finished.
The problem is that the Activiti B stops running too fast, and user can't see the toast long enough.
How can I wait while activity A come to the front and shows toast there(in the A)?
You can try this hack..
create a handler in activity B. Show you Toast before hadler & code for returning back to Activity A inside handler run() method.
Handler handler = new Handler();
handler.postDelayed(
new Runnable() {
public void run() {
// Place your code here for returning back to activity A
}
}, 1000);
}
Try this :
Start Activity B as startActivityForResult from Activity A and
then onActivityResult check if the result you are getting from
Activity B is OK
then show up a toast on Activity A.
Tutorial link showing how to use startActivityForResult are given below :
https://www.google.co.in/search?client=ubuntu&channel=fs&q=startactivity+for+result+tutorial+android&ie=utf-8&oe=utf-8&gws_rd=cr&ei=pNU2UtvSD8uGrgfPxYGACg
Try This if It works...
1. Create a Thread t1=new Thread(new Runnable(){
public void run()
{
//first Activity
}
});t1.start();
2. join t1
try
{
t1.join();
}
3. Similarly,create other thread with Second Activity
4. This will make second thread to execute only after First .Giving u the time to view the Toast message
`
I think you want to finish activity B after the the toast dismiss.You can user-defined the toast during seconds.But android doesn't provide any APIs to do this.
We can use reflect to solve this problem.
Suppose you want to finish activity B after the toast showing 10 seconds.
Toast toast = Toast.makeText(this, "ToastMessage", Toast.LENGTH_SHORT);
try {
//get "mTN" field from toast
Field field = toast.getClass().getDeclaredField("mTN");
field.setAccessible(true);
Object obj = field.get(toast);
//get method "show"
Method method = obj.getClass().getDeclaredMethod("show", null);
//show the toast
method.invoke(obj, null);
} catch (Exception e) {}
//dismiss the toast after 10 seconds
new Thread(){
public void run() {
try {
sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
try{
Method method = obj.getClass().getDeclaredMethod("hide", null);
method.invoke(obj,null);
//finish Activity B here
finish();
}
catch (Exception e){}
};
}.start();

Not able to execute loop based on thread.sleep

I'm trying to display a series of images from a specific folder in sdcard - in the form of slideshow. filelist[] contains names of all files present in that directory.
I'm filtering out the images here. Next, thread.sleep(1000) does not seem to have any effect. Only the last image in the directory is displayed after a time of 1000ms. Where am I going wrong? Any other way I could accomplish this?
Maybe I've gone completely wrong. I'm a newbie so plz help.
public class List_imgActivity extends Activity {
/** Called when the activity is first created. */
Bitmap[] bitmapArray = new Bitmap[1000];
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button pf=(Button) findViewById(R.id.pick_button);
pf.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
Intent intent = new Intent("org.openintents.action.PICK_DIRECTORY");
intent.setData(Uri.parse("file:///sdcard"));
intent.putExtra("org.openintents.extra.TITLE", "Please select a folder");
intent.putExtra("org.openintents.extra.BUTTON_TEXT", "Use this folder");
startActivityForResult(intent, 1);
}
});
}
protected void onActivityResult(int requestCode, int recievecode, Intent intent)
{
if (requestCode == 1 )
{
Uri uri = intent.getData();
try {
File f=new File(new URI(uri.toString()));
final String nx=f.toString();
if(f.isDirectory()) {
File filelist[] = f.listFiles();
for(int i=0;i<filelist.length;i++)
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String filename = filelist[i].getName();
int pos = filename.lastIndexOf(".");
String ext = filename.substring(pos);
if(ext.equals(".jpg"))
{
TextView tv1= (TextView) findViewById(R.id.textView1);
tv1.setText(filelist[i].toString());
ImageView iv1=(ImageView) findViewById(R.id.imageView1);
bitmapArray[i] = BitmapFactory.decodeFile(filelist[i].toString());
iv1.setImageBitmap(bitmapArray[i]);
}
}
}
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
In Android behaviour like this will make the UI-Thread sleep. This will freeze the whole UI of the phone your App will look crashed to the user and the System will automatically kill your application after a while.
There is a mechanism to change things in specific time intervalls. You should use this handlers for doing this. Handlers
A handler has a postDelayed and sendMessageDelayed methods that allow you to either build a Runnable that will be executed after a certain time or send a message that must be handled by the implementation of your handler.
The initialization of the handler would look something like this:
showNextImageHandler = new Handler() {
#Override
public void handleMessage(android.os.Message msg) {
showNextImage();
}
};
showNextImageHandler.sendMessageDelayed(showNextImageHandler.obtainMessage(), 1000);
This code creates a new handler that calls the function showNextImage every time it receives a message. I would store the Handler in an instance variable of your activity to send further messages later on. After the handler is created a first empty message is send in a way that will delay the posting of the message 1000 milliseconds. After a second the showNextImage function will be called. In this function you can change the view and if a next image exists you can post another delayed message to trigger another call to the function later on.
U Must synchronise the current object before applying Thread.sleep() method

Categories

Resources