티스토리 뷰

*안드로이드만 동작 함,

 

매니패스트

 

//권한
<uses-permission android:name="android.permission.ACTION_MANAGE_OVERLAY_PERMISSION" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

 

//서비스 선언
<service
android:name=".WidgetService"
android:enabled="true"
android:exported="false"/>

 

 

 

 

 

 

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.net.Uri;
import android.opengl.Visibility;
import android.os.Build;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.RemoteViews;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;


public class WidgetService extends Service {
private WindowManager mWindowManager;
private View mFloatingView;
public static LinearLayout root_container;

public WidgetService() {
}

@Override
public IBinder onBind(Intent intent) {
return null;
}

private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(
"widget",
"Foreground Service Channel",
NotificationManager.IMPORTANCE_MIN
);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
}
}

@Override
public void onCreate() {
Log.d("TAGTAGTAG","여긴..?");
//
createNotificationChannel();
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, "widget")
// .setContentTitle("위젯 기능을 사용합니다.")
// .setContentText("위젯 기능을 사용합니다.")
.setSmallIcon(R.mipmap.icon_logo_round)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);

super.onCreate();

}

@SuppressLint("ClickableViewAccessibility")
@Override
public int onStartCommand(Intent intent, int flags, int startId) {

//Inflate the floating view layout we created
mFloatingView = LayoutInflater.from(this).inflate(R.layout.layout_floating_widget, null);

int LAYOUT_FLAG;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;
}

//Add the view to the window.
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
LAYOUT_FLAG,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);

//Specify the view position
params.gravity = Gravity.TOP | Gravity.LEFT; //Initially view will be added to top-left corner
params.x = 0;
params.y = 100;

//Add the view to the window
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
mWindowManager.addView(mFloatingView, params);

//Drag and move floating view using user's touch action.
root_container = mFloatingView.findViewById(R.id.root_container);

TextView up_address = mFloatingView.findViewById(R.id.up_address);
TextView down_address = mFloatingView.findViewById(R.id.down_address);
TextView product_name = mFloatingView.findViewById(R.id.product_name);
Button button = mFloatingView.findViewById(R.id.button);

String up = intent.getStringExtra("up");
String down = intent.getStringExtra("down");
String product = intent.getStringExtra("product");

up_address.setText(up);
down_address.setText(down);
product_name.setText(product);

button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d("TAGTAGTAG", "onClick");
Intent intent = new Intent(WidgetService.this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
});


root_container.setOnTouchListener(new View.OnTouchListener() {
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;

@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:

//remember the initial position.
initialX = params.x;
initialY = params.y;

//get the touch location
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
return true;
case MotionEvent.ACTION_UP:
int Xdiff = (int) (event.getRawX() - initialTouchX);
int Ydiff = (int) (event.getRawY() - initialTouchY);

// Log.d("TAGTAGTAG", "Xdiff : " + Xdiff);
// Log.d("TAGTAGTAG", "Ydiff : " + Ydiff);

// if (Xdiff > -10 && Xdiff < 10 && Ydiff > -10 && Ydiff < 10 ) {
// Intent intent = new Intent(WidgetService.this, MainActivity.class);
// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// startActivity(intent);
// }

return true;
case MotionEvent.ACTION_MOVE:
//Calculate the X and Y coordinates of the view.
params.x = initialX + (int) (event.getRawX() - initialTouchX);
params.y = initialY + (int) (event.getRawY() - initialTouchY);


//Update the layout with new X & Y coordinate
mWindowManager.updateViewLayout(mFloatingView, params);
return true;
}
return false;
}
});
return START_NOT_STICKY;
}

@Override
public void onDestroy() {
super.onDestroy();
if (mFloatingView != null) mWindowManager.removeView(mFloatingView);
}

public void show() {
if (root_container != null) {
root_container.setVisibility(View.VISIBLE);
}
}

public void hide() {
if (root_container != null) {
root_container.setVisibility(View.GONE);
}
}
}

 

 

 

 

 

 

 

 

 

 

xml

 

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content">

<!--Root container-->
<LinearLayout
android:id="@+id/root_container"
android:layout_width="240dp"
android:layout_height="wrap_content"
tools:ignore="UselessParent"
android:orientation="vertical"
android:background="#252525"
android:padding="16dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
>

<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@mipmap/icon_logo"/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="배차과장"
android:layout_marginLeft="8dp"
android:textColor="#ffffff"
/>

</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_marginTop="12dp"
>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="상차지"
android:textColor="#ffffff"
/>

<TextView
android:id="@+id/up_address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="상차지 주소"
android:textColor="#fad401"
android:gravity="right"
/>

</LinearLayout>

<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginVertical="8dp"
android:background="#3b3b3b"/>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="하차지"
android:textColor="#ffffff"
/>

<TextView
android:id="@+id/down_address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="하차지 주소명"
android:textColor="#fad401"
android:gravity="right"
/>

</LinearLayout>

<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginVertical="8dp"
android:background="#3b3b3b"/>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="운송물"
android:textColor="#ffffff"
/>

<TextView
android:id="@+id/product_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="운송물품 명"
android:textColor="#fad401"
android:gravity="right"
/>

</LinearLayout>

<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#1b48ea"
android:layout_marginTop="20dp"
android:layout_marginBottom="10dp"
android:layout_marginHorizontal="30dp"
android:text="배차 앱으로 보기"
android:textColor="#ffffff"
/>



</LinearLayout>
</FrameLayout>

 

 

 

 

서비스 실행 유무 확인을 위한 함수

public boolean isServiceRunning(String serviceName){
ActivityManager manager = (ActivityManager) reactContext.getSystemService(Context.ACTIVITY_SERVICE);
for(ActivityManager.RunningServiceInfo runServiceInfo : manager.getRunningServices(Integer.MAX_VALUE)){
Log.d("TAGTAGTAG", runServiceInfo.service.getClassName());
if(serviceName.equals(runServiceInfo.service.getClassName())){
return true;
}
}
return false;
}

 

//서비스 시작하는 코드 

if (!isServiceRunning("com.dispatcherapp.WidgetService")) {
Intent intent = new Intent(reactContext, WidgetService.class);
intent.putExtra("up",up);
intent.putExtra("down",down);
intent.putExtra("product",product);
reactContext.startForegroundService(intent);
}

 

//서비스 종료 코드

if (isServiceRunning("com.dispatcherapp.WidgetService")) {
reactContext.stopService(new Intent(reactContext, WidgetService.class));
}