Skip to content

Instantly share code, notes, and snippets.

@Vixb1122
Created August 7, 2022 06:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Vixb1122/b37ce7a5b9c6d05cfc6f9c534ea7906c to your computer and use it in GitHub Desktop.
Save Vixb1122/b37ce7a5b9c6d05cfc6f9c534ea7906c to your computer and use it in GitHub Desktop.
Presentation solution with autosize support.
import android.content.Context;
import android.content.Intent;
import android.media.MediaRouter;
import android.os.Build;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.view.ContextThemeWrapper;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;
import androidx.annotation.MainThread;
import androidx.annotation.StyleRes;
import me.jessyan.autosize.AutoSizeCompat;
/**
* Created by <a href="mailto:xzx8023@outlook.com">Vixb</a> on 2022/8/7.
*/
public class SecondaryDisplayHelper {
private WindowManager windowManager;
private View view;
private boolean isAdd;
public SecondaryDisplayHelper(Context context, @StyleRes int themeResId, float designWidthInDp, ViewCreator viewCreator) {
MediaRouter router = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
MediaRouter.RouteInfo routeInfo = router.getSelectedRoute(MediaRouter.ROUTE_TYPE_LIVE_AUDIO
| MediaRouter.ROUTE_TYPE_LIVE_VIDEO
| MediaRouter.ROUTE_TYPE_USER);
if (routeInfo != null) {
Display display = routeInfo.getPresentationDisplay();
if (display != null) {
Context secondaryContext = new ContextThemeWrapper(context.createDisplayContext(display), themeResId);
AutoSizeCompat.autoConvertDensityBaseOnWidth(
secondaryContext.getResources(),
designWidthInDp * screenSize(context) / screenSize(secondaryContext)
);
windowManager = (WindowManager) secondaryContext.getSystemService(Context.WINDOW_SERVICE);
view = viewCreator.callback(secondaryContext);
}
}
}
@MainThread
void show() {
if (windowManager != null && view != null && !isAdd) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Context context = view.getContext();
if (!Settings.canDrawOverlays(context)) {
context.startActivity(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION));
Toast.makeText(context, "请允许该应用显示在其他应用的上层", Toast.LENGTH_SHORT).show();
} else {
windowManager.addView(view, new WindowManager.LayoutParams(getWindowType()));
isAdd = true;
}
} else {
windowManager.addView(view, new WindowManager.LayoutParams(getWindowType()));
isAdd = true;
}
}
}
@MainThread
void dismiss() {
if (windowManager != null && view != null && isAdd) {
isAdd = false;
windowManager.removeView(view);
}
}
interface ViewCreator {
View callback(Context context);
}
private float screenSize(Context context) {
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
return (float) Math.sqrt(displayMetrics.widthPixels * displayMetrics.widthPixels
+ displayMetrics.heightPixels * displayMetrics.heightPixels);
}
private int getWindowType() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
return WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
}
}
}
import android.content.Context
import android.content.Intent
import android.media.MediaRouter
import android.os.Build
import android.provider.Settings
import android.view.ContextThemeWrapper
import android.view.View
import android.view.WindowManager
import android.widget.Toast
import androidx.annotation.MainThread
import androidx.annotation.StyleRes
import me.jessyan.autosize.AutoSizeCompat
import kotlin.math.pow
import kotlin.math.sqrt
/**
* Created by [Vixb](mailto:xzx8023@outlook.com) on 2022/8/7
*/
class SecondaryDisplayHelper(
ctx: Context,
@StyleRes themeResId: Int,
designWidthInDp: Float,
block: Context.() -> View
) {
private lateinit var windowManager: WindowManager
private lateinit var view: View
private var isAdd = false
init {
ctx.apply {
(getSystemService(Context.MEDIA_ROUTER_SERVICE) as MediaRouter).getSelectedRoute(
MediaRouter.ROUTE_TYPE_LIVE_AUDIO
or MediaRouter.ROUTE_TYPE_LIVE_VIDEO
or MediaRouter.ROUTE_TYPE_USER
)?.presentationDisplay?.run {
ContextThemeWrapper(
createDisplayContext(this),
themeResId
).also { secondaryContext ->
AutoSizeCompat.autoConvertDensityBaseOnWidth(
secondaryContext.resources,
designWidthInDp * screenSize() / secondaryContext.screenSize()
)
this@SecondaryDisplayHelper.windowManager =
secondaryContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager
this@SecondaryDisplayHelper.view = block(secondaryContext)
}
}
}
}
@MainThread
fun show() {
if (::windowManager.isInitialized && ::view.isInitialized && !isAdd) {
isAdd = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
if (!Settings.canDrawOverlays(view.context)) {
view.context.startActivity(Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION))
Toast.makeText(view.context, "请允许该应用显示在其他应用的上层", Toast.LENGTH_SHORT).show()
return
} else {
windowManager.addView(view, WindowManager.LayoutParams(getWindowType()))
true
}
else {
windowManager.addView(view, WindowManager.LayoutParams(getWindowType()))
true
}
}
}
@MainThread
fun dismiss() {
if (::windowManager.isInitialized && ::view.isInitialized && isAdd) {
isAdd = false
windowManager.removeView(view)
}
}
private fun getWindowType() =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
} else {
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
}
private fun Context.screenSize() = resources.displayMetrics.run {
sqrt(
widthPixels.toFloat().pow(2) +
heightPixels.toFloat().pow(2)
)
}
}
@zhangzhuozhenshuai
Copy link

老师 这个有没有使用示例

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment