1

Modal

public class Helper {
private String a;
private String b;
private String c;
private long d;
private long e;

public Helper() {
}

public Helper(String a, String b, String c, long d, long e) {
    this.a= a;
    this.b= b;
    this.c= c;
    this.d = d;
    this.e= e;
}

public String geta() {
    return a;
}

public void seta(String a) {
    this.a= a;
}

public String getb() {
    return b;
}

public void setb(String b) {
    this.b= b;
}

public String getc() {
    return c;
}

public void setce(String c) {
    this.c = c;
}

public long isd() {
    return d;
}

public void setd(long d) {
    this.d= d;
}

public long gete() {
    return e;
}

public void sete(long e) {
    this.e= e;
}

}

Service

public class PieOptions  extends Service {
WindowManager wm;
RelativeLayout ll;
LayoutInflater li;

@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public void onCreate() {
    // TODO Auto-generated method stub
    super.onCreate();
    final View myview;
    li = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
    wm = (WindowManager) getSystemService(WINDOW_SERVICE);
    myview = li.inflate(R.layout.service_pie, null);

    ImageButton mClose = (ImageButton) myview.findViewById(R.id.close);


    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.TYPE_INPUT_METHOD |
                    WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,// | WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
            WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
            PixelFormat.TRANSLUCENT);

    /////////////////////////Another params


    params = new WindowManager.LayoutParams(
            750,1250,
            WindowManager.LayoutParams.TYPE_PHONE,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT);

    params.gravity = Gravity.CENTER | Gravity.CENTER;

    wm.addView(myview, params);
    params.x = 0;
    params.y = 0;

    final WindowManager.LayoutParams finalParameters = params;

    mClose.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            wm.removeView(myview);
            stopSelf();
        }
    });
}

@Override
public void onDestroy() {
    super.onDestroy();
    stopSelf();
}

I have progressed this much. Can someone please help me proceed. I want to fetch data from firebase and show it in this recyclerview inside service. There are very little stuff about services and inflating a layout on google so i dont quite know how to proceed so can someone please help e with code. Thanks in advance

1 Answers1

0

First, if you're running in API>= 26, you need to use foreground services, use the next code to start your service

Intent intent = new Intent(getApplicationContext(), PieOptions.class);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForegroundService(intent);
        }else {
            startService(intent);
        }

Now inside you PieOptions class, first extend JobIntentService instead of Service, in onCreate() method add the following code. Foreground services should show a notification for the user on API >= 26 otherwise the service will be killed in 5 seconds.

   @Override
    public void onCreate() {
        super.onCreate();
        String CHANNEL_ID = "my_service";
        String CHANNEL_NAME = "My Background Service";
        if (Build.VERSION.SDK_INT >= 26) {
            // in APIs 26+ we should show a notifications
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
                    CHANNEL_NAME, NotificationManager.IMPORTANCE_NONE);
            ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);

            Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
                    .setCategory(Notification.CATEGORY_SERVICE).setPriority(PRIORITY_MIN).build();

            startForeground(NOTIFICATION_ID, notification);
        }

}

Another thing you need to do is modifying the type your using when initializing your Layout params, the following code will give you the right type depending on your API version

int type = 0;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        }
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
        }

now one last thing, to draw overlays you need to make sure you have the permission to draw overlays,

private boolean canDrawOnScreen() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        return canDrawOnScreenM();
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        return canDrawOverlaysUsingReflection(getApplicationContext());
    } else
        return true;
}

@RequiresApi(api = Build.VERSION_CODES.M)
private boolean canDrawOnScreenM() {
    return Settings.canDrawOverlays(getApplicationContext());
}


@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public static boolean canDrawOverlaysUsingReflection(Context context) {
    try {
        AppOpsManager manager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        Class clazz = AppOpsManager.class;
        Method dispatchMethod = clazz.getMethod("checkOp", new Class[]{int.class, int.class, String.class});
        //AppOpsManager.OP_SYSTEM_ALERT_WINDOW = 24
        int mode = (Integer) dispatchMethod.invoke(manager, new Object[]{24, Binder.getCallingUid(), context.getApplicationContext().getPackageName()});
        return AppOpsManager.MODE_ALLOWED == mode;
    } catch (Exception e) {
        return false;
    }

}

Now for the inflating part and handling the recycler view, first you need a reference to the recyclerview, you can do as following,

                RecyclerView myRecyclerView = mView.findViewById(R.id.your_recycler_id);

then you can process your RecyclerView as usual, setting the layout manager and the adapter.

Basil
  • 845
  • 9
  • 24
  • is job intend service necessary or can i achieve it with service itself –  Oct 14 '18 at 09:59
  • it is necessary for API>=26 – Basil Oct 14 '18 at 10:42
  • Hey im sorry... why is NOTIFICATION_ID showing in RED when i type it... whats the value of it? –  Oct 19 '18 at 10:56
  • because it's not defined in the code above, it's an int value that represents the id of your intent. you can add it and give any value you prefer – Basil Oct 19 '18 at 12:02