Below is my code that show an overlay with a list view that shows some information. I am updating the data after every 7 sec
. I want to remove first list before displaying other.
In may case the ListView
s are overlapping.
public class OverlayShowingService extends Service implements OnTouchListener, OnClickListener {
private View topLeftView;
private Button overlayedButton;
ArrayList<String> list = new ArrayList<String>();
/** Declaring an ArrayAdapter to set items to ListView */
ArrayAdapter<String> adapter;
private float offsetX;
private float offsetY;
private int originalXPos;
private int originalYPos;
private boolean moving;
private WindowManager wm;
DispAsync dis;
ListView listView;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(),"onStartCommand", Toast.LENGTH_LONG).show();
listView = new ListView(getApplicationContext());
listView.setAlpha(0.0f);
listView.setBackgroundColor(0x55fe4444);
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
@Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
dis=new DispAsync();
dis.execute();
} catch (Exception e) {
// TODO Auto-generated catch block
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 7000); //execute in every 50000 ms
return super.onStartCommand(intent, flags, startId);
}
public class DispAsync extends AsyncTask<Void, Void, String>
{
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(),"onPre", Toast.LENGTH_LONG).show();
//list.clear();
adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, list);
listView.setAdapter(adapter);
super.onPreExecute();
}
@Override
protected String doInBackground(Void... params) {
// TODO Auto-generated method stub
String line = null;
wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
try
{
line = dynamic data;
while (line != null) {
if(line.contains("com"))
{list.add(line);}
line = reader.readLine();
i++;
}
p.waitFor();
}
catch(Exception e){}
return line;
}
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(),"onPost", Toast.LENGTH_LONG).show();
WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, PixelFormat.TRANSLUCENT);
params.gravity = Gravity.LEFT | Gravity.TOP;
params.x = 0;
params.y = 0;
//adapter.notifyDataSetChanged();
wm.addView(listView, params);
/* topLeftView = new View(getApplicationContext());
WindowManager.LayoutParams topLeftParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, PixelFormat.TRANSLUCENT);
topLeftParams.gravity = Gravity.LEFT | Gravity.TOP;
topLeftParams.x = 0;
topLeftParams.y = 0;
topLeftParams.width = 0;
topLeftParams.height = 0;
wm.addView(topLeftView, topLeftParams);*/
super.onPostExecute(result);
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (overlayedButton != null) {
wm.removeView(overlayedButton);
wm.removeView(topLeftView);
overlayedButton = null;
topLeftView = null;
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
float x = event.getRawX();
float y = event.getRawY();
moving = false;
int[] location = new int[2];
overlayedButton.getLocationOnScreen(location);
originalXPos = location[0];
originalYPos = location[1];
offsetX = originalXPos - x;
offsetY = originalYPos - y;
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
int[] topLeftLocationOnScreen = new int[2];
topLeftView.getLocationOnScreen(topLeftLocationOnScreen);
System.out.println("topLeftY="+topLeftLocationOnScreen[1]);
System.out.println("originalY="+originalYPos);
float x = event.getRawX();
float y = event.getRawY();
WindowManager.LayoutParams params = (LayoutParams) overlayedButton.getLayoutParams();
int newX = (int) (offsetX + x);
int newY = (int) (offsetY + y);
if (Math.abs(newX - originalXPos) < 1 && Math.abs(newY - originalYPos) < 1 && !moving) {
return false;
}
params.x = newX - (topLeftLocationOnScreen[0]);
params.y = newY - (topLeftLocationOnScreen[1]);
wm.updateViewLayout(overlayedButton, params);
moving = true;
} else if (event.getAction() == MotionEvent.ACTION_UP) {
if (moving) {
return true;
}
}
return false;
}
@Override
public void onClick(View v) {
Toast.makeText(this, "Overlay button click event", Toast.LENGTH_SHORT).show();
}
}
logcat
08-11 16:00:55.175: E/AndroidRuntime(11498): FATAL EXCEPTION: main
08-11 16:00:55.175: E/AndroidRuntime(11498): Process: de.mobilej.overlay, PID: 11498
08-11 16:00:55.175: E/AndroidRuntime(11498): java.lang.IllegalStateException: View android.widget.ListView{41db9c50 V.ED.VC. ......I. 0,0-480,422} has already been added to the window manager.
08-11 16:00:55.175: E/AndroidRuntime(11498): at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:232)
08-11 16:00:55.175: E/AndroidRuntime(11498): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
08-11 16:00:55.175: E/AndroidRuntime(11498): at de.mobilej.overlay.OverlayShowingService$DispAsync.onPostExecute(OverlayShowingService.java:151)
08-11 16:00:55.175: E/AndroidRuntime(11498): at de.mobilej.overlay.OverlayShowingService$DispAsync.onPostExecute(OverlayShowingService.java:1)
08-11 16:00:55.175: E/AndroidRuntime(11498): at android.os.AsyncTask.finish(AsyncTask.java:632)
08-11 16:00:55.175: E/AndroidRuntime(11498): at android.os.AsyncTask.access$600(AsyncTask.java:177)
08-11 16:00:55.175: E/AndroidRuntime(11498): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
08-11 16:00:55.175: E/AndroidRuntime(11498): at android.os.Handler.dispatchMessage(Handler.java:110)
08-11 16:00:55.175: E/AndroidRuntime(11498): at android.os.Looper.loop(Looper.java:193)
08-11 16:00:55.175: E/AndroidRuntime(11498): at android.app.ActivityThread.main(ActivityThread.java:5388)
08-11 16:00:55.175: E/AndroidRuntime(11498): at java.lang.reflect.Method.invokeNative(Native Method)
08-11 16:00:55.175: E/AndroidRuntime(11498): at java.lang.reflect.Method.invoke(Method.java:515)
Issue is with Listview creation. Currnetly everytime AsynTask is created it is creating the new list view. just create your list view outside of asynctask and global to class so that you can access this listview object within asyncTask like below
private ListView listView;
initialige this listView in your relevant location like below.
listView = new ListView(getApplicationContext());
listView.setAlpha(0.0f);
listView.setBackgroundColor(0x55fe4444);
adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, list);
listView.setAdapter(adapter);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, PixelFormat.TRANSLUCENT);
params.gravity = Gravity.LEFT | Gravity.TOP;
params.x = 0;
params.y = 0;
wm.addView(listView, params);
In your onPostExcute of your asyncTask update your adaper for any list data change like below
adapter.notifyDataSetChanged();
Edit
Complete fix for the reference
public class OverlayShowingService extends Service implements OnTouchListener, OnClickListener {
private View topLeftView;
private Button overlayedButton;
ArrayList<String> list = new ArrayList<String>();
/** Declaring an ArrayAdapter to set items to ListView */
ArrayAdapter<String> adapter;
private float offsetX;
private float offsetY;
private int originalXPos;
private int originalYPos;
private boolean moving;
private WindowManager wm;
DispAsync dis;
ListView listView;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
listView = new ListView(getApplicationContext());
listView.setAlpha(0.0f);
listView.setBackgroundColor(0x55fe4444);
wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, PixelFormat.TRANSLUCENT);
params.gravity = Gravity.LEFT | Gravity.TOP;
params.x = 0;
params.y = 0;
wm.addView(listView, params);
adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, list);
listView.setAdapter(adapter);
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
@Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
dis=new DispAsync();
dis.execute();
} catch (Exception e) {
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 7000); //execute in every 70000 ms
return super.onStartCommand(intent, flags, startId);
}
public class DispAsync extends AsyncTask<Void, Void, String>
{
@Override
protected void onPreExecute() {
list.clear();
super.onPreExecute();
}
@Override
protected String doInBackground(Void... params) {
String line = null;
try
{
line = dynamic data;
while (line != null) {
if(line.contains("com"))
{list.add(line);}
line = reader.readLine();
i++;
}
p.waitFor();
}
catch(Exception e){}
return line;
}
@Override
protected void onPostExecute(String result) {
adapter.notifyDataSetChanged();
super.onPostExecute(result);
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (overlayedButton != null) {
wm.removeView(overlayedButton);
wm.removeView(topLeftView);
overlayedButton = null;
topLeftView = null;
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
float x = event.getRawX();
float y = event.getRawY();
moving = false;
int[] location = new int[2];
overlayedButton.getLocationOnScreen(location);
originalXPos = location[0];
originalYPos = location[1];
offsetX = originalXPos - x;
offsetY = originalYPos - y;
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
int[] topLeftLocationOnScreen = new int[2];
topLeftView.getLocationOnScreen(topLeftLocationOnScreen);
System.out.println("topLeftY="+topLeftLocationOnScreen[1]);
System.out.println("originalY="+originalYPos);
float x = event.getRawX();
float y = event.getRawY();
WindowManager.LayoutParams params = (LayoutParams) overlayedButton.getLayoutParams();
int newX = (int) (offsetX + x);
int newY = (int) (offsetY + y);
if (Math.abs(newX - originalXPos) < 1 && Math.abs(newY - originalYPos) < 1 && !moving) {
return false;
}
params.x = newX - (topLeftLocationOnScreen[0]);
params.y = newY - (topLeftLocationOnScreen[1]);
wm.updateViewLayout(overlayedButton, params);
moving = true;
} else if (event.getAction() == MotionEvent.ACTION_UP) {
if (moving) {
return true;
}
}
return false;
}
@Override
public void onClick(View v) {
Toast.makeText(this, "Overlay button click event", Toast.LENGTH_SHORT).show();
}
}