E FATAL EXCEPTION: main
Process: [Link].talky_walking, PID: 6396
[Link]: Attempt to
invoke virtual method 'void [Link]([Link])' on a null object
reference
at
[Link].talky_walking.[Link]([Link])
at
[Link].talky_walking.[Link]$handleUserInfoMessage$5$com-example-
talky_walking-MainActivity([Link])
at [Link].talky_walking.MainActivity$
$[Link](D8$$SyntheticClass:0)
at
[Link]([Link])
at
[Link]([Link])
at
[Link]([Link])
at [Link]([Link])
at
[Link]([Link])
at [Link](Native
Method)
at
[Link]$[Link]([Link])
at
[Link]([Link])
--------- beginning of main
2025-10-26 11:31:47.093 1761-2049 VerityUtils pid-1761 E Failed to measure fs-
verity, errno 1: /data/app/~~nk_i--GjbmeYlhpHrtW0sA==/[Link].talky_walking-
OwstT57mJ3bJ0IXBXL_c1g==/[Link]
2025-10-26 11:31:47.311 1761-2049 VerityUtils pid-1761 E Failed to measure fs-
verity, errno 1: /data/app/~~nk_i--GjbmeYlhpHrtW0sA==/[Link].talky_walking-
OwstT57mJ3bJ0IXBXL_c1g==/[Link]
2025-10-26 11:32:11.397 20042-20042 AndroidRuntime pid-20042 E FATAL
EXCEPTION: main
Process: [Link].talky_walking, PID: 20042
[Link]: Attempt to
invoke interface method 'boolean [Link]()' on a null object reference
at
[Link].talky_walking.[Link]([Link])
at
[Link].talky_walking.[Link]([Link])
at
[Link].talky_walking.[Link]([Link])
at
[Link]([Link])
at
[Link]([Link])
at
[Link]([Link]
)
at
[Link]([Link])
at
[Link](FragmentManager.
java:1839)
at
[Link]([Link])
at
[Link]$[Link]([Link])
at
[Link]([Link])
at
[Link]([Link])
at
[Link]([Link])
at [Link]([Link])
at
[Link]([Link])
at [Link](Native
Method)
at
[Link]$[Link]([Link])
at
[Link]([Link])
package [Link].talky_walking;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link].talky_walking.[Link];
import [Link].talky_walking.[Link];
import [Link].talky_walking.[Link];
import [Link].talky_walking.[Link];
import [Link].talky_walking.[Link];
import [Link].talky_walking.[Link];
import [Link].talky_walking.[Link];
import [Link].talky_walking.[Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
public class MainActivity extends AppCompatActivity implements
[Link],
[Link] {
private static final String TAG = "MainActivity";
private static final int PERMISSIONS_REQUEST_CODE = 100;
private ActivityMainBinding binding;
private WebSocketService webSocketService;
private boolean isWebSocketBound = false;
private List<User> connectedUsers;
private ChatFragment currentChatFragment;
private final ServiceConnection serviceConnection = new
ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
[Link] binder =
([Link]) service;
webSocketService = [Link]();
[Link]([Link]);
Log.d(TAG, "Service WebSocket connecté");
// Initialiser après connexion
initializeAfterConnection();
}
@Override
public void onServiceDisconnected(ComponentName name) {
webSocketService = null;
Log.d(TAG, "Service WebSocket déconnecté");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
binding = [Link](getLayoutInflater());
setContentView([Link]());
initializeApp();
}
private void initializeApp() {
connectedUsers = new ArrayList<>();
setupNavigation();
checkAndRequestPermissions();
startWebSocketService();
loadDefaultFragment();
}
private void setupNavigation() {
[Link](this);
}
private void checkAndRequestPermissions() {
String[] permissions = {
[Link],
[Link].ACCESS_NETWORK_STATE,
[Link].RECORD_AUDIO,
[Link].WRITE_EXTERNAL_STORAGE,
[Link].ACCESS_FINE_LOCATION,
[Link].ACCESS_COARSE_LOCATION
};
List<String> permissionsToRequest = new ArrayList<>();
for (String permission : permissions) {
if ([Link](this, permission) !=
PackageManager.PERMISSION_GRANTED) {
[Link](permission);
}
}
if (![Link]()) {
[Link](this,
[Link](new String[0]),
PERMISSIONS_REQUEST_CODE);
}
}
private void startWebSocketService() {
Intent intent = new Intent(this, [Link]);
startService(intent);
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
isWebSocketBound = true;
}
private void initializeAfterConnection() {
// Envoyer une demande de liste des utilisateurs
requestUserList();
}
private void loadDefaultFragment() {
loadFragment(new UsersFragment());
}
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
int itemId = [Link]();
if (itemId == [Link].navigation_users) {
loadFragment(new UsersFragment());
return true;
} else if (itemId == [Link].navigation_audio) {
loadFragment(new AudioFragment());
return true;
} else if (itemId == [Link].navigation_info) {
loadFragment(new InfoFragment());
return true;
}
return false;
}
private void loadFragment(Fragment fragment) {
FragmentTransaction transaction =
getSupportFragmentManager().beginTransaction();
[Link]([Link].fragment_container, fragment);
[Link](null);
[Link]();
}
public void openChatWithUser(User user) {
currentChatFragment = [Link]([Link](),
[Link]());
loadFragment(currentChatFragment);
}
public void requestUserList() {
if (webSocketService != null && [Link]()) {
try {
JSONObject request = new JSONObject();
[Link]("action", "get_users");
[Link](request);
Log.d(TAG, "Demande liste utilisateurs envoyée");
} catch (JSONException e) {
Log.e(TAG, "Erreur création requête liste utilisateurs", e);
}
}
}
public void sendWebSocketMessage(JSONObject message) {
if (webSocketService != null) {
[Link](message);
} else {
Log.e(TAG, "WebSocketService non disponible");
}
}
// Implémentation WebSocketListener
@Override
public void onWebSocketConnected() {
Log.d(TAG, "WebSocket connecté dans MainActivity");
runOnUiThread(() -> {
// Mettre à jour l'interface utilisateur
if (binding != null) {
[Link]("Connecté à l'ESP32");
}
});
}
@Override
public void onWebSocketMessage(String message) {
Log.d(TAG, "Message WebSocket reçu: " + message);
try {
JSONObject jsonMessage = new JSONObject(message);
String action = [Link]("action");
switch (action) {
case "user_list":
handleUserList(jsonMessage);
break;
case "new_message":
handleNewMessage(jsonMessage);
break;
case "user_status":
handleUserStatus(jsonMessage);
break;
default:
Log.w(TAG, "Action non gérée: " + action);
}
} catch (JSONException e) {
Log.e(TAG, "Erreur parsing message JSON", e);
}
}
private void handleUserList(JSONObject message) {
// Traiter la liste des utilisateurs
Log.d(TAG, "Liste utilisateurs reçue");
// Implémentation de la mise à jour de la liste
}
private void handleNewMessage(JSONObject message) {
try {
int fromAddress = [Link]("fromAddress");
String content = [Link]("content");
String type = [Link]("type");
String senderName = [Link]("senderName");
Message newMessage = new Message();
[Link](fromAddress);
[Link](0); // Adresse locale
[Link](content);
[Link](type);
[Link](senderName);
[Link](new [Link]());
[Link]("delivered");
// Transférer au fragment de chat actif
if (currentChatFragment != null) {
[Link](newMessage);
}
} catch (JSONException e) {
Log.e(TAG, "Erreur parsing nouveau message", e);
}
}
private void handleUserStatus(JSONObject message) {
// Traiter le changement de statut d'un utilisateur
Log.d(TAG, "Statut utilisateur mis à jour");
}
@Override
public void onWebSocketDisconnected() {
Log.d(TAG, "WebSocket déconnecté dans MainActivity");
runOnUiThread(() -> {
if (binding != null) {
[Link]("Déconnecté de l'ESP32");
}
});
}
@Override
public void onWebSocketError(Exception ex) {
Log.e(TAG, "Erreur WebSocket dans MainActivity: " + [Link]());
}
@Override
public void onWebSocketMessagePending(JSONObject message) {
Log.w(TAG, "Message en attente: " + [Link]());
}
@Override
protected void onDestroy() {
[Link]();
if (isWebSocketBound && webSocketService != null) {
unbindService(serviceConnection);
isWebSocketBound = false;
}
Intent intent = new Intent(this, [Link]);
stopService(intent);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[]
permissions, @NonNull int[] grantResults) {
[Link](requestCode, permissions,
grantResults);
if (requestCode == PERMISSIONS_REQUEST_CODE) {
boolean allGranted = true;
for (int result : grantResults) {
if (result != PackageManager.PERMISSION_GRANTED) {
allGranted = false;
break;
}
}
if (allGranted) {
Log.d(TAG, "Toutes les permissions accordées");
} else {
Log.w(TAG, "Certaines permissions refusées");
}
}
}
@Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
getSupportFragmentManager().popBackStack();
} else {
[Link]();
}
}
}
package [Link].talky_walking.view;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link].talky_walking.R;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
public class AudioFragment extends Fragment {
private MediaRecorder mediaRecorder;
private MediaPlayer mediaPlayer;
private ImageButton buttonRecord, buttonPlay, buttonStop;
private TextView textStatus;
private boolean isRecording = false;
private boolean isPlaying = false;
private String currentAudioFilePath;
private List<String> audioFiles;
private static final int PERMISSION_REQUEST_CODE = 201;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup
container, Bundle savedInstanceState) {
View view = [Link]([Link].fragment_audio, container,
false);
initializeViews(view);
setupClickListeners();
audioFiles = new ArrayList<>();
return view;
}
private void initializeViews(View view) {
buttonRecord = [Link]([Link].button_record);
buttonPlay = [Link]([Link].button_play);
buttonStop = [Link]([Link].button_stop);
textStatus = [Link]([Link].text_status);
updateUI();
}
private void setupClickListeners() {
[Link](v -> toggleRecording());
[Link](v -> playLastRecording());
[Link](v -> stopPlayback());
}
private void toggleRecording() {
if (!isRecording) {
startRecording();
} else {
stopRecording();
}
}
private void startRecording() {
if (checkAudioPermissions()) {
try {
mediaRecorder = new MediaRecorder();
[Link]([Link]);
[Link]([Link].THREE_GPP);
[Link]([Link].AMR_NB);
currentAudioFilePath = getAudioFilePath();
[Link](currentAudioFilePath);
[Link]();
[Link]();
isRecording = true;
updateUI();
[Link]("Enregistrement en cours...");
Log.d("AudioFragment", "Enregistrement démarré: " +
currentAudioFilePath);
} catch (IOException e) {
Log.e("AudioFragment", "Erreur démarrage enregistrement", e);
[Link]("Erreur démarrage enregistrement");
}
}
}
private void stopRecording() {
if (mediaRecorder != null) {
try {
[Link]();
[Link]();
mediaRecorder = null;
isRecording = false;
[Link](currentAudioFilePath);
updateUI();
[Link]("Enregistrement terminé: " +
[Link]() + " fichiers");
Log.d("AudioFragment", "Enregistrement terminé: " +
currentAudioFilePath);
} catch (Exception e) {
Log.e("AudioFragment", "Erreur arrêt enregistrement", e);
[Link]("Erreur arrêt enregistrement");
}
}
}
private void playLastRecording() {
if (![Link]() && !isPlaying) {
try {
String filePath = [Link]([Link]() - 1);
mediaPlayer = new MediaPlayer();
[Link](filePath);
[Link]();
[Link]();
isPlaying = true;
updateUI();
[Link]("Lecture en cours...");
[Link](mp -> {
isPlaying = false;
updateUI();
[Link]("Lecture terminée");
});
Log.d("AudioFragment", "Lecture démarrée: " + filePath);
} catch (IOException e) {
Log.e("AudioFragment", "Erreur lecture audio", e);
[Link]("Erreur lecture audio");
}
}
}
private void stopPlayback() {
if (mediaPlayer != null && isPlaying) {
[Link]();
[Link]();
mediaPlayer = null;
isPlaying = false;
updateUI();
[Link]("Lecture arrêtée");
}
}
private String getAudioFilePath() {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
[Link]()).format(new Date());
String fileName = "VOICE_" + timeStamp + ".3gp";
File storageDir =
requireContext().getExternalFilesDir(Environment.DIRECTORY_MUSIC);
return new File(storageDir, fileName).getAbsolutePath();
}
private boolean checkAudioPermissions() {
String[] permissions = {
[Link].RECORD_AUDIO,
[Link].WRITE_EXTERNAL_STORAGE
};
for (String permission : permissions) {
if ([Link](requireContext(),
permission) != PackageManager.PERMISSION_GRANTED) {
[Link](requireActivity(),
permissions, PERMISSION_REQUEST_CODE);
return false;
}
}
return true;
}
private void updateUI() {
[Link](!isPlaying);
[Link](![Link]() && !isRecording && !
isPlaying);
[Link](isPlaying);
if (isRecording) {
[Link]([Link].ic_stop);
} else {
[Link]([Link].ic_mic);
}
if (isPlaying) {
[Link]([Link].ic_pause);
} else {
[Link]([Link].ic_play);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[]
permissions, @NonNull int[] grantResults) {
[Link](requestCode, permissions,
grantResults);
if (requestCode == PERMISSION_REQUEST_CODE) {
boolean allGranted = true;
for (int result : grantResults) {
if (result != PackageManager.PERMISSION_GRANTED) {
allGranted = false;
break;
}
}
if (allGranted) {
startRecording();
} else {
[Link]("Permissions refusées");
}
}
}
@Override
public void onDestroy() {
[Link]();
if (isRecording && mediaRecorder != null) {
stopRecording();
}
if (isPlaying && mediaPlayer != null) {
stopPlayback();
}
}
}