Bonjour à tous, je suis en train de dévélopper une interface graphique sous Android 2.2 qui me permettra d'afficher la vitesse et le niveau de batterie d'un Kart électrique via liaison Bluetooth. Mon projet se découpe en 4 fichiers.java et 1 fichier.xml
Mon projet Interface graphique fonctionne bien tout seul. Mon projet Bluetooth fonctionne bien tout seul aussi.
Le problème vient quand j'assemble les 2 projets. Quand je lance mon application il y a une fermeture soudaine. En effet je sais d'où vient le problème mais je ne sais pas pourquoi et comment le résoudre. Lorsque dans mon fichier Interface.java essai d'utiliser une classe de mon fichier BtInterface il y a une Erreur sous LogCat:
La source d'erreur vient de:
Voici mon InterfaceActivity.java
Code : Sélectionner tout - Visualiser dans une fenêtre à part bt = new BtInterface(handlerStatus, handler);
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359 package com.Gabriel.android.Interface; import android.app.Activity; import android.os.Bundle; import android.view.View.OnClickListener; // Permet la reaction apres un click import android.widget.TabHost; import android.widget.TextView; import android.widget.Toast; import android.widget.TabHost.TabSpec; import android.os.Handler; import android.os.Message; import android.view.View; import android.graphics.Color; import com.androidplot.ui.AnchorPosition; import com.androidplot.ui.widget.Widget; import com.androidplot.xy.LineAndPointFormatter; import com.androidplot.xy.XLayoutStyle; import com.androidplot.xy.XYPlot; import com.androidplot.xy.LineAndPointRenderer; import com.androidplot.xy.YLayoutStyle; import android.content.res.Resources; import android.graphics.drawable.LevelListDrawable; import android.widget.ImageView; import com.Gabriel.android.Interface.BtInterface; //import com.androidplot.xy.BoundaryMode; //import com.androidplot.Plot; //import android.content.Intent; //import com.androidplot.xy.XYStepMode; public final class InterfaceActivity extends Activity { private TabHost monTabHost; /** Ajouter ceci pour utiliser Tabhost*/ private XYPlot mySimpleXYPlot; private int batteryPercent; private ImageView image; private ImageView batterieImage; private LevelListDrawable drawable1; private LevelListDrawable drawable; // The Handler to refresh the ImageViewprivate private TextView logview; //private Button disconnect,connection; private BtInterface bt = null; private long lastTime = 0; final Handler handler = new Handler() { public void handleMessage(Message msg) { String data = msg.getData().getString("receivedData"); long t = System.currentTimeMillis(); if(t-lastTime > 100) {// Pour éviter que les messages soit coupés logview.append("\n"); lastTime = System.currentTimeMillis(); } logview.append(data); } }; final Handler handlerStatus = new Handler() { public void handleMessage(Message msg) { int co = msg.arg1; if(co == 1) { logview.append("Connected\n"); logview.append("Bienvenue\n"); String device = bt.getDevice().getName().toString(); Toast.makeText(getApplicationContext(),"connected to " + device, Toast.LENGTH_LONG).show(); } if(co != 1) { logview.append("Disconnected\n"); } } }; Handler updateImage = new Handler() { public void handleMessage(android.os.Message msg) {// Update batterieImage. image.setImageLevel(msg.what); batterieImage.setImageLevel(msg.what); }; }; // private ImageView imageView; // private int m_level=0; /** Called when the activity is first created. */ /** * Appelée lorsque lactivité est créée. * Permet de restaurer létat de linterface * utilisateur grâce au paramètre savedInstanceState. */ @Override public void onCreate(Bundle savedInstanceState) { // Placez votre code ici super.onCreate(savedInstanceState); setContentView(R.layout.main); //bt = new BtInterface(handlerStatus, handler); Resources res=getResources(); drawable=(LevelListDrawable)res.getDrawable(R.drawable.image); image=(ImageView)findViewById(R.id.battery_anim); image.setImageDrawable(drawable); Resources res1=getResources(); drawable1=(LevelListDrawable)res1.getDrawable(R.drawable.batterie); batterieImage=(ImageView)findViewById(R.id.battery_niveau); batterieImage.setImageDrawable(drawable1); new Thread(new Runnable() { public void run() { while (true) { batteryPercent=(int) (Math.random()*100); updateImage.sendEmptyMessage(batteryPercent); // Notify the change to Handler. try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // Update battery every 3s. } } }).start(); // initialize our XYPlot reference: mySimpleXYPlot = (XYPlot) findViewById(R.id.mySimpleXYPlot); // add a new series mySimpleXYPlot.addSeries(new SimpleXYSeries(), LineAndPointRenderer.class, new LineAndPointFormatter(Color.rgb(0, 200, 0), Color.rgb(200, 0, 0), null)); // reduce the number of range labels //mySimpleXYPlot.getGraphWidget().setRangeTicksPerLabel(4); // reposition the domain label to look a little cleaner: Widget domainLabelWidget = mySimpleXYPlot.getDomainLabelWidget(); mySimpleXYPlot.position(domainLabelWidget, // the widget to position 45, // x position value, in this case 45 pixels XLayoutStyle.ABSOLUTE_FROM_LEFT, // how the x position value is applied, in this case from the left 0, // y position value YLayoutStyle.ABSOLUTE_FROM_BOTTOM, // how the y position is applied, in this case from the bottom AnchorPosition.LEFT_BOTTOM); // point to use as the origin of the widget being positioned // get rid of the visual aids for positioning: mySimpleXYPlot.disableAllMarkup(); // Récupération du TabHost monTabHost =(TabHost) findViewById(R.id.TabHost01); // Avant dajouter des onglets, il faut impérativement appeler la méthode // setup() du TabHost monTabHost.setup(); // Nous ajoutons les 3 onglets dans notre TabHost // Nous paramétrons le 1er Onglet TabSpec spec = monTabHost.newTabSpec("Presentation"); // Nous paramétrons le texte qui saffichera dans longlet // ainsi que limage qui se positionnera // au dessus du texte. spec.setIndicator(" ",getResources().getDrawable(R.drawable.presentatione)); // On spécifie le Layout qui saffichera lorsque longlet sera sélectionné spec.setContent(R.id.Onglet1); // On ajoute longlet dans notre TabHost monTabHost.addTab(spec); TabSpec spec1 = monTabHost.newTabSpec("Commande"); spec1.setIndicator(" ",getResources().getDrawable(R.drawable.commande)); spec1.setContent(R.id.Onglet2); monTabHost.addTab(spec1); TabSpec spec2 = monTabHost.newTabSpec("Courbes"); spec2.setIndicator(" ",getResources().getDrawable(R.drawable.courbe)); spec2.setContent(R.id.Onglet3); monTabHost.addTab(spec2); monTabHost.setOnTabChangedListener ( new TabHost.OnTabChangeListener () { public void onTabChanged(String tabId) { // Vous pourrez exécuter du code lorsquun // onglet est cliqué. Pour déterminer // quel onglet a été cliqué, il // vous suffira de vérifier le tabId envoyé lors // du clic et dexécuter votre code en // conséquence. Toast.makeText(InterfaceActivity.this, "Longlet " + tabId + " a été cliqué", Toast.LENGTH_SHORT).show(); } } ); //bt.connect(); //BtInterface(handlerStatus, handler).connect(); findViewById(R.id.ImageButton04).setOnClickListener(connectListener); findViewById(R.id.ImageButton05).setOnClickListener(disconnectListener); } private OnClickListener connectListener = new OnClickListener() { public void onClick(View v) { //bt.connect(); //disconnect.setEnabled(true); //send.setEnabled(true); String connecter = "Connecté"; Toast.makeText(getApplicationContext(), connecter, Toast.LENGTH_LONG).show(); } }; private OnClickListener disconnectListener = new OnClickListener() { public void onClick(View v) { //bt.close(); //disconnect.setEnabled(false); //send.setEnabled(false); String deconnect = "Deconnecté"; Toast.makeText(getApplicationContext(), deconnect, Toast.LENGTH_LONG).show(); } }; @Override public void onDestroy() { // Placez votre code ici super.onDestroy(); } /** * Appelée lorsque lactivité démarre. * Permet dinitialiser les contrôles. */ @Override public void onStart() { super.onStart(); // Placezvotre code ici } /** * Appelée lorsque lactivité passe en arrière plan. * Libérez les écouteurs, arrêtez les threads, votre activité * peut disparaître de la mémoire. */ @Override public void onStop() { // Placez votre code ici super.onStop(); } /** * Appelée lorsque lactivité sort de son état de veille. */ @Override public void onRestart() { super.onRestart(); //Placez votre code ici } /** * Appelée lorsque que lactivité est suspendue. * Stoppez les actions qui consomment des ressources. * Lactivité va passer en arrière-plan. */ @Override public void onPause() { //Placez votre code ici super.onPause(); } /** * Appelée après le démarrage ou une pause. * Relancez les opérations arrêtées (threads). * Mettez à jour votre application et vérifiez vos écouteurs. */ @Override public void onResume() { super.onResume(); // Placez votre code ici } /** * Appelée lorsque l activité termine son cycle visible. * Sauvez les données importantes. */ @Override public void onSaveInstanceState(Bundle savedInstanceState) { // Placez votre code ici // sans quoi lactivité aura perdu son état // lors de son réveil super.onSaveInstanceState(savedInstanceState); } /** * Appelée après onCreate. * Les données sont rechargées et linterface utilisateur. * est restaurée dans le bon état. */ }
BtInterface.java
Thermometer.java
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187 package com.Gabriel.android.Interface; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Set; import java.util.UUID; //import android.widget.TextView; //import android.widget.Toast; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; //import android.widget.Toast; public class BtInterface { private BluetoothDevice device = null; private BluetoothSocket socket = null; private InputStream receiveStream = null; private OutputStream sendStream = null; public String rdata = "Interface Bluetooth"; private ReceiverThread receiverThread; Handler handler; public BtInterface(Handler hstatus, Handler h) //constructeur { Set<BluetoothDevice> setpairedDevices = BluetoothAdapter.getDefaultAdapter().getBondedDevices(); BluetoothDevice[] pairedDevices = (BluetoothDevice[]) setpairedDevices.toArray(new BluetoothDevice[setpairedDevices.size()]); for(int i=0;i<pairedDevices.length;i++) { if(pairedDevices[i].getName().contains("GAGURA-PC")) { device = pairedDevices[i]; try { socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")); receiveStream = socket.getInputStream(); sendStream = socket.getOutputStream(); } catch (IOException e) { e.printStackTrace(); } break; } } handler = hstatus; receiverThread = new ReceiverThread(h); } public void sendData(String data) { sendData(data, false); } public void sendData(String data, boolean deleteScheduledData) { try { sendStream.write(data.getBytes()); sendStream.flush(); } catch (IOException e) { e.printStackTrace(); } } public void connect() { new Thread() { @Override public void run() { try { socket.connect(); Message msg = handler.obtainMessage(); msg.arg1 = 1; handler.sendMessage(msg); receiverThread.start(); } catch (IOException e) { Log.v("N", "Connection Failed : "+e.getMessage()); e.printStackTrace(); } } }.start(); } public void close() { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } public BluetoothDevice getDevice() { return device; } public String getdat() { return rdata; } private class ReceiverThread extends Thread { Handler handler; ReceiverThread(Handler h) { handler = h; } public String getdata() { return rdata; } @Override public void run() { while(true) { try { // On teste si des données sont disponibles if(receiveStream.available() > 0) { byte buffer[] = new byte[100]; // On lit les données, k représente le nombre de bytes lu int k = receiveStream.read(buffer, 0, 100); if(k > 0) { byte rawdata[] = new byte[k]; for(int i=0;i<k;i++) // On convertit les données en String rawdata[i] = buffer[i]; String data = new String(rawdata); rdata =data; rdata=getdata(); // On envoie les données dans le thread de l'UI pour les affichées Message msg = handler.obtainMessage(); Bundle b = new Bundle(); b.putString("receivedData", data); msg.setData(b); handler.sendMessage(msg); } } } catch (IOException e) { e.printStackTrace(); } } }} }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518 package com.Gabriel.android.Interface; import java.util.List; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.LightingColorFilter; import android.graphics.LinearGradient; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.RadialGradient; import android.graphics.RectF; import android.graphics.Shader; import android.graphics.Typeface; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.os.Handler; import android.os.Parcelable; import android.util.AttributeSet; import android.util.Log; import android.view.View; public final class Thermometer extends View implements SensorEventListener { private static final String TAG = Thermometer.class.getSimpleName(); private Handler handler; // drawing tools private RectF rimRect; private Paint rimPaint; private Paint rimCirclePaint; private RectF faceRect; private Bitmap faceTexture; private Paint facePaint; private Paint rimShadowPaint; private Paint scalePaint; private RectF scaleRect; private Paint titlePaint; private Path titlePath; private Paint logoPaint; private Bitmap logo; private Matrix logoMatrix; private float logoScale; private Paint handPaint; private Path handPath; private Paint handScrewPaint; private Paint backgroundPaint; // end drawing tools private Bitmap background; // holds the cached static part // scale configuration private static final int totalNicks = 30; private static final float degreesPerNick = 360.0f / totalNicks; private static final int centerDegree = 20; // the one in the top center (12 o'clock) private static final int minDegrees = 0; private static final int maxDegrees = 40; // hand dynamics -- all are angular expressed in F degrees private boolean handInitialized = true; private float handPosition = 30; private float handTarget = minDegrees; private float handVelocity = 0.0f; private float handAcceleration = 0.0f; private long lastHandMoveTime = -1L; public Thermometer(Context context) { super(context); init(); } public Thermometer(Context context, AttributeSet attrs) { super(context, attrs); init(); } public Thermometer(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); attachToSensor(); } @Override protected void onDetachedFromWindow() { detachFromSensor(); super.onDetachedFromWindow(); } @Override protected void onRestoreInstanceState(Parcelable state) { Bundle bundle = (Bundle) state; Parcelable superState = bundle.getParcelable("superState"); super.onRestoreInstanceState(superState); handInitialized = bundle.getBoolean("handInitialized"); handPosition = bundle.getFloat("handPosition"); handTarget = bundle.getFloat("handTarget"); handVelocity = bundle.getFloat("handVelocity"); handAcceleration = bundle.getFloat("handAcceleration"); lastHandMoveTime = bundle.getLong("lastHandMoveTime"); } @Override protected Parcelable onSaveInstanceState() { Parcelable superState = super.onSaveInstanceState(); Bundle state = new Bundle(); state.putParcelable("superState", superState); state.putBoolean("handInitialized", handInitialized); state.putFloat("handPosition", handPosition); state.putFloat("handTarget", handTarget); state.putFloat("handVelocity", handVelocity); state.putFloat("handAcceleration", handAcceleration); state.putLong("lastHandMoveTime", lastHandMoveTime); return state; } private void init() { handler = new Handler(); initDrawingTools(); } private String getTitle() { return "Kart Electrique - GE5E - 2011/2012"; } // Capture de la grandeur à afficher sur le tachymètre -------------------------- private SensorManager getSensorManager() { return (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE); } private void attachToSensor() { SensorManager sensorManager = getSensorManager(); List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_TEMPERATURE); if (sensors.size() > 0) { Sensor sensor = sensors.get(0); sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_FASTEST, handler); } else { Log.e(TAG, "No temperature sensor found"); } } private void detachFromSensor() { SensorManager sensorManager = getSensorManager(); sensorManager.unregisterListener(this); } // ------------------------------------------------------------------------------- private void initDrawingTools() { rimRect = new RectF(0.1f, 0.1f, 0.9f, 0.9f); // the linear gradient is a bit skewed for realism rimPaint = new Paint(); rimPaint.setFlags(Paint.ANTI_ALIAS_FLAG); rimPaint.setShader(new LinearGradient(0.40f, 0.0f, 0.60f, 1.0f, Color.rgb(0xf0, 0xf5, 0xf0), Color.rgb(0x30, 0x31, 0x30), Shader.TileMode.CLAMP)); rimCirclePaint = new Paint(); rimCirclePaint.setAntiAlias(true); rimCirclePaint.setStyle(Paint.Style.STROKE); rimCirclePaint.setColor(Color.argb(0x4f, 0x33, 0x36, 0x33)); rimCirclePaint.setStrokeWidth(0.005f); float rimSize = 0.02f; faceRect = new RectF(); faceRect.set(rimRect.left + rimSize, rimRect.top + rimSize, rimRect.right - rimSize, rimRect.bottom - rimSize); faceTexture = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.plastic); BitmapShader paperShader = new BitmapShader(faceTexture, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR); Matrix paperMatrix = new Matrix(); facePaint = new Paint(); facePaint.setFilterBitmap(true); paperMatrix.setScale(1.0f / faceTexture.getWidth(), 1.0f / faceTexture.getHeight()); paperShader.setLocalMatrix(paperMatrix); facePaint.setStyle(Paint.Style.FILL); facePaint.setShader(paperShader); rimShadowPaint = new Paint(); rimShadowPaint.setShader(new RadialGradient(0.5f, 0.5f, faceRect.width() / 2.0f, new int[] { 0x00000000, 0x00000500, 0x50000500 }, new float[] { 0.96f, 0.96f, 0.99f }, Shader.TileMode.MIRROR)); rimShadowPaint.setStyle(Paint.Style.FILL); scalePaint = new Paint(); scalePaint.setStyle(Paint.Style.STROKE); scalePaint.setColor(0x9f004d0f); scalePaint.setStrokeWidth(0.005f); scalePaint.setAntiAlias(true); scalePaint.setTextSize(0.045f); scalePaint.setTypeface(Typeface.SANS_SERIF); scalePaint.setTextScaleX(0.8f); scalePaint.setTextAlign(Paint.Align.CENTER); float scalePosition = 0.10f; scaleRect = new RectF(); scaleRect.set(faceRect.left + scalePosition, faceRect.top + scalePosition, faceRect.right - scalePosition, faceRect.bottom - scalePosition); titlePaint = new Paint(); titlePaint.setColor(0xaf946109); titlePaint.setAntiAlias(true); titlePaint.setTypeface(Typeface.DEFAULT_BOLD); titlePaint.setTextAlign(Paint.Align.CENTER); titlePaint.setTextSize(0.05f); titlePaint.setTextScaleX(0.8f); titlePath = new Path(); titlePath.addArc(new RectF(0.24f, 0.24f, 0.76f, 0.76f), -180.0f, -180.0f); logoPaint = new Paint(); logoPaint.setFilterBitmap(true); logo = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.logo); logoMatrix = new Matrix(); logoScale = (1.0f / logo.getWidth()) * 0.3f;; logoMatrix.setScale(logoScale, logoScale); handPaint = new Paint(); handPaint.setAntiAlias(true); handPaint.setColor(0xff392f2c); handPaint.setShadowLayer(0.01f, -0.005f, -0.005f, 0x7f000000); handPaint.setStyle(Paint.Style.FILL); handPath = new Path(); handPath.moveTo(0.5f, 0.5f + 0.2f); handPath.lineTo(0.5f - 0.010f, 0.5f + 0.2f - 0.007f); handPath.lineTo(0.5f - 0.002f, 0.5f - 0.32f); handPath.lineTo(0.5f + 0.002f, 0.5f - 0.32f); handPath.lineTo(0.5f + 0.010f, 0.5f + 0.2f - 0.007f); handPath.lineTo(0.5f, 0.5f + 0.2f); handPath.addCircle(0.5f, 0.5f, 0.025f, Path.Direction.CW); handScrewPaint = new Paint(); handScrewPaint.setAntiAlias(true); handScrewPaint.setColor(0xff493f3c); handScrewPaint.setStyle(Paint.Style.FILL); backgroundPaint = new Paint(); backgroundPaint.setFilterBitmap(true); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { Log.d(TAG, "Width spec: " + MeasureSpec.toString(widthMeasureSpec)); Log.d(TAG, "Height spec: " + MeasureSpec.toString(heightMeasureSpec)); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int chosenWidth = chooseDimension(widthMode, widthSize); int chosenHeight = chooseDimension(heightMode, heightSize); int chosenDimension = Math.min(chosenWidth, chosenHeight); setMeasuredDimension(chosenDimension, chosenDimension); } private int chooseDimension(int mode, int size) { if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) { return size; } else { // (mode == MeasureSpec.UNSPECIFIED) return getPreferredSize(); } } // in case there is no size specified private int getPreferredSize() { return 300; } private void drawRim(Canvas canvas) { // first, draw the metallic body canvas.drawOval(rimRect, rimPaint); // now the outer rim circle canvas.drawOval(rimRect, rimCirclePaint); } private void drawFace(Canvas canvas) { canvas.drawOval(faceRect, facePaint); // draw the inner rim circle canvas.drawOval(faceRect, rimCirclePaint); // draw the rim shadow inside the face canvas.drawOval(faceRect, rimShadowPaint); } private void drawScale(Canvas canvas) { canvas.drawOval(scaleRect, scalePaint); canvas.save(Canvas.MATRIX_SAVE_FLAG); for (int i = 0; i < totalNicks; ++i) { float y1 = scaleRect.top; float y2 = y1 - 0.020f; canvas.drawLine(0.5f, y1, 0.5f, y2, scalePaint); if (i % 5 == 0) { int value = nickToDegree(i); if (value >= minDegrees && value <= maxDegrees) { String valueString = Integer.toString(value); canvas.drawText(valueString, 0.5f, y2 - 0.015f, scalePaint); } } canvas.rotate(degreesPerNick, 0.5f, 0.5f); } canvas.restore(); } private int nickToDegree(int nick) { int rawDegree = ((nick < totalNicks / 2) ? nick : (nick - totalNicks)) * 2; int shiftedDegree = rawDegree + centerDegree; return shiftedDegree; } private float degreeToAngle(float degree) { return (degree - centerDegree) / 2.0f * degreesPerNick; } private void drawTitle(Canvas canvas) { String title = getTitle(); canvas.drawTextOnPath(title, titlePath, 0.0f,0.0f, titlePaint); } private void drawLogo(Canvas canvas) { canvas.save(Canvas.MATRIX_SAVE_FLAG); canvas.translate(0.5f - logo.getWidth() * logoScale / 2.0f, 0.5f - logo.getHeight() * logoScale / 2.0f); int color = 0x00000000; float position = getRelativeTemperaturePosition(); if (position < 0) { color |= (int) ((0xf0) * -position); // blue } else { color |= ((int) ((0xf0) * position)) << 16; // red } //Log.d(TAG, "*** " + Integer.toHexString(color)); LightingColorFilter logoFilter = new LightingColorFilter(0xff338822, color); logoPaint.setColorFilter(logoFilter); canvas.drawBitmap(logo, logoMatrix, logoPaint); canvas.restore(); } private void drawHand(Canvas canvas) { if (handInitialized) { float handAngle = degreeToAngle(handPosition); canvas.save(Canvas.MATRIX_SAVE_FLAG); canvas.rotate(handAngle, 0.5f, 0.5f); canvas.drawPath(handPath, handPaint); canvas.restore(); canvas.drawCircle(0.5f, 0.5f, 0.01f, handScrewPaint); } } private void drawBackground(Canvas canvas) { if (background == null) { Log.w(TAG, "Background not created"); } else { canvas.drawBitmap(background, 0, 0, backgroundPaint); } } @Override protected void onDraw(Canvas canvas) { drawBackground(canvas); float scale = (float) getWidth(); canvas.save(Canvas.MATRIX_SAVE_FLAG); canvas.scale(scale, scale); drawLogo(canvas); drawHand(canvas); canvas.restore(); if (handNeedsToMove()) { moveHand(); } } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { Log.d(TAG, "Size changed to " + w + "x" + h); regenerateBackground(); } private void regenerateBackground() { // free the old bitmap if (background != null) { background.recycle(); } background = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); Canvas backgroundCanvas = new Canvas(background); float scale = (float) getWidth(); backgroundCanvas.scale(scale, scale); drawRim(backgroundCanvas); drawFace(backgroundCanvas); drawScale(backgroundCanvas); drawTitle(backgroundCanvas); } private boolean handNeedsToMove() { return Math.abs(handPosition - handTarget) > 0.01f; } private void moveHand() { if (! handNeedsToMove()) { return; } if (lastHandMoveTime != -1L) { long currentTime = System.currentTimeMillis(); float delta = (currentTime - lastHandMoveTime) / 1000.0f; float direction = Math.signum(handVelocity); if (Math.abs(handVelocity) < 90.0f) { handAcceleration = 5.0f * (handTarget - handPosition); } else { handAcceleration = 0.0f; } handPosition += handVelocity * delta; handVelocity += handAcceleration * delta; if ((handTarget - handPosition) * direction < 0.01f * direction) { handPosition = handTarget; handVelocity = 0.0f; handAcceleration = 0.0f; lastHandMoveTime = -1L; } else { lastHandMoveTime = System.currentTimeMillis(); } invalidate(); } else { lastHandMoveTime = System.currentTimeMillis(); moveHand(); } } // Changement des aiguilles du tachymètre --------------------------------------- public void onAccuracyChanged(Sensor sensor, int accuracy) { } public void onSensorChanged(SensorEvent sensorEvent) { if (sensorEvent.values.length > 0) { float temperatureC = sensorEvent.values[0]; //Log.i(TAG, "*** Temperature: " + temperatureC); float temperatureF = (9.0f / 5.0f) * temperatureC + 32.0f; setHandTarget(temperatureF); } else { Log.w(TAG, "Empty sensor event received"); } } private float getRelativeTemperaturePosition() { if (handPosition < centerDegree) { return - (centerDegree - handPosition) / (float) (centerDegree - minDegrees); } else { return (handPosition - centerDegree) / (float) (maxDegrees - centerDegree); } } private void setHandTarget(float temperature) { if (temperature < minDegrees) { temperature = minDegrees; } else if (temperature > maxDegrees) { temperature = maxDegrees; } handTarget = temperature; handInitialized = true; invalidate(); } // --------------------------------------------------------------------------------- }
SimpleXYSeries.java
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 package com.Gabriel.android.Interface; import com.androidplot.series.XYSeries; public class SimpleXYSeries implements XYSeries { private static final int[] vals = {0, 25, 35, 2, 40, 30, 29, 0, 34, 6}; // f(x) = x public Number getX(int index) { return index; } // range begins at 0 public Number getMinX() { return 0; } // range ends at 9 public Number getMaxX() { return 9; } public String getTitle() { return "Vitesse Instantanée"; } // range consists of all the values in vals public int size() { return vals.length; } public void onReadBegin() { } public void onReadEnd() { } // return vals[index] public Number getY(int index) { // make sure index isnt something unexpected: if(index < 0 || index > 9) { throw new IllegalArgumentException("Only values between 0 and 9 are allowed."); } return vals[index]; } // smallest value in vals is 0 public Number getMinY() { return 0; } // largest value in vals is 99 public Number getMaxY() { return 40; } }
main.xml
AndroidManifest.xml
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff" > <!-- Le TabHost qui contient tous les éléments de nos onglets--> <TabHost android:id="@+id/TabHost01" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <!-- TabWidget qui sert à afficher les onglets --> <TabWidget android:layout_width="fill_parent" android:id="@android:id/tabs" android:layout_height="wrap_content"></TabWidget> <!-- contenu de nos onglets. --> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="fill_parent" android:layout_height="fill_parent" > <!-- Contenu de longlet N°1 --> <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:scrollbars="vertical" android:id="@+id/Onglet1" android:background="@drawable/presentation" > </LinearLayout> <!-- Contenu de longlet N°2 --> <ScrollView android:id="@+id/ScrollView01" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/Onglet2" > <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="left|top" > <LinearLayout android:orientation="horizontal" android:layout_width="210px" android:layout_height="280px" android:gravity="right|center_vertical" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/battery_niveau" > </ImageView> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/battery_anim" > </ImageView> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="310px" android:layout_height="280px" android:gravity="right" android:weightSum="2.0" > <com.Gabriel.android.Interface.Thermometer android:id="@+id/thermometer" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="2.0" /> </LinearLayout> <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="280px" > <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="150px" android:gravity="bottom" > <TextView android:text="Heure" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#000" android:textSize="25dip" > </TextView> <!-- Horloge Digital --> <DigitalClock android:text="Horloge" android:id="@+id/DigitalClock01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#000" android:textSize="40dip" > </DigitalClock> </LinearLayout> <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="40px" android:gravity="bottom" > <TextView android:text="Distance Parcourue" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#000" android:textSize="25dip" > </TextView> </LinearLayout> </LinearLayout> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" > <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="left" > <!-- Bouton avec une Image--> <ImageButton android:id="@+id/ImageButton01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/haut_parleur" > <!-- @drawable/icon est une Image qui se trouve dans le dossier /res/ drawable de notre projet --> </ImageButton> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="600px" android:layout_height="wrap_content" android:gravity="center_horizontal" > <ImageButton android:id="@+id/ImageButton04" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/bluetooth_on" android:gravity="left" > </ImageButton> <ImageButton android:id="@+id/ImageButton02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/phares" > </ImageButton> <ImageButton android:id="@+id/ImageButton05" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/bluetooth_off" android:gravity="right" > </ImageButton> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="right" > <ImageButton android:id="@+id/ImageButton03" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/frein" > </ImageButton> </LinearLayout> </LinearLayout> </LinearLayout> </ScrollView> <!-- Contenu de longlet N°3 --> <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/Onglet3"> <com.androidplot.xy.XYPlot android:id="@+id/mySimpleXYPlot" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginTop="10px" android:layout_marginLeft="10px" android:layout_marginRight="10px" title="Vitesse du Kart en fonction du temps" /> </LinearLayout> </FrameLayout> </LinearLayout> </TabHost> </LinearLayout>
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.Gabriel.android.Interface" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="8" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".InterfaceActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".BtInterface"> </activity> </application> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH" /> </manifest>
Les fichiers Thermometer.java et SimpleXYSeries.java sont 2 objets graphiques et sont pas tres importants en ce moment.
Pourrait quelqu'un me donner un indice par rapport à la raison de cette fermeture soudaine?
Merci
Partager