오늘은 최상단 위치에  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));
            }
        }
    }
}


완료 및 실행 화면!


   


 



+ Recent posts