this is the view that crashes when i click start but i dont know why
i think it has something to do with the threding in the bruteForce function
package com.my.app;
import android.app.*;
import android.os.*;
import android.view.*;
import android.view.View.*;
import android.widget.*;
import android.content.*;
import android.graphics.*;
import android.media.*;
import android.net.*;
import android.text.*;
import android.util.*;
import java.util.*;
import java.text.*;
import android.test.*;
import android.view.animation.*;
import android.widget.Button;
public class TestActivity extends Activity {
private LinearLayout linear1;
private TextView original;
private TextView match;
private TextView text;
private Button bstart;
String attempt = new String();
boolean running;
int counter;
private String hash = "";
public String username = new String();
public static String password = "ZZZZZ";
public static char[] charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
private static char[] currentGuess = new char[1];
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
initialize();
initializeLogic();
}
private void initialize() {
linear1 = (LinearLayout) findViewById(R.id.linear1);
original = (TextView) findViewById(R.id.original);
match = (TextView) findViewById(R.id.match);
text = (TextView) findViewById(R.id.text);
bstart = (Button) findViewById(R.id.bstart);
bstart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View _v) {
bruteForce();
}
});
}
private void initializeLogic() {
Intent test = getIntent();
hash = test.getStringExtra("hash");
original.setText(password);
}
public void increment()
{
int index = currentGuess.length - 1;
while (index >= 0)
{
if (currentGuess[index] == charset[charset.length - 1])
{
if (index == 0)
{
currentGuess = new char[currentGuess.length + 1];
Arrays.fill(currentGuess, charset[0]);
break;
}
else
{
currentGuess[index] = charset[0];
index--;
}
}
else
{
currentGuess[index] = charset[Arrays.binarySearch(charset, currentGuess[index]) + 1];
break;
}
}
}
public String toString()
{
return String.valueOf(currentGuess);
}
public void bruteForce()
{
Animation animation = new Animation(){
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
text.setText(attempt);
}
};
animation.setRepeatCount(Animation.INFINITE);
text.startAnimation(animation);
new Thread(){
#Override
public void run() {
running = true;
while(running)
if (attempt.equals(password))
{
text.setText(attempt);
this.stop();
}
attempt = toString();
text.setText(attempt);
increment();
}
}.start();
}
#Override
protected void onStop() {
super.onStop();
running = false;
}
public void BruteForceTest()
{
Arrays.fill(currentGuess, charset[0]);
}
// created automatically
private void ShowMessage(String _s) {
Toast.makeText(getApplicationContext(), _s, Toast.LENGTH_SHORT).show();
}
private int GetRandom(int _minValue ,int _maxValue){
Random random = new Random();
return random.nextInt(_maxValue - _minValue + 1) + _minValue;
}
public ArrayList<Integer> getCheckedItemPositionsToArray(ListView _list) {
ArrayList<Integer> _result = new ArrayList<Integer>();
SparseBooleanArray _arr = _list.getCheckedItemPositions();
for (int _iIdx = 0; _iIdx < _arr.size(); _iIdx++) {
if (_arr.valueAt(_iIdx))
_result.add(_arr.keyAt(_iIdx));
}
return _result;
}
}
Your problem lies here
new Thread(){
#Override
public void run() {
running = true;
while(running)
if (attempt.equals(password))
{
text.setText(attempt);
this.stop();
}
attempt = toString();
text.setText(attempt);
increment();
}
}.start();
You can only update an UI element from the main thread. If you want to do it likes this you need to wrap text.setText(attempt) with a handler that posts it to the main thread. e.g.
new Handler(Looper.getMainLooper()).post(new Runnable(){
void run() {
text.setText(attempt);
}
});
Looper.getMainLooper() (docs) will get the main application thread which the handler then posts the Runnable to .
if (attempt.equals(password))
{
getActivity().runOnUiThread(new Runnable()
{
#Override
public void run()
{
text.setText(attempt);
}
});
this.stop();
}
Similarly wherever you are changing ui elements like setting text or changin colors do it in runOnUithread as I did above.
Related
I'm facing an issue regarding cameraview. Do I have to import something since the error goes "cannot resolve flurgle" for import com.flurgle.camerakit.CameraView;
My permissions in manifest file are already set.
Heres the code using cameraview(taken from "https://blog.mindorks.com/android-tensorflow-machine-learning-example-ff0e9b2654cc.html" )
package com.example.mujtaba.basicai.Machine_Learning;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.mujtaba.basicai.R;
import com.flurgle.camerakit.CameraListener;
import com.flurgle.camerakit.CameraView;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class ImageRecognition extends AppCompatActivity {
private static final int INPUT_SIZE = 224;
private static final int IMAGE_MEAN = 117;
private static final float IMAGE_STD = 1;
private static final String INPUT_NAME = "input";
private static final String OUTPUT_NAME = "output";
private static final String MODEL_FILE = "file:///android_asset/tensorflow_inception_graph.pb";
private static final String LABEL_FILE =
"file:///android_asset/imagenet_comp_graph_label_strings.txt";
private Classifier classifier;
private Executor executor = Executors.newSingleThreadExecutor();
private TextView textViewResult;
private Button btnDetectObject, btnToggleCamera;
private ImageView imageViewResult;
private cameraView cameraView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_recognition);
cameraView = (CameraView) findViewById(R.id.cameraView);
imageViewResult = (ImageView) findViewById(R.id.imageViewResult);
textViewResult = (TextView) findViewById(R.id.textViewResult);
textViewResult.setMovementMethod(new ScrollingMovementMethod());
btnToggleCamera = (Button) findViewById(R.id.btnToggleCamera);
btnDetectObject = (Button) findViewById(R.id.btnDetectObject);
cameraView.setCameraListener(new CameraListener() {
#Override
public void onPictureTaken(byte[] picture) {
super.onPictureTaken(picture);
Bitmap bitmap = BitmapFactory.decodeByteArray(picture, 0, picture.length);
bitmap = Bitmap.createScaledBitmap(bitmap, INPUT_SIZE, INPUT_SIZE, false);
imageViewResult.setImageBitmap(bitmap);
final List<Classifier.Recognition> results = classifier.recognizeImage(bitmap);
textViewResult.setText(results.toString());
}
});
btnToggleCamera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
cameraView.toggleFacing();
}
});
btnDetectObject.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
cameraView.captureImage();
}
});
initTensorFlowAndLoadModel();
}
#Override
protected void onResume() {
super.onResume();
cameraView.start();
}
#Override
protected void onPause() {
cameraView.stop();
super.onPause();
}
#Override
protected void onDestroy() {
super.onDestroy();
executor.execute(new Runnable() {
#Override
public void run() {
classifier.close();
}
});
}
private void initTensorFlowAndLoadModel() {
executor.execute(new Runnable() {
#Override
public void run() {
try {
classifier = TensorFlowImageClassifier.create(
getAssets(),
MODEL_FILE,
LABEL_FILE,
INPUT_SIZE,
IMAGE_MEAN,
IMAGE_STD,
INPUT_NAME,
OUTPUT_NAME);
makeButtonVisible();
} catch (final Exception e) {
throw new RuntimeException("Error initializing TensorFlow!", e);
}
}
});
}
private void makeButtonVisible() {
runOnUiThread(new Runnable() {
#Override
public void run() {
btnDetectObject.setVisibility(View.VISIBLE);
}
});
}
}
I've been trying to test the performance of Realm with large datasets. It seems to perform really well inserting and with queries that result in moderate resultset sizes but as soon as there is a result set that is large it starts impacting the main thread even though the actual writes are running async. I've written a test activity that shows the issue below. A few notes:
Attendee is a model with a primary key of "name" and an indexed integer field of "age".
The view has a text field showing the count, a button that calls reloadData on click, and an element that is interactive (I used a slider) to see skipped frames when using it.
If you change the query for the list so that it's causes a smaller result set (instead of less then change to equalsTo) then the issue goes away.
Is this a bug or am I doing something wrong?
package com.test.ui;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.test.R;
import com.test.model.Attendee;
import io.realm.OrderedRealmCollection;
import io.realm.Realm;
import io.realm.RealmAsyncTask;
import io.realm.RealmRecyclerViewAdapter;
import io.realm.RealmResults;
public class LoginActivity extends AppCompatActivity {
private static final int RECORD_COUNT = 200000;
private static final int TRANSACTION_SIZE = 1000;
private RealmAsyncTask mTask = null;
private RecyclerView mAttendeeList;
private TextView mCountText;
private Button mButton;
private Handler handler;
private Realm mRealm;
private RealmResults<Attendee> mActualList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
mRealm = Realm.getDefaultInstance();
mCountText = (TextView) findViewById(R.id.count_text);
mButton = (Button) findViewById(R.id.button);
handler = new Handler(Looper.getMainLooper());
setCountText((int) mRealm.where(Attendee.class).count());
mActualList = mRealm.where(Attendee.class).lessThan("age", 20).findAllAsync();
mRealm.executeTransactionAsync(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
realm.deleteAll();
setCountText(0);
}
}, new Realm.Transaction.OnSuccess() {
#Override
public void onSuccess() {
mButton.setEnabled(true);
}
}, new Realm.Transaction.OnError() {
#Override
public void onError(Throwable error) {
String text = "Error deleting";
Log.e("ANRTEST", text, error);
Toast.makeText(LoginActivity.this, text, Toast.LENGTH_LONG).show();
}
});
}
private void setCountText(int size) {
mCountText.setText(String.format("Count: %s", size));
}
#Override
protected void onDestroy() {
mActualList = null;
if(mTask != null && !mTask.isCancelled()) {
mTask.cancel();
mTask = null;
}
if(mRealm != null && !mRealm.isClosed()) {
mRealm.close();
}
super.onDestroy();
}
public void loadData(final TimerUtil t) {
Realm.Transaction.OnError onError = new Realm.Transaction.OnError() {
#Override
public void onError(Throwable error) {
mTask = null;
Toast.makeText(LoginActivity.this, "Finished should show now", Toast.LENGTH_LONG).show();
}
};
Realm.Transaction.OnSuccess onSuccess = new Realm.Transaction.OnSuccess() {
#Override
public void onSuccess() {
mTask = null;
int count = (int) mRealm.where(Attendee.class).count();
if (count >= RECORD_COUNT) {
Log.v("ANRTEST", String.format("Finished in %s seconds", t.currentElapsed() / 1000));
mButton.setEnabled(false);
} else {
handler.postDelayed(new Runnable() {
#Override
public void run() {
loadData(t);
}
}, 300);
}
setCountText(count);
}
};
mTask = mRealm.executeTransactionAsync(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
int innerStart = (int) realm.where(Attendee.class).count();
int i = 0;
while (i < TRANSACTION_SIZE && i + innerStart < RECORD_COUNT) {
Attendee attendee = new Attendee();
int innerValue = innerStart + i;
attendee.name = "name " + (innerValue + 1);
attendee.age = innerValue % 50;
realm.insert(attendee);
i++;
}
Log.v("ANRTEST", String.format("Checkpoint %s (%s seconds)", Math.min(innerStart + i, RECORD_COUNT), t.currentElapsed() / 1000));
}
}, onSuccess, onError);
}
public void reloadData(View view) {
//Setup start of process
mButton.setEnabled(false);
final TimerUtil t = TimerUtil.start();
loadData(t);
}
public static class TimerUtil {
private final long mStartTime;
public TimerUtil(long startTime) {
mStartTime = startTime;
}
public static TimerUtil start() {
return new TimerUtil(System.currentTimeMillis());
}
public long currentElapsed() {
return System.currentTimeMillis() - mStartTime;
}
}
}
The issue I am having is that I have created a simple count down timer, using AsyncTasks and using the SetRetainInstance(true) to ensure that even with orientation change the counter updates on the ui.
The issue is that I have an editText that gives me the values for the timer and then should pass them on to the Task to count Down. I must be missing something somewhere because, I cannot seem to get the new value.
This is the code that I am using as the Fragment:
package com.example.app;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.Fragment;
import android.util.Log;
public class TaskFragment extends Fragment {
private static final String TAG = TaskFragment.class.getSimpleName();
String i;
int counter;
Bundle bundle;
static interface TaskCallbacks {
public void onPreExecute();
public void onProgressUpdate(int timer);
public void onCancelled();
public void onPostExecute();
}
private TaskCallbacks mCallbacks;
private DummyTask mTask;
private boolean mRunning;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (!(activity instanceof TaskCallbacks)) {
throw new IllegalStateException("Activity must implement the TaskCallbacks interface.");
}
mCallbacks = (TaskCallbacks) activity;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
bundle=getArguments();
i = bundle.getString("SecValue");
Log.i("VertygoEclypse - TaskFragment-onCreate", i);
counter=Integer.parseInt(i);
}
#Override
public void onDestroy() {
super.onDestroy();
cancel();
}
public void start() {
if (!mRunning) {
bundle=getArguments();
i=bundle.getString("SecValue");
mTask = new DummyTask();
Log.i("VertygoEclypse - TaskFragment - start", i);
mTask.execute();
mRunning = true;
} else{
mTask.cancel(true);
}
}
public void cancel() {
if (mRunning) {
mTask.cancel(true);
mTask = null;
mRunning = false;
}
}
public boolean isRunning() {
return mRunning;
}
private class DummyTask extends AsyncTask<Void, Integer, Void> {
#Override
protected void onPreExecute() {
mCallbacks.onPreExecute();
mRunning = true;
counter=Integer.parseInt(i);
Log.i("Vertygo Eclypse - AsyncTask - onPreExecute", i);
}
#Override
protected Void doInBackground(Void... ignore) {
do {
publishProgress(counter);
SystemClock.sleep(1000);
counter=counter-1;
if(isCancelled()){
mTask.cancel(true);
break;
}
} while (counter>0);
return null;
}
#Override
protected void onProgressUpdate(Integer... timer) {
mCallbacks.onProgressUpdate(timer[0]);
}
#Override
protected void onCancelled() {
mCallbacks.onCancelled();
mRunning = false;
}
#Override
protected void onPostExecute(Void ignore) {
mCallbacks.onPostExecute();
mRunning = false;
}
}
}
That being said I have Log.i set up at a number of spots the onCreate, the start, the pre-execute and the post-execute.
The following excerpt from the logcat shows that some of the values show the entered text, but the start and preexecute are holding the old values:
01-17 17:37:12.383 10261-10261/com.example.app I/VertygoEclypse - replaceFrag﹕ 35
01-17 17:37:12.383 10261-10261/com.example.app I/VertygoEclypse - replaceFrag﹕ 35
01-17 17:37:12.383 10261-10261/com.example.app I/Vertygo Eclypse - MainActivity - replaceFrag﹕ 35
01-17 17:37:12.403 10261-10261/com.example.app I/VertygoEclypse - TaskFragment-onCreate﹕ 35
01-17 17:37:17.247 10261-10261/com.example.app I/VertygoEclypse - TaskFragment - start﹕ 15
01-17 17:37:17.259 10261-10261/com.example.app I/Vertygo Eclypse - AsyncTask - onPreExecute﹕ 15
I am also using Bundle to transfer the text from an EditText to the fragment and using getString() to get the value based on a key.
Below is the MainActivity so far.
package com.example.app;
import android.annotation.TargetApi;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import java.util.concurrent.TimeUnit;
public class MainActivity extends FragmentActivity implements TaskFragment.TaskCallbacks {
private static final String TAG = MainActivity.class.getSimpleName();
private static final String KEY_CURRENT_PROGRESS = "current_progress";
private static final String KEY_PERCENT_PROGRESS = "percent_progress";
private static final String TIME_COUNT = "time_count";
private TaskFragment mTaskFragment;
private ProgressBar mProgressBar;
private TextView mPercent, tv1;
private Button mButton;
private EditText secentered;
public String sample;
Bundle bundl;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1 = (TextView) findViewById(R.id.textView1);
secentered = (EditText) findViewById(R.id.valueentered);
mButton = (Button) findViewById(R.id.task_button);
initialfrag();
mButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (mTaskFragment.isRunning()) {
mButton.setText("Start");
mTaskFragment.cancel();
replaceFrag();
} else {
mButton.setText("Cancel");
mTaskFragment.start();
}
}
});
if (savedInstanceState != null) {
tv1.setText(savedInstanceState.getString(TIME_COUNT));
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(TIME_COUNT, tv1.getText().toString());
}
#Override
public void onPreExecute() {
mButton.setText(getString(R.string.cancel));
Toast.makeText(this, R.string.task_started_msg, Toast.LENGTH_SHORT).show();
}
#Override
public void onProgressUpdate(int timer) {
long timelong = timer*1000;
String tval = getDurationBreakdown(timelong);
tv1.setText(tval);
}
#Override
public void onCancelled() {
mButton.setText(getString(R.string.start));
tv1.setText("0 seconds");
mTaskFragment.cancel();
replaceFrag();
Toast.makeText(this, R.string.task_cancelled_msg, Toast.LENGTH_SHORT).show();
}
#Override
public void onPostExecute() {
mButton.setText(getString(R.string.start));
tv1.setText("Completed");
mTaskFragment.cancel();
replaceFrag();
Toast.makeText(this, R.string.task_complete_msg, Toast.LENGTH_SHORT).show();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_trigger_config_change:
recreate();
return true;
}
return super.onOptionsItemSelected(item);
}
public static String getDurationBreakdown(long secondstobreak) {
if(secondstobreak < 0)
{
throw new IllegalArgumentException("Duration must be greater than zero!");
}
long hours = TimeUnit.MILLISECONDS.toHours(secondstobreak);
secondstobreak-=TimeUnit.HOURS.toMillis(hours);
long minutes = TimeUnit.MILLISECONDS.toMinutes(secondstobreak);
secondstobreak-=TimeUnit.MINUTES.toMillis(minutes);
long seconds = TimeUnit.MILLISECONDS.toSeconds(secondstobreak);
secondstobreak-=TimeUnit.SECONDS.toMillis(seconds);
StringBuilder sb = new StringBuilder(64);
if(hours<10){
sb.append("0"+hours);
}else {
sb.append(hours);
}
sb.append(" : ");
if(minutes<10){
sb.append("0"+minutes);
}else{
sb.append(minutes);
}
sb.append(" : ");
if(seconds<10){
sb.append("0"+seconds);
} else {
sb.append(seconds);
}
sb.append(" remaining");
return (sb.toString());
}
public void replaceFrag(){
Bundle bundle = new Bundle();
String tester2 = secentered.getText().toString();
Log.i("VertygoEclypse - replaceFrag", tester2);
if(tester2.matches("")){
bundle.putString("SecValue", "15");
} else {
Log.i("VertygoEclypse - replaceFrag", tester2);
bundle.putString("SecValue", tester2);
}
FragmentTransaction rfm = getSupportFragmentManager().beginTransaction();
rfm.remove(mTaskFragment);
rfm.detach(mTaskFragment);
TaskFragment mTaskFragment = new TaskFragment();
Log.i("Vertygo Eclypse - MainActivity - replaceFrag", tester2);
mTaskFragment.setArguments(bundle);
rfm.add(mTaskFragment, "task").commit();
}
public void initialfrag(){
bundl = new Bundle();
String tester = secentered.getText().toString();
Log.i("VertygoEclypse - initialFrag", tester);
if(tester.matches("")){
bundl.putString("SecValue", "15");
} else{
Log.i("VertygoEclypse - initialFrag", tester);
bundl.putString("SecValue", tester);
}
FragmentManager fm = getSupportFragmentManager();
mTaskFragment = (TaskFragment) fm.findFragmentByTag("task");
if (mTaskFragment == null) {
mTaskFragment = new TaskFragment();
mTaskFragment.setArguments(bundl);
fm.beginTransaction().add(mTaskFragment, "task").commit();
}
}
}
I know that the value is being passed to the fragment, however I am not certain if the AsyncTask or the Fragment is being replaced or refreshed. What I would like Ideally is to have the AsyncTask killed and a new one created using the new value from the Bundle.
Any help would be greatly appreciated.
Ok all it seems that I have stumbled upon the answer. the issue was th int counter, validcounter; it seems that without the static in front of it, the variable creates it's own instance of it. so with the following static int counter, validcounter; the issue is resolved.
thanks for the sounding board.
regards
cchinchoy
I created a simple crossfade image class for use in my app. But... i have an error i can't fix due to lack of knowledge. I found this post This Handler class should be static or leaks might occur: IncomingHandler but i have no clue how to fix this in my class. It is a very straightforward class. Create, initialize and start to use it.
I hope someone can help me fix this warning and while we are at it, some hints and tips on my code or comments are very welcome too ;)
MainActivity.java
package com.example.crossfadeimage;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
Xfade xfade = new Xfade();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// INIT(current activity, image id's, time between fades, fade speed)
xfade.init(this, new int[]{ R.id.image1, R.id.image2, R.id.image3 }, 3000, 500);
xfade.start();
}
}
Xfade.java
package com.example.crossfadeimage;
import android.app.Activity;
import android.os.Handler;
import android.os.Message;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.ImageView;
public class Xfade {
private Activity activity;
// Handler
private Handler handlerTimer = new Handler();
private static final int UPDATE_STUFF_ON_DIALOG = 999;
private int updateTime;
private Animation fadeIn;
private Animation fadeOut;
public int[] xfadeImages;
public int xfadeCounter = 1;
public void init(Activity thisActivity, int[] images, int time,
int animationSpeed) {
activity = thisActivity;
xfadeImages = images;
updateTime = time;
// Set Animations
fadeIn = new AlphaAnimation(0, 1);
fadeIn.setDuration(animationSpeed);
fadeOut = new AlphaAnimation(1, 0);
fadeOut.setDuration(animationSpeed);
// Hide all images except the first
// which is always visible
for (int image = 1; image < xfadeImages.length; image++) {
ImageView thisImage = (ImageView) activity
.findViewById(xfadeImages[image]);
thisImage.setVisibility(4);
}
}
public void start() {
handlerTimer.removeCallbacks(taskUpdateStuffOnDialog);
handlerTimer.postDelayed(taskUpdateStuffOnDialog, updateTime);
}
private Runnable taskUpdateStuffOnDialog = new Runnable() {
public void run() {
Message msg = new Message();
msg.what = UPDATE_STUFF_ON_DIALOG;
handlerEvent.sendMessage(msg);
// Repeat this after 'updateTime'
handlerTimer.postDelayed(this, updateTime);
}
};
private Handler handlerEvent = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case UPDATE_STUFF_ON_DIALOG: {
crossFade();
}
break;
default: {
super.handleMessage(msg);
}
break;
}
}
};
public void crossFade() {
if (xfadeCounter == 0) {
ImageView lastImage = (ImageView) activity
.findViewById(xfadeImages[xfadeImages.length - 1]);
lastImage.setVisibility(4);
}
if (xfadeCounter < xfadeImages.length) {
ImageView thisImage = (ImageView) activity
.findViewById(xfadeImages[xfadeCounter]);
thisImage.setVisibility(0);
thisImage.startAnimation(fadeIn);
xfadeCounter++;
} else {
// Hide all images except the first
// before fading out the last image
for (int image = 1; image < xfadeImages.length; image++) {
ImageView thisImage = (ImageView) activity
.findViewById(xfadeImages[image]);
thisImage.setVisibility(4);
}
// Fadeout
ImageView lastImage = (ImageView) activity
.findViewById(xfadeImages[xfadeImages.length - 1]);
lastImage.startAnimation(fadeOut);
// LastImage is faded to alpha 0 so it doesn't have to be hidden
// anymore
xfadeCounter = 1;
}
}
}
This allows you to modify views and have your handler set to static.
package com.testing.test;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;
public class MainActivity extends Activity implements Runnable {
private static final int THREAD_RESULT = 1000;
private TextView mTextView;
private static Handler mHandler;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.text);
}
#Override
protected void onResume() {
super.onResume();
mHandler = new CustomHandler(this);
new Thread(this).start();
}
#Override
public void run() {
// Do some threaded work
// Tell the handler the thread is finished
mHandler.post(new Runnable() {
#Override
public void run() {
mHandler.sendEmptyMessage(THREAD_RESULT);
}
});
}
private class CustomHandler extends Handler {
private MainActivity activity;
public CustomHandler(MainActivity activity) {
super();
this.activity = activity;
}
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case THREAD_RESULT:
activity.mTextView.setText("Success!");
break;
}
}
}
}
I am trying to update my existing Android Application to work on both mobile phone and Tablet. So I want to change the Activity class to fragment. The below is my activity class.
Individual Activity class
package FXPAL.Unity.Android;
import FXPAL.Unity.Android.Person.CalendarEntry;
import FXPAL.Unity.Android.Person.IM;
import FXPAL.Unity.Android.Person.Person;
import FXPAL.Unity.Android.Person.Status;
import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;
public class IndividualViewActivity extends Activity {
private static final String DB_TAG = "IndividualView";
//private static final String DB_TAG_PING = "ShowPingView";
private TextView displayName, presence, phoneNum, cellNum, emailAddr, btLocation, calInfo, status;
private ImageView userImage;
private Person personToDisplay;
private String phoneNumber, cellNumber, username, emailAddress;
private TableRow fxpalIMrow, skypeIMrow, msLiveIMrow, gtalkIMrow;
private TableLayout imTable;
private TextView fxpalIMstatus, skypeIMstatus, msLiveIMstatus, gtalkIMstatus, pingText;
private Button nudgeButton, pingButton, clearPingButton, calendarButton;
private LinearLayout pingLayout, pingNudgeButtonLayout;
protected String numToCall, numtype;
private DatabaseHelper db;
//private int pingID = -1;
private UnityMobileApp appCtx;
private static final int DIALOG_CALL_OFFICE_ID = 0;
private static final int DIALOG_CALL_CELL_ID = 1;
protected static final int DIALOG_VIEW_CALENDAR = 2;
private static final int REFRESH_MENU_ID = 0;
protected static final String OFFICE = "office";
private static final String CELL = "cell";
protected static final int MESSAGE_CONNECTION_ERROR_TOAST = 0;
//private static final String DEBUG_TAG = "unity.IndividualViewActivity";
private final Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_CONNECTION_ERROR_TOAST:
Toast.makeText(IndividualViewActivity.this, Consts.CONNECTION_ERROR_MESSAGE, Toast.LENGTH_SHORT).show();
break;
}
}
};
private SharedPreferences prefs;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//doBindService();
setContentView(R.layout.individual_view);
db = new DatabaseHelper(this);
appCtx = (UnityMobileApp) getApplication();
prefs = PreferenceManager.getDefaultSharedPreferences(this);
//Setup View
displayName = (TextView)findViewById(R.id.individualName);
presence = (TextView)findViewById(R.id.individualPresence);
userImage = (ImageView)findViewById(R.id.individualUserImage);
phoneNum = (TextView)findViewById(R.id.individualPhone);
cellNum = (TextView)findViewById(R.id.individualCellPhone);
emailAddr = (TextView)findViewById(R.id.individualEmail);
btLocation = (TextView)findViewById(R.id.individualLocation);
calInfo = (TextView)findViewById(R.id.individualCalendarInfo);
status = (TextView)findViewById(R.id.individualStatus);
fxpalIMrow = (TableRow)findViewById(R.id.im_fxpal);
skypeIMrow = (TableRow)findViewById(R.id.im_skype);
msLiveIMrow = (TableRow)findViewById(R.id.im_ms_live);
gtalkIMrow = (TableRow)findViewById(R.id.im_gtalk);
fxpalIMstatus = (TextView)findViewById(R.id.im_status_fxpal);
skypeIMstatus = (TextView)findViewById(R.id.im_status_skype);
msLiveIMstatus = (TextView)findViewById(R.id.im_status_ms_live);
gtalkIMstatus = (TextView)findViewById(R.id.im_status_gtalk);
imTable = (TableLayout)findViewById(R.id.individualIMStatus);
nudgeButton = (Button)findViewById(R.id.individual_nudge_button);
pingButton = (Button) findViewById(R.id.individual_ping_button);
calendarButton = (Button)findViewById(R.id.individualViewCalendarButton);
pingText = (TextView)findViewById(R.id.individualPingText);;
clearPingButton = (Button) findViewById(R.id.individualClearPingButton);
pingLayout = (LinearLayout)findViewById(R.id.individualPingInfo);
pingNudgeButtonLayout = (LinearLayout)findViewById(R.id.individual_nudge_ping_layout);
calendarButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
showDialog(DIALOG_VIEW_CALENDAR);
db.viewEvent(DB_TAG + ":CalendarDialog", username);
}
});
nudgeButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
startActivity(new Intent(IndividualViewActivity.this, SendNudgeActivity.class)
.putExtra(Consts.EXTRA_USERNAME, personToDisplay.getUsername())
.putExtra(Consts.EXTRA_DISPLAY_NAME, personToDisplay.getDisplayName()));
}
});
pingButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
startActivity(new Intent(IndividualViewActivity.this, SendPingActivity.class)
.putExtra(Consts.EXTRA_USERNAME, personToDisplay.getUsername())
.putExtra(Consts.EXTRA_DISPLAY_NAME, personToDisplay.getDisplayName()));
}
});
}
public void onPause(){
super.onPause();
}
public void onDestroy(){
super.onDestroy();
//doUnbindService();
db.close();
}
public void onResume(){
super.onResume();
Intent mIntent = getIntent();
username = mIntent.getStringExtra(Consts.EXTRA_USERNAME);
if(username.equalsIgnoreCase(prefs.getString(Consts.PREF_USERNAME, "")))
pingNudgeButtonLayout.setVisibility(View.GONE);
else
pingNudgeButtonLayout.setVisibility(View.VISIBLE);
personToDisplay = appCtx.getEveryone().get(username);
updateView();
updateInfo();
if (personToDisplay == null || personToDisplay.getCalendar() == null ||
personToDisplay.getCalendar().getCalendar().size() == 0)
calendarButton.setEnabled(false);
else
calendarButton.setEnabled(true);
db.viewEvent(DB_TAG, username);
pingLayout.setVisibility(View.GONE);
//}
}
private void updateInfo(){
ServerHelper.RequestListener listener = new ServerHelper.RequestListener() {
public void onCompleted(ServerHelper.Request request) {
if (request.isUnauthorized())
startActivity(new Intent(IndividualViewActivity.this, LoginActivity.class));
else if (request.isSuccess()) {
Person.PersonHelper.getEveryoneAsync(IndividualViewActivity.this, appCtx.everyone, null, request.getResponseString(),
new Runnable() {
public void run () {
personToDisplay = appCtx.everyone.get(username);
updateView();
}
});
}
}
};
ServerHelper.appCtx = appCtx;
ServerHelper.getStatus (prefs, listener);
}
private void updateView(){
if (personToDisplay == null)
return;
displayName.setText(personToDisplay.getDisplayName());
presence.setText(personToDisplay.getPresenceState());
Status mStatus = personToDisplay.getStatus();
if( mStatus!= null && mStatus.toString().length()>0){
status.setVisibility(View.VISIBLE);
status.setText(mStatus.toString());
}
userImage.setImageBitmap(personToDisplay.getRoundedImage(Consts.LARGE_USER_IMAGE_SIZE, Consts.LARGE_USER_IMAGE_BORDER));
phoneNumber = personToDisplay.getPhoneNum();
if(phoneNumber.length()>0){
phoneNum.setText(OFFICE + ": " + phoneNumber);
phoneNum.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
numToCall = phoneNumber;
numtype = OFFICE;
showDialog(DIALOG_CALL_OFFICE_ID);
}
});}
else
phoneNum.setVisibility(View.GONE);
cellNumber = personToDisplay.getCellPhoneNum();
if(cellNumber.length()>0){
cellNum.setText(CELL + ": " + cellNumber);
cellNum.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
numToCall = cellNumber;
numtype = CELL;
showDialog(DIALOG_CALL_CELL_ID);
}
});}
else
cellNum.setVisibility(View.GONE);
emailAddress = personToDisplay.getEmailAddress();
emailAddr.setText(emailAddress);
emailAddr.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
db.communicate(DB_TAG, "email", username);
Intent emailIntent = new Intent();
emailIntent.setAction(android.content.Intent.ACTION_SENDTO);
emailIntent.setData(Uri.parse("mailto:" + emailAddress));
startActivity(Intent.createChooser(emailIntent, "Select Email Client"));
}
});
if(personToDisplay.hasLocation()){
btLocation.setVisibility(View.VISIBLE);
btLocation.setText(personToDisplay.getLocation().toString());
}
CalendarEntry usefulCalInfo = personToDisplay.getCalendar().getMostUseful();
if(usefulCalInfo != null){
calInfo.setVisibility(View.VISIBLE);
calInfo.setText("Calendar: " + usefulCalInfo.toString());
}
if(personToDisplay.hasIM()){
imTable.setVisibility(View.VISIBLE);
}
for(IM mIM : personToDisplay.getIMList().values()){
switch(mIM.getId()){
case(IM.FXPAL_ID):
fxpalIMrow.setVisibility(View.VISIBLE);
fxpalIMstatus.setText(mIM.getStatus());
break;
case(IM.SKYPE_ID):
skypeIMrow.setVisibility(View.VISIBLE);
skypeIMstatus.setText(mIM.getStatus());
break;
case(IM.MS_LIVE_ID):
msLiveIMrow.setVisibility(View.VISIBLE);
msLiveIMstatus.setText(mIM.getStatus());
break;
case(IM.GTALK_ID):
gtalkIMrow.setVisibility(View.VISIBLE);
gtalkIMstatus.setText(mIM.getStatus());
break;
default:
}
}
}
protected Dialog onCreateDialog(int id) {
Dialog dialog = null;
switch(id) {
case DIALOG_CALL_OFFICE_ID:
case DIALOG_CALL_CELL_ID:
dialog = CommDialog.getCallDialog(displayName.getText().toString(), numToCall, numtype, IndividualViewActivity.this, db);
break;
case DIALOG_VIEW_CALENDAR:
return CalendarListDialog.getDialog(username, IndividualViewActivity.this, appCtx);
default:
dialog = null;
}
return dialog;
}
public boolean onCreateOptionsMenu(Menu menu){
menu.add(Menu.NONE, REFRESH_MENU_ID, Menu.NONE, "Refresh")
.setIcon(R.drawable.ic_menu_refresh)
.setAlphabeticShortcut('r');
return(super.onCreateOptionsMenu(menu));
}
#Override
public boolean onOptionsItemSelected(MenuItem item){
switch (item.getItemId()) {
case REFRESH_MENU_ID:
refresh();
break;
}
return (super.onOptionsItemSelected(item));
}
void refresh() {
// update the location and report it to the server
ReportingService.startLocationRequest(appCtx, true);
// this may still retrieve the old location
updateInfo();
}
}
Please help me guys. I am stuck with this problem since long time.
Regards,
Rakesh