I'm using OSMdroid Mapview and using AsyncTask class to get some data, and I create overlays and try to redraw every time I get a msg.
Unfortunately I'm able to get data from a client and I'm able to create overlays to in onProgressUpdated, I've even called invalidate(); But nothing seems to happen. Not sure what is the problem?
Here's my AsyncTask:
public class TaskManager extends AsyncTask<Void, GeoPoint, Void>{
.....
public TaskManager(Master master,MapView mapview) {
//Construtor
}
#Override
protected Void doInBackground(Void... arg0) {
if(Constance.TCPIP) {
Log.d("APP","Inside TCPIP");
//Creation of TCPIP Sockets
try {
m_ssocket = new ServerSocket(Constance.PORT_NO);
Log.d("APP","ServerSocket: "+m_ssocket);
m_socket = m_ssocket.accept();
Log.d("APP","Accepted: "+m_socket);
} catch (IOException e) {
e.printStackTrace();
}
}
else if (Constance.UDPIP) {
//Creation of UDP Sockets
try {
m_dsocket = new DatagramSocket(Constance.PORT_NO);
} catch (SocketException e) {
e.printStackTrace();
}
}
else if (Constance.MCUDP) {
//Lock Wifi multicast
mMultiCastLock = new MultiCastLock(mMaster.getBaseContext());
mMultiCastLock.setMultiCastAcquire();
//Creation of MC-UDP Sockets
try {
m_mcsocket = new MulticastSocket(Constance.PORT_NO);
InetAddress address = InetAddress.getByName(Constance.GROUP_ADDR);
m_mcsocket.joinGroup(address);
} catch (IOException e) {
e.printStackTrace();
}
}
// Create a buffer to read datagrams into.
byte[] mSocketbuffer = new byte[Constance.DGRAM_LEN];
if(Constance.TCPIP) {
try {
m_inSocketData = new BufferedReader(new InputStreamReader(m_socket.getInputStream()));
Log.d("APP","Reading");
} catch (IOException e) {
e.printStackTrace();
}
} else {
// Create a packet to receive data into the buffer
m_inPacket = new DatagramPacket(mSocketbuffer, mSocketbuffer.length);
}
//prepare overlay items
prepareItemizedOverlay();
// Now loop forever, waiting to receive packets and printing them.
if(m_ssocket!=null || m_dsocket!=null || m_mcsocket!=null)
while (true) {
if (isCancelled()) break;
//Get Data
parseData();
//Make Packet Object
if(mMSG!=null) {
make(mMSG);
}
if(m_inPacket!=null && !Constance.TCPIP) {
// Reset the length of the packet before reusing it.
m_inPacket.setLength(mSocketbuffer.length);
}
}
return null;
}
#Override
protected void onProgressUpdate(GeoPoint... geoPoints){
OverlayItem overlayItem = new OverlayItem("Name", "Description", geoPoints[0]);
mItemizedOverlay.addOverlay(overlayItem);
mMapView.getOverlays().add(mItemizedOverlay);
mMapView.getController().animateTo(geoPoints[0]);
mMapView.invalidate();
}
#Override
protected void onCancelled() {
super.onCancelled();
if(Constance.TCPIP) {
if(m_ssocket!=null && m_socket!=null){
try {
m_ssocket.close();
m_socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} else if(Constance.UDPIP) {
if(m_dsocket!=null)
m_dsocket.close();
} else if(Constance.MCUDP) {
if(m_mcsocket!=null)
m_mcsocket.close();
}
Log.d("APP","Task Ended");
}
private void parseData() {
if(Constance.TCPIP) {
// Wait to receive a socket data
try{
mMSG = m_inSocketData.readLine();
} catch (IOException e) {
e.printStackTrace();
}
} else {
// Wait to receive a datagram
try {
m_dsocket.receive(m_inPacket);
// Convert the contents to a string, and display them
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void make(String plot) {
//Make Object
mMSG = new MSG(plot);
//Overlay
mGeoPoint = mMSG.getGeoPoint();
publishProgress(mMSG.getGeoPoint());
}
private void prepareItemizedOverlay() {
/* itemized overlay */
Drawable newMarker = mMaster.getResources().getDrawable(R.drawable.ic_sensor);
mItemizedOverlay = new PlotItemOverlay(mMaster,mItemList,newMarker,
new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
#Override
public boolean onItemSingleTapUp(int index, OverlayItem item) {
Log.d("APP","HERE");
return true;
}
#Override
public boolean onItemLongPress(int index, OverlayItem item) {
return true;
}
}, mResourceProxy);
}
}
Everything seems to work, but nothing seems to happen, not sure what is the problem?
Finally resolved it. I was actually replacing my MapFragment class which led to all this loss of Object and a new object created was interfacing the old one, and so the data received to interfacing to the older MapFragment and not the new MapFragment. Got it resolved, once I found the logically analyzing the code. Anyways, thanks for the support #kurtzmarc you have been very helpful until now. I will continue same with OSMdroid to see any more things that I come up with.
Related
I am using the example code from IBM's github for Speech To Text but this line is giving me problems. android studio throws an error saying that i don't need the "capture" argument but when i remove it, i get an error when i run it that the audio cannot be null.
speechService.recognizeUsingWebSocket(capture, getRecognizeOptions(), new MicrophoneRecognizeDelegate());
it is used in this part
private void recordMessage() {
//mic.setEnabled(false);
speechService = new SpeechToText();
speechService.setUsernameAndPassword(STT_username, STT_password);
speechService.setEndPoint("https://stream.watsonplatform.net/speech-to-text/api");
if(listening != true) {
capture = microphoneHelper.getInputStream(true);
InputStream myInputStream = new MicrophoneInputStream(true);
new Thread(new Runnable() {
#Override public void run() {
try {
speechService.recognizeUsingWebSocket(capture, getRecognizeOptions(), new MicrophoneRecognizeDelegate());
} catch (Exception e) {
showError(e);
}
}
}).start();
listening = true;
Toast.makeText(MainActivity.this,"Listening....Click to Stop", Toast.LENGTH_LONG).show();
} else {
try {
microphoneHelper.closeInputStream();
listening = false;
Toast.makeText(MainActivity.this,"Stopped Listening....Click to Start", Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
}
This is a very late answer but just in case anyone needs this ..
update your call to :
speechService.recognizeUsingWebSocket(getRecognizeOptions(capture),new MicrophoneRecognizeDelegate());
I'm trying to implement a way to listen to a client's connection event on the smartphone hotspot. I see that android.net.wifi.WIFI_HOTSPOT_CLIENTS_CHANGED is no longer avaible. How can i do this? I think that this is possible because the smartphone notify me when i client make a connection to the smartphone hotspot.
You can't use the Intent Action...You have to use a custom method, i'l suggest you create a background thread that checks/reads the I.P table (/proc/net/arp) constantly and update you...here's a snippet I've used.
Read i.p list table
public ArrayList<String> getConnectedDevices() {
ArrayList<String> arrayList = new ArrayList();
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader("/proc/net/arp"));
while (true) {
String readLine = bufferedReader.readLine();
if (readLine == null) {
break;
}
String[] split = readLine.split(" +");
if (split != null && split.length >= 4) {
arrayList.add(split[0]);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return arrayList;
}
Create runnable to check
class CheckHotSpotConnection implements Runnable {
private CheckHotSpotConnection() {
}
public void run() {
int i = 0;
while (discoverClient()) {
i = getConnectedDevices().size();
if (i > 1) {
//client discovered
//disable client discovery to end thread
} else {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Start Thread
new Thread(new CheckHotSpotConnection()).start();
I would like to show ProgressDialog during another asynctask.
I write ProgressDialog . one AsyncTask
and I write another AsyncTask in PostExecute method.
but ProgressDialog doesn't run... I'd appreciate your kind help.
AsyncTask code:
public class SavingProgressTask extends AsyncTask<Void, Void, Void> {
private Context mContext;
private ProgressDialog progDialog = null;
public SavingProgressTask(Context context) {
mContext = context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progDialog = new ProgressDialog(mContext);
progDialog.setMessage("saving...");
progDialog.setIndeterminate(false);
progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progDialog.setCancelable(false);
progDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if(isUpdateStore) {
try {
int storeResponseMessage = new StoreUpdateTask(SettingActivity.this).execute(fc_code).get();
if(storeResponseMessage == 1) {
Store updateStore = new StoreDetailTask(SettingActivity.this, false).execute(fc_code).get();
mAuthUser.setStore(updateStore);
UserAuthUtil.saveUserObject(SettingActivity.this, mAuthUser);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
int userinfoResponseMessage;
int userinfosex;
if(mSexTextView.getText().toString().equals("남자")) {
userinfosex = 1;
} else if (mSexTextView.getText().toString().equals("여자")){
userinfosex = 2;
} else {
userinfosex = 2;
}
if(isUpdateBirthday) {
if(isUpdateSex) {
try {
userinfoResponseMessage = new UserUpdateTask(SettingActivity.this, true, "TWICE").execute(tempBirthDay, String.valueOf(userinfosex)).get();
if(userinfoResponseMessage == 1) {
mAuthUser.getUser().setBirthday(tempBirthDay);
mAuthUser.getUser().setSex(userinfosex);
UserAuthUtil.saveUserObject(SettingActivity.this, mAuthUser);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
} else {
try {
userinfoResponseMessage = new UserUpdateTask(SettingActivity.this, true, "BIRTHDAY").execute(tempBirthDay).get();
if(userinfoResponseMessage == 1) {
mAuthUser.getUser().setBirthday(tempBirthDay);
UserAuthUtil.saveUserObject(SettingActivity.this, mAuthUser);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
} else {
if(isUpdateSex) {
try {
userinfoResponseMessage = new UserUpdateTask(SettingActivity.this, true, "SEX").execute(String.valueOf(userinfosex)).get();
if(userinfoResponseMessage == 1) {
mAuthUser.getUser().setSex(userinfosex);
UserAuthUtil.saveUserObject(SettingActivity.this, mAuthUser);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
} else {
}
}
if(progDialog != null) {
progDialog.dismiss();
Intent intent = new Intent(mContext, HomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
mContext.startActivity(intent);
}
}
in click listener:
SavingProgressTask saveTask = new SavingProgressTask(SettingActivity.this);
saveTask.execute();
As far as I know starting another async task from the post execute of previous async task is not that good idea.
When I had a similar problem in one of my projects I had followed the following process.
1) Create an interface with a method like notifyUIThread().
2) Implement this interface from the activity, which calls the async task.
3) While creating the async task, pass 'this' as a parameter to the constructor of the async task.
4) In the post execute of async task call the this.notifyUIThread() method.
5) In the overridden method notifyUIThread(), make a call to the next async task.
Coming to the progress dialog, make it global variable, show it in the pre execute method of the first async task, dismiss it in the post execute of the second async task.
You can also do make the progress dialog local to the async task, show in pre execute and dismiss in post execute of both the async tasks.
But a small advice here is, keep the app responsive. Showing the progress dialog for a long time is not advisable.
I am creating an android application that uses async task to login and send data(HTTP Post Request. The application works fine when internet connection is good but when logging and it takes too long to post data due to slow connection the application force closes. i would like to display a toast "Error in Connection" when this happens. Please Help
Your application probably crashes, because you are trying to show Toast not in a UI Thread. That is you always should make any changes to UI by using Handler, or within onPostExecute() method, which also runs in UI Thread.
How to catch exceptions in doInBackground's thread and represent them in UI Thread is another question, I can suggest you this solution:
private class LoginTask extends
AsyncTask<Void, Integer, JSONArray[]> {
private static final int NETWORK_NO_ERROR = -1;
private static final int NETWORK_HOST_UNREACHABLE = 1;
private static final int NETWORK_NO_ACCESS_TO_INTERNET = 2;
private static final int NETWORK_TIME_OUT = 3;
// You can continue this list...
Integer serverError = NETWORK_NO_ERROR;
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog.show(); // Don't forget to create it before
}
#Override
protected JSONArray[] doInBackground(Void... v) {
JSONArray[] result = null;
try {
result = NetworkManager.login(/* All params you need */);
} catch (JSONException e) {
return null;
} catch (ConnectException e) {
serverError = NETWORK_NO_ACCESS_TO_INTERNET;
return null;
} catch (UnknownHostException e) {
serverError = NETWORK_HOST_UNREACHABLE;
return null;
} catch (SocketTimeoutException e) {
serverError = NETWORK_TIME_OUT;
return null;
} catch (URISyntaxException e) {
// ..
return null;
} catch (ClientProtocolException e) {
// ..
return null;
} catch (Exception e) {
// ..
return null;
}
return result;
}
#Override
protected void onPostExecute(JSONArray[] result) {
progressDialog.dismiss();
if (result != null) {
processAndShowResult(result);
} else {
switch (serverError) {
case NETWORK_NO_ERROR:
Toast.makeText(YourActivity.this, "Probably, invalid response from server", Toast.LENGTH_LONG).show();
break;
case NETWORK_NO_ACCESS_TO_INTERNET:
// You can customize error message (or behavior) for different type of error
case NETWORK_TIME_OUT:
case NETWORK_HOST_UNREACHABLE:
Toast.makeText(YourActivity.this, "Error in Connection", Toast.LENGTH_LONG).show();
break;
}
}
}
}
By this means, you can flexibly control network errors and undertake appropriate actions, according to these errors.
I have MainActivity which does some Work before it Executes an AsyncTask called "Datensammlung". This task starts some other Threads via different classes. All of Them implement Runnable and work correct. Two are for communication with a Server(TCP Connections) and some are listening for Events/ generating random numbers(Intervall 10 seconds).
Now i want to display some Values every thread works on(i always use synchronized).
When i only start the Listener-Threads, "onProgressUpdate" is called maybe 5 times until it ends updating the UI. When i start the two other threads for Communication nothing is displayed ever.
Why is my UI still blocked although i used asynctasks?
Anyone got an idea? Thank you!
Fabian
AsyncTask:Datensammlung
protected Void doInBackground(String[]... params) {
// TODO Auto-generated method stub
while (true) {
int counter = 0;
ArrayList<String> texte = new ArrayList<String>();
String test = "";
for (Input i : this.Dataliste) {
String text = " "+i.variablenName + ": "+String.valueOf(i.getAbstrakterWert())+"\n";
texte.add(text);
test += text;
// Log.e("TEXT ", text);
// counter ++;
}
publishProgress(test);
Log.e("TEXT", test);
test = "";
counter ++;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO: handle exception
}
}
}
#Override
protected void onProgressUpdate(String... listen) {
TextView t = this.viewList.get(0);
Log.e("hier isser", "1");
for (String r : listen) {
t.setText(r);
Log.e("hier isser", r);
}
}
One of my Communication Class:
package kommunikation;
public class SensorAdapter implements Runnable{
String iP;
int port;
Socket socket;
ObjectOutputStream out;
ObjectInputStream in;
ArrayList<Nachricht> nachrichtenliste = new ArrayList<Nachricht>();
Handler handler = new Handler();
// Konstruktor
public SensorAdapter(String iP, int port) {
super();
this.iP = iP;
this.port = port;
}
public boolean initialisiere_sensor(ArrayList<Textobjekt> pObjekte){
try {
socket = new java.net.Socket(iP,port);
// serialisiere alle Inputs und sende die Daten an das FW
out = new ObjectOutputStream(new ObjectOutputStream(socket.getOutputStream()));
out.writeObject(pObjekte);
out.flush();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
public void run() {
try {
while (true) {
if (!nachrichtenliste.isEmpty()) {
PrintWriter printWriter =new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
Nachricht speicher = nachrichtenliste.get(0);
String senden = schreibe_nachricht(speicher);
printWriter.print(senden);
printWriter.flush();
synchronized (nachrichtenliste) {
nachrichtenliste.remove(speicher);
}
}
try {
Thread.sleep(500);
handler.post(this);
} catch (InterruptedException e) {
// TODO: handle exception
}
}
} catch (Exception e) {
// TODO: handle exception
}
}
The Place where the Communication-Thread gets started:
public class Kommunikator implements Callback{
ArrayList<Input> objektliste;
ArrayList<Textobjekt> textliste;
boolean update_erforderlich = false;
public boolean bereit = false;
private Verbindungsdaten verbindungsdaten;
private SensorAdapter sadapter;
private ClientAdapter cadapter;
Thread sensorfred;
Thread clientfred;
// Konstruktor
public Kommunikator(ArrayList<Input> plist, ArrayList<Textobjekt> ptextliste){
boolean check;
boolean cCheck;
this.objektliste = plist;
this.textliste = ptextliste;
// startet die kommunikation
this.sadapter = new SensorAdapter("192.168.2.106", 1111);
this.cadapter = new ClientAdapter("192.168.2.106", 2222,this);
check = sadapter.initialisiere_sensor(ptextliste);
if (check ) {
sensorfred = new Thread(sadapter);
sensorfred.start();
}
// client darf wirklcih erst nach dem sensorlayer starten
cCheck = cadapter.initialisiere_client(ptextliste);
if (cCheck) {
clientfred = new Thread(cadapter);
clientfred.start();
}
this.bereit = true;
}
// kann vom Sensor aufgerufen werden um die updates an das framework zu senden
public void melde(Nachricht na){
Nachricht speicher =null;
for (Nachricht n : this.sadapter.nachrichtenliste) {
if (n.getName().equals(na.getName())) {
speicher = n;
}
}
// lösche die alte nachricht
if (speicher != null) {
int index = sadapter.nachrichtenliste.indexOf(speicher);
sadapter.nachrichtenliste.remove(index);
}
synchronized (sadapter.nachrichtenliste) {
this.sadapter.nachrichtenliste.add(na);
}
}
public void melde_Abstract(String name, int Version, float wert){
// hier synchronized rein???
for (Input i : objektliste) {
if (i.variablenName.equals(name)) {
// mache Versionscheck und schreibe dann dort den wert
synchronized (i) {
i.setAbstrakterWert(wert);
}
}
}
}
When you use Handler.post() it will execute runnable on UI thread (if handler was created in UI thread). So when you do handler.post(this) you actually do all your communication on UI thread.