오늘은 최상단 위치에 Services를 통해 View를 실행하는 예제를 작성하겠습니다.
먼저 Service에서 WindowManager를 통해 View를 만들 수 있습니다.
코드 작성
AndroidManifest.xml (permission 과 application 영역내의 service를 등록 해 줍니다.)
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <application> ... <service android:name=".MyService" android:enabled="true" android:permission="android.permission.SYSTEM_ALERT_WINDOW" > </service> </application>
view_in_service.xml (서비스를 통해 보여질 view xml을 작성합니다.)
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="200dp" android:background="#0000ff"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" android:textColor="#ffffff" android:id="@+id/textView" /> <ImageButton android:layout_width="368dp" android:layout_height="wrap_content" android:id="@+id/bt" android:text="click" android:textColor="#ffffff" android:src="@mipmap/ic_launcher" android:layout_below="@+id/textView" android:layout_alignParentLeft="true" android:layout_marginTop="12dp" /> </RelativeLayout>
MyService.java
import android.app.Service; import android.content.Context; import android.content.Intent; import android.graphics.PixelFormat; import android.os.IBinder; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.widget.ImageButton; import android.widget.TextView; public class MyService extends Service { WindowManager wm; View mView; @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); LayoutInflater inflate = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); wm = (WindowManager) getSystemService(WINDOW_SERVICE); WindowManager.LayoutParams params = new WindowManager.LayoutParams( /*ViewGroup.LayoutParams.MATCH_PARENT*/300, ViewGroup.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, PixelFormat.TRANSLUCENT); params.gravity = Gravity.LEFT | Gravity.TOP; mView = inflate.inflate(R.layout.view_in_service, null); final TextView textView = (TextView) mView.findViewById(R.id.textView); final ImageButton bt = (ImageButton) mView.findViewById(R.id.bt); bt.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { bt.setImageResource(R.mipmap.ic_launcher_round); textView.setText("on click!!"); } }); wm.addView(mView, params); } @Override public void onDestroy() { super.onDestroy(); if(wm != null) { if(mView != null) { wm.removeView(mView); mView = null; } wm = null; } } }
MainActivity.java
(마시멜로우 버전 이상부터는 보안이 강화가 되어서 아래 사용자의 동의를 얻어야지만 사용할 수 있습니다.
그래서 checkpermission이라는 부분에서 상세히 작성되어 있습니다.)
public class MainActivity extends AppCompatActivity { private static final int ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button bt_start = (Button) findViewById(R.id.bt_start); bt_start.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { checkPermission(); //startService(new Intent(MainActivity.this, AlwaysOnTopService.class)); } }); Button bt_stop = (Button) findViewById(R.id.bt_stop); bt_stop.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { stopService(new Intent(MainActivity.this, MyService.class)); } }); } public void checkPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // 마시멜로우 이상일 경우 if (!Settings.canDrawOverlays(this)) { // 체크 Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())); startActivityForResult(intent, ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE); } else { startService(new Intent(MainActivity.this, MyService.class)); } } else { startService(new Intent(MainActivity.this, MyService.class)); } } @TargetApi(Build.VERSION_CODES.M) @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE) { if (!Settings.canDrawOverlays(this)) { // TODO 동의를 얻지 못했을 경우의 처리 } else { startService(new Intent(MainActivity.this, MyService.class)); } } } }
완료 및 실행 화면!
'Android' 카테고리의 다른 글
[안드로이드] Directory 생성, file list 가져오기 (0) | 2017.05.01 |
---|---|
[안드로이드] Activity <-> Service 데이터 주고 받기 예제 (2) | 2017.04.30 |
[안드로이드] AppCompatSeekBar 최소,최대,스텝(Min, Max, Setp) 설정하기 (0) | 2017.04.27 |
[안드로이드] org.apache.log4j.chainsaw.ControlPanel: can't find superclass or interface javax.swing.JPanel 오류 대응 (0) | 2017.04.25 |
[안드로이드] SQL Like 검색 (0) | 2017.04.25 |