i'm trying to add markers to my map, the coordinates and names are contained in a stop object that i'm getting through a query to a stackmob database, the program runs fine displays the map, but for some reason it looks like its not executing the addmarker instruction, won't even loop through the for in the addMarkers method. Also i'm not getting errors or messages of any kind in the console or LogCat, i'm running out of ideas to solve this.
public class MainActivity extends Activity {
GoogleMap map;
List<Stop> stops=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
StackMobAndroid.init(getApplicationContext(), 0, "f4e013f5-3e0f-41e2-af2f-3fc2bfa2446b");
getMarkers();
}
public void getMarkers( )
{
Stop.query(Stop.class, new StackMobQuery().field(new StackMobQueryField("stop")), new StackMobQueryCallback<Stop>() {
#Override
public void success(List<Stop> result) {
addMarkers(result);
}
#Override
public void failure(StackMobException e) {
System.out.println("Fail");
}
});
}
public void addMarkers(List<Stop> stops)
{
for(int i=0;i<=stops.size();i++)
{
LatLng markerPos = new LatLng(stops.get(i).getLatitude(), stops.get(i).getLongitude());
System.out.println(markerPos);
System.out.println(stops.get(i).getName());
System.out.println(i);
map.addMarker(new MarkerOptions().title(stops.get(i).getName()).snippet("test").position(markerPos));
}
}
Thanks
Edit: If i add a a marker manually in, lets say the onCreate method, it will display correctly on the map.
Edit2: When i put a try catch statement around the map.addmarker the error message reads "Not on the main thread" not sure about this.
Okay so i found the solution, apparently the stackmob query runs on a separate thread so if yo want to modify an ui element, like the map in this case , you have to call a runonUithread from the success method.
public void getMarkers( )
{
Stop.query(Stop.class, new StackMobQuery().field(new StackMobQueryField("stop")), new StackMobQueryCallback<Stop>() {
#Override
public void success(List<Stop> result) {
runThread(result);
}
#Override
public void failure(StackMobException e) {
System.out.println("Fail");
}
});
}
private void runThread(final List<Stop> stops) {
new Thread() {
public void run() {
int i=0;
while (i++ < 1) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
for(int j=0;j<stops.size();j++)
{
LatLng markerPos = new LatLng(stops.get(j).getLatitude(), stops.get(j).getLongitude());
System.out.println(markerPos);
System.out.println(stops.get(j).getName());
System.out.println(j);
try {
map.addMarker(new MarkerOptions().title(stops.get(j).getName()).snippet("test").position(markerPos));
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}
});
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
Related
my question is this, I have my main class, she command to run a AyncTask with a URL audio, at the end repreduce the next audio, my question is, I have the player in another class, as I do so the TextView which is updated every actualize the url of the song to play?
Here my code:
Activity main:
AsyncTask
public class Repoduce extends AsyncTask<String, Integer, String> {
#Override
protected void onPreExecute() {
//mostrarNotificacion("Reproduciendo...");
}
#Override
protected String doInBackground(String... strings) {
String url = strings[0];
try {
PlayAudioManager.playAudio(getApplicationContext(), url, Lista);
runOnUiThread(new Runnable() {
#Override
public void run() {
//titulo.setText(guardaDatos.getArtista());
titulo_cancion.setText(guardaDatos.getArtista());
Picasso.with(getApplicationContext()).load(guardaDatos.getCoverURL()).into(caratula);
}
}
);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
}
}
Here class with media player
public static void playAudio(final Context context, final String url, String currentTrack) throws Exception {
mmr = new FFmpegMediaMetadataRetriever();
listaReproduccion a = new listaReproduccion(context);
//am = MusicPlayer.getAm();
//am.setMode(AudioManager.STREAM_MUSIC);
codigos = a.getArray("Codigos");
nombres = a.getArray("Nombres");
artista = a.getArray("Artista");
//guardaDatos.setArtista(nombres.get(cancion));
setIsPlaying(true);
mediaPlayer = MediaPlayer.create(context, Uri.parse(codigos.get(cancion)));
//coverDeezer.caratulaArtista(artista.get(cancion));
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
if (cancion <= codigos.size()) {
try {
cancion++;
playAudio(context, "", "lista");
Log.i("CONTADOR2", String.valueOf(cancion));
} catch (Exception e) {
e.printStackTrace();
}
}
I have textview in activityclass, how to update this from class player automatically?
I think you have some solutions below if you want update textview in another activity :
1 - Create interface listener catch event change audio to update TextView.
2 - Use Broadcast receiver.
3 - Use Handler Message.
Make the AsyncTask inside (inner class) of your Acitivity and call .setTex() inside the onPostExecute() method
I have to update the list after optimizing the running apps ....
m_optimizeBtn.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
launchProgressRing(OptimizationActivity.this);
listAdaptor.notifyDataSetChanged();
}
});
}
Killing the running process in a seprate thread....
public void launchProgressRing(Context ctx){
final ProgressDialog opt_proDialog=new ProgressDialog(ctx);
opt_proDialog.setTitle("Please wait...");
opt_proDialog.setMessage("Optimizing power draining apps...");
opt_proDialog.setIndeterminate(true);
opt_proDialog.show();
opt_proDialog.setCancelable(false);
new Thread(new Runnable()
{
#Override
public void run()
{
//TODO: optimize apps
m_cPowerDrainingApps.killBgRunningProcesses(runningAppsList);
try
{
Thread.sleep(1500);
} catch (InterruptedException e)
{
e.printStackTrace();
}
runOnUiThread(new Runnable()
{
#Override
public void run()
{
opt_proDialog.dismiss();
}
});
}
}).start();
}
listAdaptor.notifyDataSetChanged() is not working ,don't know why ???
What I suggest is to use AsyncTask to do the job. AsyncTask has two good methods for you:
doInBackground: which you can put most of the background tasks in there
onPostExecute : which you can put the logic of what needs to be done when the background task has finished its job.
So your code should look like this:
public class BackgroundTask extends AsyncTask<Void,Void,Void>{
private ListAdapter mAdapter;
public BackgroundTask(ListAdapter adapter)
{
mAdapter = adapter
}
public Void doInBackground (Void... params)
{
//define m_cPowerDrainingApps somewhere
m_cPowerDrainingApps.killBgRunningProcesses(runningAppsList);
try
{
Thread.sleep(1500);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
public Void onPostExecute (Void... params)
{
//do your UI things
mAdapter.notifyDataSetChanged();
}
}
and then run this with:
new BackgroundTask(listAdapter).execute()
Use a Handler and its postDelayed method to invalidate the list's adapter as follows:
final Handler handler = new Handler()
handler.postDelayed( new Runnable() {
#Override
public void run() {
adapter.notifyDataSetChanged();
handler.postDelayed( this, 60 * 1000 );
}
}, 60 * 1000 );
You must only update UI in the main (UI) thread.
I want to make an quiz application in which the questions will be displayed every ten seconds. But when the user answers the question, I need to display the next question. For this I use threads. I have accomplished displaying questions in regular intervals, but when the user answers the question, it wait for the thread to complete. I want to stop the thread and start a fresh one on a button click. My code is given below:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
int i = 0;
while (i++ < 10) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
//Display questions here
}
});
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t.start();
}
public void buttonOnClick(View view)
{
//I want to display new question here
}
How can I call the run method inside the thread. Any help is appreciated. Thank you.
You can use t.interrupt() to stop the thread. Here is the code.
Thread t ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
generateQuestions()
}
public void generateQuestions()
{
t = new Thread(new Runnable() {
#Override
public void run() {
int i = 0;
try {
while (i++ < 10 & !Thread.currentThread().isInterrupted()) {
runOnUiThread(new Runnable() {
#Override
public void run() {
//Display questions here
}
});
Thread.sleep(6000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
}
public void buttonOnClick(View view)
{
//I want to display new question here
t.interrupt();
generateQuestions();
}
In my application I have a button and when it gets clicked I start a new thread and change the text of button. If I press the button again it will start changing its text faster.
I would like to interrupt the thread when the button is pressed in the second time. What's the correct way to do it?
public class TestActivity extends Activity {
Button btn;
int i = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
runThread();
}
});
}
private void runThread() {
new Thread() {
public void run() {
while (i++ < 1000) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
btn.setText("#" + i);
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
In this case, just keep a reference to your thread and use Thread.interrupt():
private Thread runThread() {
return new Thread() {
public void run() {
while (i++ < 1000) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
btn.setText("#" + i);
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Then:
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (myThread != null) myThread.interrupt();
myThread = runThread();
myThread.start();
}
});
Read this post for more info and options:
How to properly stop the Thread in Java?
In my opinion, the best way would be using a variable to control this.
Something like:
while(i++ < 1000 && keepRunning)
I see that as a good solution because it cant cause unexpected behavior, as you are sure the exactly moment your thread would exit.
extra--
As a suggestion, I also would recommend you to set your thread non-Damon (setDaemon(false)) because it makes layout changes
Also it is a good practice to give thread a name (setName()) to make it easy on debugging.
Right now you start a new Thread each time you press the button.
Something like this should work.
public class TestActivity extends Activity {
Button btn;
int i = 0;
Thread countThread = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
countThread = new Thread() {
public void run() {
while (i++ < 1000) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
btn.setText("#" + i);
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
runThread();
}
});
}
private void runThread() {
if(countThread != null) {
if(countThread.isAlive()) {
countThread.stop();
} else {
countThread.start();
}
}
}
I only had a text editor so I can't guarantee if this solves your problem.
You can use thread.interrupt() to interrupt the thread.
Try this, Just take another variable j and it will handle your code:-
public class TestActivity extends Activity {
Button btn;
int i = 0,j=0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
j=1;
runThread();
}
});
}
private void runThread() {
new Thread() {
public void run() {
while (i++ < 1000) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
if(j==1){
btn.setText("#" + i);
j=0;
}
else
Thread.interrupted();
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
You can use normal Thread in Android (and call interrupt() for your use case) but frameworks provides other better options by providing helper classes around Threads. You can refer to official documentation page for other options.
HandlerThread is preferred option. You can call quitSafely() or quit() for your use case if you go for HandlerThread
Related post:
Why use HandlerThread in Android
My code here works fine . It changes the image in my gallery at certain times , but i dont think this is the best approach , especially using thread.sleep() . How can i write a better code for that ? What am i missing ?
Thanks..
#Override
protected void onResume() {
paraThread = true;
workThread = new LooperFoto("MyWorkThread");
workThread.setPriority(Thread.MIN_PRIORITY);
workThread.start();
super.onResume();
}
#Override
protected void onStop() {
Log.i(TAG, "thread state: " + workThread.getState());
paraThread = false;
workThread = null;
super.onStop();
}
class LooperFoto extends HandlerThread {
public LooperFoto(String name) {
super(name);
}
#Override
public void run() {
while (paraThread) {
try {
this.sleep(2000);
mudaFoto.sendMessage(new Message());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Handler mudaFoto = new Handler() {
public void handleMessage(Message msg) {
Random generator = new Random();
int randomIndex = generator.nextInt(thumbImgGallery.getAdapter()
.getCount());
thumbImgGallery.setSelection(randomIndex);
};
};
As long as the thread that is .sleeping() is not your main (UI) thread, you should be fine. What are you worried about?