마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

항상 노출되는 최상위 뷰에서 텍스트 갱신 방법

0 추천

안녕하십니까? 안드로이드 공부하는 학생입니다.

저는 전체 윈도우중 일정 부분을 차지하는 최상위 뷰에서, 어딘가에서 정보를 가져와 주기적으로 띄워주는 것을 만들고 싶습니다. 배터리나 시간표시같은 것이 유사하다고 볼 수 있습니다.

다음 블로그(http://blog.daum.net/mailss/18)에서 항상 최상위에 놓는 뷰 예제를 확인하였는데요,

이 예제는 액티비티에서 스타트 버튼을 누르면 서비스가 실행되면서 최상위 뷰를 생성합니다. 스탑 버튼을 누르면 서비스 종료와 동시에 뷰도 제거가 됩니다.

제가 시도하고 있는것은 일정 시간마다 뷰를 갱신하여 텍스트를 바꾸고 싶은데, 제 짧은 지식으로는 어떤식으로 고쳐야 할지 모르겠습니다. 다음 코드에서 Service에 정의된 count 변수를 일정시간마다 증가시켜 보여주고 싶습니다.

스택오버플로우(http://stackoverflow.com/questions/24504759/updating-the-android-view-which-is-always-on-top) 에서도 질문하였으나, LocalBroadcastManager를 이용하라는데 잘 이해가 안되고 있습니다.

도움 주시면 감사하겠습니다.

 최상위 뷰에서 텍스트가 있는 모습

1. AlwaysOnTopActivity.java

package pe.sbk.alwaysontop;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;

public class AlwaysOnTopActivity extends Activity implements OnClickListener {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        findViewById(R.id.start).setOnClickListener(this);//시작버튼
        findViewById(R.id.end).setOnClickListener(this);//중시버튼
    }
    
    @Override
	public void onClick(View v) {
    	int view = v.getId();
    	if(view == R.id.start)
    		startService(new Intent(this, AlwaysOnTopService.class));	//서비스 시작
    	else
    		stopService(new Intent(this, AlwaysOnTopService.class));	//서비스 종료
    }
}

2. AlwaysOnTopService.java

package pe.sbk.alwaysontop;

import android.app.Service;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.util.TypedValue;
import android.view.WindowManager;
import android.widget.TextView;

public class AlwaysOnTopService extends Service {
	private TextView tv;		//항상 보이게 할 뷰
	@Override
	public IBinder onBind(Intent arg0) { return null; }
	
	private int count=0; //몇번 뷰를 갱신하였는지 체크할 예정
	
	@Override
	public void onCreate() {
		super.onCreate();

		tv = new TextView(this);		//뷰 생성
		tv.setText("This view is always on top");
		tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
		tv.setTextColor(Color.BLUE);
		
		//최상위 윈도우에 넣기 위한 설정
		WindowManager.LayoutParams params = new WindowManager.LayoutParams(
			WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,					//항상 최 상위에 있게
			WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,		//터치 인식, 나중에 기능 추가를 위해 일단 넣어둠
			PixelFormat.TRANSLUCENT); //투명
		
		WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);	//윈도우 매니저 불러옴.
		wm.addView(tv, params);		//최상위 윈도우에 뷰 넣기. *중요 : 여기에 permission을 미리 설정해 두어야 한다. 매니페스트에 
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		if(tv != null)		//서비스 종료시 뷰 제거. *중요 : 뷰를 꼭 제거 해야함.
		{
			((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(tv);
			tv = null;
		}
	}
}

 

ohyeaha (450 포인트) 님이 2014년 7월 2일 질문
ohyeaha님이 2014년 7월 2일 수정

2개의 답변

+1 추천
 
채택된 답변
wm.addView(tv, params); 밑에 주가해주세요
 
final Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) { 
                // TODO Auto-generated method stub 
                super.handleMessage(msg);    
                tv.setText(String.valueOf(count));
            }
        };
        
        new Thread(new Runnable(){ 
            @Override
            public void run() {
                // TODO Auto-generated method stub
                while (true) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    count++;
                    handler.sendEmptyMessage(0); 
                }
            }
        }).start();
 
 
 
 
 
그리고..onDestory 오버라드이된 부분에 WIndowManager에 추가된 TextView를 제거해줘야하는데
wm.removeView(tv); 를 빼먹었습니다..
whdrb19 (23,520 포인트) 님이 2014년 7월 2일 답변
ohyeaha님이 2014년 7월 2일 채택됨
답변 감사드립니다. 그런데 마지막에 말씀하신 부분이
((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(tv);
위 코드로 실행이 되고있는것 아닌가요?
아네그러네요 ㅎㅎ 글이 너무길어서 못봤네요
+1 추천

 AlwaysOnTopService.java 에서 handler 를 사용하여 일정 주기로 count  값을 더한 후 tv.setText에 그 값을 넣는 것을 반복 해 주면 됩니다.

사악미소 (65,330 포인트) 님이 2014년 7월 2일 답변
답변 감사드립니다. 핸들러에 대한 이해가 필요하겠네요
...