@@ -7,120 +7,43 @@ folder:
77
88.. code-block :: python
99
10- from jnius import autoclass
11-
12- ...
13-
14- class CompassApp (App ):
15-
16- def __init__ (self , ** kwargs ):
17- """
18- Constructor of the Compass App
19-
20- 1) The Java Android API DisplayMetrics is called to get
21- information about the densityDpi factor of the Android device
22-
23- 2) The Kivy Python-For-Android Android API is called to
24- get access to the hardware sensors of the Android device
25-
26- """
27- super (CompassApp, self ).__init__ (** kwargs)
28- DisplayMetrics = autoclass(' android.util.DisplayMetrics' )
29- metrics = DisplayMetrics()
30- metrics.setToDefaults()
31- LoggerDisplayMetrics(metrics)
32- self .densityDpi = metrics.densityDpi
33-
34- Hardware = autoclass(' org.renpy.android.Hardware' )
35- self .hw = Hardware()
36- Logger.info(' COMPASS: Hardware Objects: %s ' % (str (dir (self .hw))))
37- Logger.info(' COMPASS: Hardware Sensors\n %s \n ' % (self .hw.getHardwareSensors()))
38-
39- def viewCompass (self , * largs ):
40- """
41- viewCompass calls the readSensor method of the
42- magneticFieldSensor instance of the generic3AxisSensor, it reads the
43- 3-tuple value of the magnetic field
44-
45- the declination angle is computed as the angle of the magnetic field
46- vector in the x,y-plane and the unity-vector of the y-axis.
47-
48- afterwards the rotateNeedle function rotates the needle as given
49- by the declination angle parameter
50- """
51- (x, y, z) = self .hw.magneticFieldSensor.readSensor()
52- declination = Vector(x,y).angle((0 ,1 ))
53- Logger.info(' COMPASS: viewCompass x=%s y=%s z=%s declination=%s ' % (x,y,z,declination))
54- self .needle.rotateNeedle(declination)
55-
56- def stopApp (self ,* largs ):
57- """
58- this function is called when pushed the stopButton, disables
59- the magneticFieldSensor and stops the app
60- """
61- self .hw.magneticFieldSensor.changeStatus(False )
62- Logger.info(' COMPASS: stop largs ' + str (largs))
63- self .stop()
64-
65- def build (self ):
66- """
67- Building all together:
68-
69- 1) Creating the parent widget and clearing it to white background color
70-
71- 2) Defining a suitable position and size of the CompassWidget, the
72- needleSize and the stopButtonHeight depending on the densityDpi value
73- given by DisplayMetrics
74-
75- 3) Creating an instance of the CompassWidget and adding it to the
76- parent widget and calling the appropriate build function
77-
78- 4) Creating an instance of the NeedleWidget and adding it also to the
79- parent widget and calling the appropriate build function
80-
81- 5) Creating an instance of a Button widget and adding it as stopButton
82- also to the parent widget and bind it with the stopApp function
83-
84- 6) Calling the instance method changeStatus of the magneticFieldSensor
85- instance with parameter True to enable the magnetic field sensor
86- and additionally calling the function schedule_interval of the Clock
87- class for a repeated call of the function viewCompass every second.
88- """
89- parent = FloatLayout(size = (500 ,500 ))
90- Window.clearcolor = (1 , 1 , 1 , 1 )
91-
92- if self .densityDpi == 240 :
93- CompassPos = Vector(50 ., 200 .)
94- CompassSize = Vector(400 ., 400 .)
95- needleSize = Vector(100 ., 60 .)
96- stopButtonHeight = 60
97- elif self .densityDpi == 320 :
98- CompassPos = Vector(75 ., 300 .)
99- CompassSize = Vector(600 ., 600 .)
100- needleSize = Vector(150 ., 90 .)
101- stopButtonHeight = 90
102- else :
103- Logger.info(' COMPASS: widget size should be adopted - minimum used for densityDpi=%s ' % (str (self .densityDpi)))
104- CompassPos = Vector(50 ., 200 .)
105- CompassSize = Vector(400 ., 400 .)
106- needleSize = Vector(100 ., 60 .)
107- stopButtonHeight = 60
108-
109- self .Compass = CompassWidget()
110- parent.add_widget(self .Compass)
111- self .Compass.build(pos = CompassPos,size = CompassSize)
112-
113- self .needle = NeedleWidget()
114- parent.add_widget(self .needle)
115- self .needle.build(center = CompassPos+ CompassSize/ 2 .,needleSize = needleSize)
116-
117- self .stopButton = Button(text = ' Stop' , pos_hint = {' right' :1 }, size_hint = (None ,None ), height = stopButtonHeight)
118- parent.add_widget(self .stopButton)
119- self .stopButton.bind(on_press = self .stopApp)
120-
121- self .hw.magneticFieldSensor.changeStatus(True )
122- Clock.schedule_interval(self .viewCompass, 1 .)
123- return parent
10+ # ... imports
11+ Hardware = autoclass(' org.renpy.android.Hardware' )
12+
13+ class CompassApp (App ):
14+
15+ needle_angle = NumericProperty(0 )
16+
17+ def build (self ):
18+ self ._anim = None
19+ Hardware.magneticFieldSensorEnable(True )
20+ Clock.schedule_interval(self .update_compass, 1 / 10 .)
21+
22+ def update_compass (self , * args ):
23+ # read the magnetic sensor from the Hardware class
24+ (x, y, z) = Hardware.magneticFieldSensorReading()
25+
26+ # calculate the angle
27+ needle_angle = Vector(x , y).angle((0 , 1 )) + 90 .
28+
29+ # animate the needle
30+ if self ._anim:
31+ self ._anim.stop(self )
32+ self ._anim = Animation(needle_angle = needle_angle, d = .2 , t = ' out_quad' )
33+ self ._anim.start(self )
34+
35+ def on_pause (self ):
36+ # when you are going on pause, don't forget to stop the sensor
37+ Hardware.magneticFieldSensorEnable(False )
38+ return True
39+
40+ def on_resume (self ):
41+ # reactivate the sensor when you are back to the app
42+ Hardware.magneticFieldSensorEnable(True )
43+
44+ if __name__ == ' __main__' :
45+ CompassApp().run()
46+
12447
12548 If you compile this app, you will get an APK which outputs the following
12649screen:
0 commit comments