HealthKit可能会提供不完整的数据?

时间:2015-12-18 21:56:46

标签: ios objective-c health-kit

有没有人有HealthKit似乎提供不完整数据的问题?使用以下查询:

showError(myForm, myForm.email)

我有时只看到部分数据而不是全部数据。此外,我看到的数据没有模式(它的数据块,不像我看到的最新或最早的数据)。 还有其他人遇到过这个吗?

这是我的确切代码:

HKAnchoredObjectQuery *newQuery = [[HKAnchoredObjectQuery alloc] initWithType:quantityType predicate:predicate anchor:anchor limit:HKObjectQueryNoLimit resultsHandler:^(HKAnchoredObjectQuery * _Nonnull query, NSArray<__kindof HKSample *> * _Nullable sampleObjects, NSArray<HKDeletedObject *> * _Nullable deletedObjects, HKQueryAnchor * _Nullable newAnchor, NSError * _Nullable error) {
                /*...etc...*/
            }];

2 个答案:

答案 0 :(得分:0)

问题是您对所执行的所有import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridBagLayout; import java.awt.Image; import java.awt.RenderingHints; import java.awt.Transparency; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.swing.ButtonModel; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; public class JavaApplication24 { public static void main(String[] args) { new JavaApplication24(); } public JavaApplication24() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } catch (IOException ex) { Logger.getLogger(JavaApplication24.class.getName()).log(Level.SEVERE, null, ex); } } }); } public class TestPane extends JPanel { public TestPane() throws IOException { setLayout(new GridBagLayout()); BufferedImage source = ImageIO.read(...)); // This the shape we want the source to be clipped to int size = Math.min(source.getWidth(), source.getHeight()); BufferedImage mask = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB); Graphics2D maskg = mask.createGraphics(); applyQualityRenderingHints(maskg); maskg.setColor(Color.WHITE); maskg.fillOval((source.getWidth() - size) / 2, (source.getHeight() - size) / 2, size, size); maskg.dispose(); // This will mask the source to the shape we've defined BufferedImage masked = applyMask(source, mask, AlphaComposite.DST_ATOP); BufferedImage normal = makeOutline(masked, Color.BLACK); BufferedImage rollOver = makeOutline(masked, Color.RED); JButton btn = new JButton(new ImageIcon(normal)); btn.setRolloverIcon(new ImageIcon(rollOver)); btn.setRolloverEnabled(true); btn.getModel().addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { ButtonModel model = (ButtonModel) e.getSource(); System.out.println("Change: " + model.isRollover()); } }); add(btn); } protected BufferedImage makeOutline(BufferedImage original, Color color) { // This generates a image which is completely filled with the provided color BufferedImage outline = new BufferedImage(original.getWidth(), original.getHeight(), BufferedImage.TYPE_INT_ARGB); Graphics2D outlineg = outline.createGraphics(); applyQualityRenderingHints(outlineg); outlineg.setColor(color); outlineg.fillRect(0, 0, outline.getWidth(), outline.getHeight()); outlineg.dispose(); // This applies a AlphaComposite to mask the outline with the shape // of the original image outline = applyMask(original, outline, AlphaComposite.SRC_ATOP); // Now we make it slightly larger... double scale = 1.05; outline = getScaledInstanceToFit(outline, scale); // And we combine the images outlineg = outline.createGraphics(); int x = (outline.getWidth() - original.getWidth()) / 2; int y = (outline.getHeight() - original.getHeight()) / 2; outlineg.drawImage(original, x, y, this); outlineg.dispose(); return outline; } public BufferedImage applyMask(BufferedImage sourceImage, BufferedImage maskImage) { return applyMask(sourceImage, maskImage, AlphaComposite.DST_IN); } public BufferedImage applyMask(BufferedImage sourceImage, BufferedImage maskImage, int method) { BufferedImage maskedImage = null; if (sourceImage != null) { int width = maskImage.getWidth(null); int height = maskImage.getHeight(null); maskedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics2D mg = maskedImage.createGraphics(); applyQualityRenderingHints(mg); int x = (width - sourceImage.getWidth(null)) / 2; int y = (height - sourceImage.getHeight(null)) / 2; mg.drawImage(sourceImage, x, y, null); mg.setComposite(AlphaComposite.getInstance(method)); mg.drawImage(maskImage, 0, 0, null); mg.dispose(); } return maskedImage; } public void applyQualityRenderingHints(Graphics2D g2d) { g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE); g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); // g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); } public BufferedImage getScaledInstanceToFit(BufferedImage img, double scale) { int width = (int)(img.getWidth() * scale); int height = (int)(img.getHeight()* scale); return getScaledInstanceToFit(img, new Dimension(width, height)); } public BufferedImage getScaledInstanceToFit(BufferedImage img, Dimension size) { double scaleFactor = getScaleFactorToFit(new Dimension(img.getWidth(), img.getHeight()), size); return getScaledInstance(img, scaleFactor); } public double getScaleFactorToFit(Dimension original, Dimension toFit) { double dScale = 1d; if (original != null && toFit != null) { double dScaleWidth = getScaleFactor(original.width, toFit.width); double dScaleHeight = getScaleFactor(original.height, toFit.height); dScale = Math.min(dScaleHeight, dScaleWidth); } return dScale; } public double getScaleFactor(int iMasterSize, int iTargetSize) { return (double) iTargetSize / (double) iMasterSize; } public BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor) { return getScaledInstance(img, dScaleFactor, RenderingHints.VALUE_INTERPOLATION_BILINEAR, true); } protected BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor, Object hint, boolean bHighQuality) { BufferedImage imgScale = img; int iImageWidth = (int) Math.round(img.getWidth() * dScaleFactor); int iImageHeight = (int) Math.round(img.getHeight() * dScaleFactor); if (dScaleFactor <= 1.0d) { imgScale = getScaledDownInstance(img, iImageWidth, iImageHeight, hint, bHighQuality); } else { imgScale = getScaledUpInstance(img, iImageWidth, iImageHeight, hint, bHighQuality); } return imgScale; } protected BufferedImage getScaledDownInstance(BufferedImage img, int targetWidth, int targetHeight, Object hint, boolean higherQuality) { int type = (img.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB; BufferedImage ret = (BufferedImage) img; if (targetHeight > 0 || targetWidth > 0) { int w, h; if (higherQuality) { w = img.getWidth(); h = img.getHeight(); } else { w = targetWidth; h = targetHeight; } do { if (higherQuality && w > targetWidth) { w /= 2; if (w < targetWidth) { w = targetWidth; } } if (higherQuality && h > targetHeight) { h /= 2; if (h < targetHeight) { h = targetHeight; } } BufferedImage tmp = new BufferedImage(Math.max(w, 1), Math.max(h, 1), type); Graphics2D g2 = tmp.createGraphics(); g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint); g2.drawImage(ret, 0, 0, w, h, null); g2.dispose(); ret = tmp; } while (w != targetWidth || h != targetHeight); } else { ret = new BufferedImage(1, 1, type); } return ret; } protected BufferedImage getScaledUpInstance(BufferedImage img, int targetWidth, int targetHeight, Object hint, boolean higherQuality) { int type = BufferedImage.TYPE_INT_ARGB; BufferedImage ret = (BufferedImage) img; int w, h; if (higherQuality) { w = img.getWidth(); h = img.getHeight(); } else { w = targetWidth; h = targetHeight; } do { if (higherQuality && w < targetWidth) { w *= 2; if (w > targetWidth) { w = targetWidth; } } if (higherQuality && h < targetHeight) { h *= 2; if (h > targetHeight) { h = targetHeight; } } BufferedImage tmp = new BufferedImage(w, h, type); Graphics2D g2 = tmp.createGraphics(); g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint); g2.drawImage(ret, 0, 0, w, h, null); g2.dispose(); ret = tmp; tmp = null; } while (w != targetWidth || h != targetHeight); return ret; } } } 实例使用相同的锚点。它们具有不同的谓词,因此如果重用单个锚点,结果将没有意义。有几种方法可以在不执行多个查询的情况下实现您在此代码段中尝试执行的操作。正如我在回答您的其他问题时提到的那样,我建议您只使用一个HKAnchoredObjectQuery,然后通过查看HKAnchoredObjectQuery获取的source属性来处理结果。

答案 1 :(得分:0)

此外,将 HKObjectQueryNoLimit 与 HKAnchoredObjectQuery 和 Active Energy 等类型一起使用可能非常危险。至少在较旧的 iPhone 上,我们的测试表明,在某些情况下,我们的某些用户的 HealthKit 数据库中显然有一些 Active Energy HKSamples 的奇怪结构,因此他们在 100 天内拥有大约 100 万个这样的样本。在这些情况下 HKAnchoredObjectQuery 只会卡在里面并且永远不会返回到它的完成处理程序......也许这是早期 iOS-es 上的一个错误,现在它已经修复,但你永远不知道 - 它可以像在 100 个案例中一样重现我们的 30 万用户群。我们通过使用 100.000 个样本限制而不是无限制来解决这个问题,然后如果未达到限制,则递归地进行这些锚定查询