해당 자료들은 구글에 파이어몽키 플로팅 위젯에 관련된 자료 하나도 없기에
본인이 직접 수정 및 제작 본인이 직접 작성한 게시글을 정리하였습니다
java로 프로그래밍 한파일을 jar패키징 한후 파이어몽키 라이브러리 추가 하시거나 또는 classes.dex에 병합 시켜주시면 됩니다 java로 코드 짠것은 서비스 쪽입니다 그렇다면 서비스 외부에 해당되기 때문에 액티비티와 통신을 해야
가사의 내용이 액티비티에서 서비스로 전달이 됩니다
1. 액티비티가 뭐죠?
액티비티는 모든 뷰들을 담는 케이스 같은 역활이라고 보시면 됩니다
버튼이나 레이블 혹은 레이아웃들을 이 액티비티에 배치 하게 되지요 스크린은 우리가 보고 있는
스마트폰 화면이라고 보시면 됩니다

그래서 파이어몽키도 안드로이드 액티비티로 구성이 되어 있기 때문에
서비스와 액티비티가 내용을 전달하고자 필요한 상황일때에는 통신을 해야한답니다
아래가 양방향 통신 방법인데 그 방법도 추가로 넣어 드렸으니 이해하시길 바랍니다.
플로팅 개념으로 만들었으니 이와 같이 플로팅 위젯을 다양하게 만들수 있습니다
리모컨 같은 버튼 위젯이 돌아댕기게
하거나 말이죠
https://cafe.naver.com/soyeoncode/18970
파이어몽키 TextView Java Service를 브로드캐스트로 Activity ↔ Service 양방향 통신 활용
대한민국 모임의 시작, 네이버 카페
cafe.naver.com
↓ 메인 디쉬인 KMSLyric 플로팅 가사 자바 코드로 수정한 소스 입니다
package com.KMSLyric;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.widget.Toast;
import android.app.Service;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
public class KMSLyricService extends Service {
private TextView mPopupView; //항상 보이게 할 뷰
private WindowManager.LayoutParams mParams; //layout params 객체. 뷰의 위치 및 크기를 지정하는 객체
private WindowManager mWindowManager; //윈도우 매니저
private SeekBar mSeekBar; //투명도 조절 seek bar
public static final String KMS_Lyric = "KMS_Lyric";
Intent KMSIntent = new Intent("com.KMSLyric.KMSLyricService");
String KMSMessage;
private float START_X,
START_Y; //움직이기 위해 터치한 시작 점
private int PREV_X,
PREV_Y; //움직이기 이전에 뷰가 위치한 점
private int MAX_X = -1,
MAX_Y = -1; //뷰의 위치 최대 값
private OnTouchListener mViewTouchListener = new OnTouchListener() {
@Override public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: //사용자 터치 다운이면
if (MAX_X == -1)
setMaxPosition();
START_X = event.getRawX(); //터치 시작 점
START_Y = event.getRawY(); //터치 시작 점
PREV_X = mParams.x; //뷰의 시작 점
PREV_Y = mParams.y; //뷰의 시작 점
break;
case MotionEvent.ACTION_MOVE:
int x = (int)(event.getRawX() - START_X); //이동한 거리
int y = (int)(event.getRawY() - START_Y); //이동한 거리
//터치해서 이동한 만큼 이동 시킨다
mParams.x = PREV_X + x;
mParams.y = PREV_Y + y;
optimizePosition(); //뷰의 위치 최적화
mWindowManager.updateViewLayout(mPopupView, mParams); //뷰 업데이트
break;
}
return true;
}
};
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onTaskRemoved(Intent rootIntent) { //핸들링 하는 부분
Toast.makeText(this, "KMSPack 강제종료 감지", Toast.LENGTH_SHORT).show();
stopSelf(); //서비스 종료
}
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
@Override public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
// Get extra data included in the Intent
if(intent.getAction().equals("com.KMSLyric.KMSLyricService")){
KMSMessage = intent.getStringExtra("KMS_Lyric");
mPopupView.setText(KMSMessage);
mWindowManager.updateViewLayout(mPopupView, mParams);
}
}
};
@Override
public void onCreate() {
super.onCreate();
KMSIntent.putExtra("KMS_Lyric","KMSPack 플로팅 가사창 입니다.");
sendBroadcast(KMSIntent);
final IntentFilter theFilter = new IntentFilter();
theFilter.addAction("com.KMSLyric.KMSLyricService");
registerReceiver(mMessageReceiver, theFilter);
mPopupView = new TextView(this); //뷰 생성
mPopupView.setText(KMSIntent.getStringExtra("KMS_Lyric")); //텍스트 설정
mPopupView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14); //텍스트 크기 18sp
mPopupView.setTextColor(Color.GREEN); //글자 색상
mPopupView.setBackgroundColor(Color.GRAY); //텍스트뷰 배경 색
//mPopupView.setBackgroundColor(Color.argb(127, 0, 255, 255)); //텍스트뷰 배경 색
mPopupView.setOnTouchListener(mViewTouchListener); //팝업뷰에 터치 리스너 등록
//최상위 윈도우에 넣기 위한 설정
mParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE, //항상 최 상위에 있게. status bar 밑에 있음. 터치 이벤트 받을 수 있음.
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, //이 속성을 안주면 터치 & 키 이벤트도 먹게 된다.
//포커스를 안줘서 자기 영역 밖터치는 인식 안하고 키이벤트를 사용하지 않게 설정
PixelFormat.TRANSLUCENT); //투명
mParams.gravity = Gravity.LEFT | Gravity.TOP; //왼쪽 상단에 위치하게 함.
mWindowManager = (WindowManager)getSystemService(WINDOW_SERVICE); //윈도우 매니저 불러옴.
mWindowManager.addView(mPopupView, mParams); //최상위 윈도우에 뷰 넣기. *중요 : 여기에 permission을 미리 설정해 두어야 한다. 매니페스트에
addOpacityController(); //팝업 뷰의 투명도 조절하는 컨트롤러 추가
}
/*
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 서비스가 호출될 때마다 실행
return super.onStartCommand(intent, flags, startId);
}
*/
/**
* 뷰의 위치가 화면 안에 있게 최대값을 설정한다
*/
private void setMaxPosition() {
DisplayMetrics matrix = new DisplayMetrics();
mWindowManager.getDefaultDisplay().getMetrics(matrix); //화면 정보를 가져와서
MAX_X = matrix.widthPixels - mPopupView.getWidth(); //x 최대값 설정
MAX_Y = matrix.heightPixels - mPopupView.getHeight(); //y 최대값 설정
}
/**
* 뷰의 위치가 화면 안에 있게 하기 위해서 검사하고 수정한다.
*/
private void optimizePosition() {
//최대값 넘어가지 않게 설정
if (mParams.x > MAX_X)
mParams.x = MAX_X;
if (mParams.y > MAX_Y)
mParams.y = MAX_Y;
if (mParams.x < 0)
mParams.x = 0;
if (mParams.y < 0)
mParams.y = 0;
}
/**
* 알파값 조절하는 컨트롤러를 추가한다
*/
private void addOpacityController() {
mSeekBar = new SeekBar(this); //투명도 조절 seek bar
mSeekBar.setMax(100); //맥스 값 설정.
mSeekBar.setProgress(100); //현재 투명도 설정. 100:불투명, 0은 완전 투명
mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override public void onStopTrackingTouch(SeekBar seekBar) {}
@Override public void onStartTrackingTouch(SeekBar seekBar) {}
@Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mParams.alpha = progress / 100.0f; //알파값 설정
mWindowManager.updateViewLayout(mPopupView, mParams); //팝업 뷰 업데이트
}
});
//최상위 윈도우에 넣기 위한 설정
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE, //항상 최 상위에 있게. status bar 밑에 있음. 터치 이벤트 받을 수 있음.
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, //이 속성을 안주면 터치 & 키 이벤트도 먹게 된다.
//포커스를 안줘서 자기 영역 밖터치는 인식 안하고 키이벤트를 사용하지 않게 설정
PixelFormat.TRANSLUCENT); //투명
params.gravity = Gravity.LEFT | Gravity.TOP; //왼쪽 상단에 위치하게 함.
mWindowManager.addView(mSeekBar, params);
}
/**
* 가로 / 세로 모드 변경 시 최대값 다시 설정해 주어야 함.
*/
@Override
public void onConfigurationChanged(Configuration newConfig) {
setMaxPosition(); //최대값 다시 설정
optimizePosition(); //뷰 위치 최적화
}
@Override
public void onDestroy() {
if (mWindowManager != null) { //서비스 종료시 뷰 제거. *중요 : 뷰를 꼭 제거 해야함.
if (mPopupView != null)
mWindowManager.removeView(mPopupView);
if (mSeekBar != null)
mWindowManager.removeView(mSeekBar);
}
super.onDestroy();
}
}
그래도 사용법을 모르겠다면 아래의 내용을 참고 하시길 바랍니다
FireMonkey Floating(플로팅) 안드로이드 가사 위젯 jar 파일 업로드
본인인 본문글 주소는 https://kswit.tistory.com/19?category=973345 입니다 제가 따로 만들어둔 플로팅 가사 플로팅 jar파일입니다 ※받으신 jar파일은 파이어몽키 안드로이드 라이브러리에 jar파일을 추가
kswit.tistory.com
또는 서비스에서 앱이 Task하는것을 감지하면 서비스도 종료하는것은 아래의 내용을 참고 하시면 됩니다
java 최근에 실행된 앱 보기에서 앱 지울시 종료하기
Android Service에서는 뒤로가기나 홈버튼 누를시 java소스에 public void onDestroy() 이벤트가 발생할수 있습니다 그러나 앱 강제종료시 onDestroy()로 안 넘어가게 되니 아래의 방법대로 하면 해결 할 수 있
kswit.tistory.com
기기 부팅시 해당 앱 자동 실행하게 하고 싶다면 아래의 링크를 참고 하시면 됩니다
https://cafe.naver.com/soyeoncode/17649
[파이어몽키]안드로이드 기기부팅시 어플자동실행
대한민국 모임의 시작, 네이버 카페
cafe.naver.com
'FireMonkey 예제 자료' 카테고리의 다른 글
FireMonkey java class patch and jar patch 패치 하기 (0) | 2022.01.14 |
---|---|
java 최근에 실행된 앱 보기에서 앱 지울시 종료하기 (0) | 2022.01.09 |
FireMonkey Floating(플로팅) 안드로이드 가사 위젯 jar 파일 업로드 (0) | 2022.01.08 |
파이어몽키[Window,Android] 이미지 리스트 비트맵 추가할수 있게 하는 코드 (0) | 2022.01.05 |
java 코드에 리소스 id 얻어오기 (0) | 2022.01.03 |
(영상강의)파이어몽키 Live2D 변환작업 하는방법 (0) | 2022.01.03 |
안드로이드 파이어몽키 지정된폴더에 파일목록 불러오기 (0) | 2021.12.13 |
안드로이드 파이어몽키 euckr encode 예제 (0) | 2021.12.13 |
댓글