我正在尝试捕捉屏幕
View decorView = activity.getWindow().getDecorView();
decorView.setDrawingCacheEnabled(true);
Bitmap bitmap = decorView.getDrawingCache();
一切正常,我可以截取屏幕截图。 但对于一种情况,我面临一个问题。 但是当有Dialog片段时,Dialog片段的视图没有被捕获,但是部分可见的背景活动视图被捕获,就好像最顶层的活动的根视图一样。
答案 0 :(得分:1)
但是当有Dialog片段时,Dialog片段的视图没有被捕获,但是部分可见的背景活动视图被捕获,就好像最顶层的活动的根视图一样。
这是因为 #region Camera focus definition
public class CameraFocusData
{
public Position Position { get; set; }
public Distance Distance { get; set; }
}
private static void OnCustomPinsPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
CustomMap customMap = ((CustomMap)bindable);
if (customMap.CameraFocusParameter == CameraFocusReference.OnPins)
{
List<double> latitudes = new List<double>();
List<double> longitudes = new List<double>();
foreach (CustomPin pin in (newValue as List<CustomPin>))
{
latitudes.Add(pin.Position.Latitude);
longitudes.Add(pin.Position.Longitude);
}
double lowestLat = latitudes.Min();
double highestLat = latitudes.Max();
double lowestLong = longitudes.Min();
double highestLong = longitudes.Max();
double finalLat = (lowestLat + highestLat) / 2;
double finalLong = (lowestLong + highestLong) / 2;
double distance = DistanceCalculation.GeoCodeCalc.CalcDistance(lowestLat, lowestLong, highestLat, highestLong, DistanceCalculation.GeoCodeCalcMeasurement.Kilometers);
customMap.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(finalLat, finalLong), Distance.FromKilometers(distance * 0.7)));
}
}
private class DistanceCalculation
{
public static class GeoCodeCalc
{
public const double EarthRadiusInMiles = 3956.0;
public const double EarthRadiusInKilometers = 6367.0;
public static double ToRadian(double val) { return val * (Math.PI / 180); }
public static double DiffRadian(double val1, double val2) { return ToRadian(val2) - ToRadian(val1); }
public static double CalcDistance(double lat1, double lng1, double lat2, double lng2)
{
return CalcDistance(lat1, lng1, lat2, lng2, GeoCodeCalcMeasurement.Miles);
}
public static double CalcDistance(double lat1, double lng1, double lat2, double lng2, GeoCodeCalcMeasurement m)
{
double radius = GeoCodeCalc.EarthRadiusInMiles;
if (m == GeoCodeCalcMeasurement.Kilometers) { radius = GeoCodeCalc.EarthRadiusInKilometers; }
return radius * 2 * Math.Asin(Math.Min(1, Math.Sqrt((Math.Pow(Math.Sin((DiffRadian(lat1, lat2)) / 2.0), 2.0) + Math.Cos(ToRadian(lat1)) * Math.Cos(ToRadian(lat2)) * Math.Pow(Math.Sin((DiffRadian(lng1, lng2)) / 2.0), 2.0)))));
}
}
public enum GeoCodeCalcMeasurement : int
{
Miles = 0,
Kilometers = 1
}
}
#endregion
在一个单独的窗口中。我不知道你能做些什么。
答案 1 :(得分:0)
您可以借助反射获取应用的所有窗口的装饰视图列表。此列表不仅包含活动的装饰视图,还包含对话框和弹出窗口的装饰视图。
void processDialogWindow(Context context) {
WindowManager windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
Field globalField = Class.forName("android.view.WindowManagerImpl").getDeclaredField("mGlobal");
globalField.setAccessible(true);
Object globalFieldValue = globalField.get(windowManager);
List<?> viewsFieldValue = getViews(globalFieldValue);
for (int i = viewsFieldValue.size() - 1; i >= 0; i--) {
View decorView = (View)viewsFieldValue.get(i);
WindowManager.LayoutParams castedParams = (WindowManager.LayoutParams)decorView.getLayoutParams();
if (castedParams.type == WindowManager.LayoutParams.TYPE_APPLICATION) { // Dialog
//TODO: get decorView screenshot.
}
}
}
List<?> getViews(Object globalWindowManager) throws NoSuchFieldException, IllegalAccessException {
Field viewsField = globalWindowManager.getClass().getDeclaredField("mViews");
viewsField.setAccessible(true);
Object viewsFieldValue = viewsField.get(globalWindowManager);
if (viewsFieldValue instanceof List<?>)
return (List<?>)viewsFieldValue;
else if (viewsFieldValue instanceof View[]) {
return new ArrayList<>(Arrays.asList((View[])viewsFieldValue));
}
return null;
}
我已经在Android 5,6和7上测试了这种方法。当然,当你使用反射时,你应该检查一些字段的值是否为空并且确实具有预期的类型。因此,通过反射访问的内部数据结构可以在Android的未来版本中更改,也可以由设备供应商更改,即使在现有的Android版本中也是如此。为了简洁起见,我没有在这里添加空或错类型的检查。