Update WZBitmap using WZBitmap.setBitmap() got black overlayview - android

I download gocoder android example and run the BitmapOverlayActivity, everything is ok but when I try to update the WZBitmap using WZBitmap.setBitmap() like:
private Runnable runnable = new Runnable() {
#Override
public void run() {
if (mWZBitmap != null) {
if (System.currentTimeMillis() % 2 == 0) {
mWZBitmap.setBitmap(overlayBitmap1);
} else {
mWZBitmap.setBitmap(overlayBitmap2);
}
}
handler.postDelayed(runnable, 5000);
}
};
private Handler handler = new Handler();
and the camera only shows black view:

Related

Android: Playing MIDI Notes Using Handler and Scrolling RecyclerView Accordingly

I am playing MIDI notes using this library as follows:
handler.postDelayed(new Runnable() {
ShortMessage message;
#Override
public void run() {
{
MidiEvent event = midiEvents.get(index[0]);
if (index[0] < midiEvents.size() - 1) {
delta = midiEvents.get(index[0] + 1).getDelta();
time[0] = timeFactor * midiEvents.get(index[0] + 1).getDelta();
mTotalMidiTime += time[0];
int noteValue;
int NOTE_STATUS;
if (event instanceof NoteOn) {
noteValue = ((NoteOn) event).getNoteValue();
NOTE_STATUS = NOTE_ON;
if (index[0] != 0) {
if (delta != 0) {
Intent intent = new Intent();
intent.setAction(Constants.SCROLL_RECYCLERVIEW);
localBroadcastManager.sendBroadcast(intent);
}
}
} else {
noteValue = ((NoteOff) event).getNoteValue();
NOTE_STATUS = NOTE_OFF;
}
try {
message = new ShortMessage(NOTE_STATUS, 2, noteValue,
127);
} catch (Exception e) {
e.printStackTrace();
}
Intent intent = new Intent();
intent.setAction(Constants.ACTION_SEEK);
localBroadcastManager.sendBroadcast(intent);
if (message != null)
recv.send(message, -1);
index[0]++;
} else {
index[0] = 0;
time[0] = 1;
mTotalMidiTime = mMinimumTime;
delta = 0;
}
handler.postDelayed(this, time[0]);
}
}
}, 0);
With each NoteOn event I am smooth scrolling a RecyclerView and updating a Seekbar using a LocalBroadcastManager
My problem is that playback is fine when UI operations are not performed but playback and UI get completely out of sync as soon as multiple MIDI notes (chords) are played in very quick succession. It would be appreciated if any performance improvements are suggested for the same. I have already tried performing the UI operations in runOnUiThread and also launching a new Handler for UI operations.
My BroadcastReceiver is as follows:
BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String actionType = intent.getAction();
switch (actionType) {
case Constants.SCROLL_RECYCLERVIEW:
Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
mNotesRecycler.smoothScrollBy(pixels, 0);
}
});
break;
case Constants.ACTION_SEEK:
Handler seekHandler = new Handler();
seekHandler.post(new Runnable() {
#Override
public void run() {
mPinchSeekBar.setSelectedCentreValue(mTotalMidiTime);
mCurrentTime.setText(timeInMinutes((int) mTotalMidiTime));
}
});
break;
}
}
};
Besides the optimizations you can do, I think the problem itself is RecyclerView's smoothScroll is more a method you call sometimes to do a fancy scroll rather than bomb it with requests that cause it to constantly recompute the running animation.
One thing you can try is to write yourself a simple scroll handler that calls mRecyclerView.scrollTo() that does the scroll without animation but I guess it's going to be more reliable.
Try something like this
Handler mHandler = new Handler();
int mPosition, mTargetPosition;
#IntRange(from = 20, to = 100)
final int INTERVAL = 50; // try with 50 ms or a little lower
Runnable mTimerScroll = new Runnable() {
public void run() {
if (mPosition != mTargetPosition) {
if (mPosition < mTargetPosition) {
mPosition += mDelta;
if (mPosition > mTargetPosition) mPosition = mTargetPosition;
}
if (mPosition > mTargetPosition) {
mPosition -= mDelta;
if (mPosition < mTargetPosition) mPosition = mTargetPosition;
}
mRecyclerView.scrollTo(mPosition, 0);
}
// repeat every 50ms
mTimerScroll.post(mRunnable, INTERVAL);
}
}
And then you start it
void startTimer() {
stop(); // prevent double start
mHandler.post(mTimerScroll);
}
void stopTimer() {
mHandler.removeCallbacks(mTimerScroll);
}
void scroll(int target) {
mTargetPosition = target;
}
void scrollBy(int pixels) {
scroll(mPosition + pixels);
}
I don't know the specifics of your app but it might work.
About optimization, you are using a lot of stuff there that can or cannot be necessary depending on the specifics of your library, etc, but if there are no different threads or services involved you could avoid the LocalBroadcast thing and all the handler.post() as everything is already on the UI thread (handler.post just posts a runnable to the thread where the handler was created, that in your case is the UI thread, so it doesn't do anything)

long delay AsyncTask and restart task

I would like to implement this function:
When the user click on button start the task and after 5 minute send one file to dropbox, but if the user click another time on the button, the precedent task abort and new task (5 min) start.
I wrote code to upload files to Dropbox, but never written code using task with such a long time (5 minute).
How can do that?
-- EDIT --
thanks #xdevs23, I have implemented the final code
public void onSendOrder() {
try {
mHandler.removeCallbacks(postRunnable); // stop current wait
} catch(Exception ex) {
// Just if the above fails (might be first time)
ex.printStackTrace();
}
int minutes = 5;
mHandler.postDelayed(postRunnable, minutes * 20 * 1000 /* 5 minutes in milliseconds */);
...
...
...
private Runnable postRunnable = new Runnable() {
#Override
public void run() {
Thread myThread = new Thread(myRunnable);
myThread.start();
}
};
private Runnable myRunnable = new Runnable() {
#Override
public void run() {
// your code
int cloud = GetPreferenceCloud();
if(cloud > 0){
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
final File bckDatabase = BackupDatabase();
if (networkInfo != null && networkInfo.isConnected() && bckDatabase != null) {
runOnUiThread(new Runnable() {
public void run() {
// call your asynctask here
new UploadOnCloud(MainActivity.this,
PreferenceConstants.DB_DATABASE_STORE_CLOUD,
PreferenceConstants.FILE_DIR_CLOUD,
bckDatabase,
mUListener,
cloud).execute();
}
});
} else {
Toast.makeText(getContext(),getContext().getResources().getString(R.string.send_msg13), Toast.LENGTH_SHORT).show();
}
}
}
};
* EDIT. V2 *
For implement the Countdown on statusbar I've implemented this:
Modify the onSend function:
public void onSendOrder() {
try {
mHandler.removeCallbacks(postRunnable); // stop current wait
} catch(Exception ex) {
// Just if the above fails (might be first time)
ex.printStackTrace();
}
minute = 3600;
//mHandler.postDelayed(postRunnable, minutes * 20 * 1000 /* 5 minutes in milliseconds */);
mHandler.postDelayed(postRunnable, 1000 /* 1 seconds */);
....
....
in the file menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/break_timer"
android:title="00:00"
app:showAsAction="always"
app:actionViewClass="android.widget.TextView" />
<item
android:id="#+id/action_refresh"
android:title="#string/action_refresh"
app:showAsAction="ifRoom"
android:icon="#drawable/ic_action_autorenew"/>
</menu>
modify the onCreateOptionsMenu
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
MenuItem timerItem = menu.findItem(R.id.break_timer);
timerText = (TextView) MenuItemCompat.getActionView(timerItem);
timerText.setPadding(10, 0, 10, 0); //Or something like that...
return super.onCreateOptionsMenu(menu);
}
private int minute;
private Runnable postRunnable = new Runnable() {
#Override
public void run() {
if(minute >= 0){
minute--;
mHandler.postDelayed(postRunnable, 1000 /* 1 seconds */);
timerText.setText(secondsToString(minute));
}else {
Thread myThread = new Thread(myRunnable);
myThread.start();
}
}
};
Instead of using an AsyncTask, you could use Threads and Runnables.
Create a Runnable where your code, which you want to run in the background, is located:
Runnable myRunnable = new Runnable() {
#Override
public void run() {
// your code
}
}
Create your Thread:
private Thread myThread;
Make sure that you have a handler created on the main thread.
For best results, add it to your onCreate() method:
private Handler mHandler;
#Override
public void onCreate() {
// ...
mHandler = new Handler();
// ...
}
You need to import android.os.Handler.
Declare the runnable where your upload code is:
private Runnable postRunnable = new Runnable() {
#Override
public void run() {
Thread myThread = new Thread(myRunnable);
myThread.start();
}
}
Now do following when the user clicks on the button:
try {
mHandler.removeCallbacks(postRunnable); // stop current wait
} catch(Exception ex) {
// Just if the above fails (might be first time)
}
int minutes = 5;
mHandler.postDelayed(postRunnable, minutes * 60 * 1000 /* 5 minutes in milliseconds */);
And that's it.
Explanation:
When the user clicks on the button, it will wait (without blocking the UI) for 5 seconds, and then it will run the code inside postRunnable, which starts a new thread in the background, which will run the code inside your myRunnable.
Edit for updating notification
private Handler mHandler;
private int minutes = 5;
private Runnable updateRunnable = new Runnable() {
#Override
public void run() {
if(minutes > 0) {
String notifContent = "" + minutes + " remaining.";
// Create your notification (there are several guides which show you how to do this), use notifContent as title or text or whatsoever
minutes--;
mHandler.postDelayed(updateRunnable, 60 * 1000);
} else {
// Remove your notification
}
}
};
To start the countdown:
mHandler.post(updateRunnable);

ScheduledThreadPoolExecutor only "ticking" once

I was using a CountDownTimer for some countdown functionality I have in my Activity. I decided to move away from CountDownTimer and use ScheduledThreadPoolExecutor because CountDownTimers can't cancel themselves in onTick().
For some reason, my Runnable in the following code only executes once. I'm not sure why it isn't executing multiple times. The destroyCountdownTimer() function is not getting hit.
private ScheduledThreadPoolExecutor mCountdownTimer;
private Tick mTick;
class Tick implements Runnable {
#Override
public void run() {
Log.e("tick", String.valueOf(mAccumulatedMilliseconds));
mAccumulatedMilliseconds += 1000;
populateTimeAccumulated();
populateTimeRemaining();
updatePercentages();
if (mTotalMilliseconds <= mAccumulatedMilliseconds) {
destroyCountdownTimer();
}
}
}
private void startCountdown() {
if (mAccumulatedMilliseconds < mTotalMilliseconds) {
mCounterIsRunning = true;
if (mCountdownTimer == null) {
mCountdownTimer = new ScheduledThreadPoolExecutor(1);
}
if (mTick == null) {
mTick = new Tick();
}
mCountdownTimer.scheduleAtFixedRate(mTick, 1000, 1000, TimeUnit.MILLISECONDS);
}
}
private void destroyCountdownTimer() {
if (mCountdownTimer != null) {
mCountdownTimer.shutdownNow();
mCountdownTimer = null;
}
if (mTick != null) {
mTick = null;
}
}
The documentation says:
If any execution of the task encounters an exception, subsequent executions are suppressed.
Add try-catch block to your Tick runnable.

Run a AsyncTask every 10 seconds until cancelled

In my application, I have a button that starts an AsyncTask that downloads data with coordinates for google maps, then draws a marker on the map at the following coordinates. I want to run this every 10 seconds until the user presses the button again.
Here's my code for the handler:
class handleMap{
Handler mHandler = new Handler();
Runnable mTask = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while(btnRefreshPressed == false){
try{
new getGoogleMap().execute();
mHandler.postDelayed(mTask, INTERVAL);
Thread.sleep(INTERVAL);
} catch(Exception e){
System.out.println(e.toString());
}
}
}
};
public void starReapetingClass (){
hMap.starReapetingClass();
}
public void stopDoing(){
mHandler.stopDoing();
}
}
And in the menubutton where it is called:
case R.id.id_Refresh:
handleMap hMap = new handleMap();
if(btnRefreshPressed == true){
menuItem = item;
menuItem.setActionView(R.layout.progressbar);
menuItem.expandActionView();
fRun += 1;
btnRefreshPressed = false;
hMap.run();
}else if(btnRefreshPressed == false){
if(fRun > 0){
menuItem.collapseActionView();
menuItem.setActionView(null);
}
btnRefreshPressed = true;
hMap.stopHandler();
}
This currently causes the application to freeze, and the system outputs a dialog saying that the app isn't responding, and asking if I want to close or wait.
I suspect it has to with the while statement, but I don't get any errors in logcat.
Thanks in advance.
Just use:
private int mSampleDurationTime = 10000;
private boolean continueToRun = true;
mHandler.postDelayed(mRunnable, mSampleDurationTime);
where mRunnable is your task:
private final Runnable mRunnable = new Runnable() {
//...
public void run() {
...
if(continueToRun == true){
mHandler.postDelayed(mRunnable, mSampleDurationTime);
}
}
...
};
First time you call postDelayed and invoke new Runnable(). After, if you want to continue,
call the same method into run()

Why doesn't this update the screen after it is fired?

I am scheduling a simple task that should update a text field in 4 seconds.
However everytime this is called the activity pauses and does not show the value in the text field until I restart the activity.
private void showDelayedValue() {
Runnable longRunningTask = new Runnable() {
public void run() {
int randomVal = randomNumberGenerator.nextInt(30 - -10) - 10; //random number between -10 and 30
String randomValStr = Integer.toString(randomVal);
Log.i(this.getClass().getSimpleName(),
"FIRED startScheduler: " + randomValStr);
theFieldOnScreenTV.setText(randomTempStr);
}
};
//show the value in 2 seconds
scheduledTaskExecutor.schedule(longRunningTask, 4, TimeUnit.SECONDS);
}
The log shows:
FIRED startScheduler: 4
but does not update the TextView theFieldOnScreenTV
Instead onPause is called right after Fired startScheduler: is displayed in LogCat.
Many thanks!
EDIT:
This worked for me following Alex' approach:
private void showDelayedValue() {
int randomX = randomNumberGenerator.nextInt(30 - -10) - 10;
final String randomXStr = Integer.toString(randomX);
final Runnable updateFieldR = new Runnable() {
public void run() {
theFieldOnScreenTV.setText(randomXStr);
}
};
Runnable longRunningTask = new Runnable() {
public void run() {
theFieldOnScreenTV.post(updateFieldR);
}
};
scheduledTaskExecutor.schedule(longRunningTask, 4, TimeUnit.SECONDS);
}
instead of
theFieldOnScreenTV.setText(randomTempStr);
try
theFieldOnScreenTV.post(new Runnable() { theFieldOnScreenTV.setText(randomTempStr); } );
Have a try using Handlers.
Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
theFieldOnScreenTV.setText(randomTempStr);
}
});

Categories

Resources