Anonymous
Отправить SMS-оповещение сохраненному контакту на Java [закрыто]
Сообщение
Anonymous » 08 июл 2024, 19:04
Я хочу создать функцию SOS в мобильном приложении, которая может отправлять SMS-оповещения, включающие текущее местоположение пользователя, на сохраненный контакт для экстренных случаев при встряхивании телефона с помощью Java в студии Android. но мой код не работает.
Код: Выделить всё
public class SosService extends Service implements SensorEventListener {
private String mLocation = "";
private long lastShakeTime = 0;
private boolean sentSMS = false;
public static boolean isRunning = false;
private boolean calledEmergency = false;
private boolean sentNotification = false;
private AudioManager audioManager = null;
private final Float shakeThreshold = 10.2f;
private SensorManager sensorManager = null;
private LocationManager locationManager = null;
private LocationRequest locationRequest = null;
private static final int MIN_TIME_BETWEEN_SHAKES = 1000;
private final SmsManager smsManager = SmsManager.getDefault();
private static final MediaPlayer mediaPlayer = new MediaPlayer();
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
if (locationRequest == null) {
locationRequest = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 5000)
.setWaitForAccurateLocation(false)
.setMinUpdateIntervalMillis(2000)
.setMaxUpdateDelayMillis(5000)
.build();
}
if (sensorManager != null) {
Sensor accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getAction() != null) {
if (intent.getAction().equalsIgnoreCase("STOP")) {
if (isRunning) {
this.stopForeground(true);
this.stopSelf();
stopSiren();
resetValues();
Log.i("SosService", "Service Stopped");
}
} else {
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, notificationIntent, PendingIntent.FLAG_IMMUTABLE);
NotificationChannel channel = new NotificationChannel(getString(R.string.notification_channel_emergency), getString(R.string.notification_channel_emergency), NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription(getString(R.string.notification_channel_emergency_desc));
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(channel);
Notification notification = new Notification.Builder(this, getString(R.string.notification_channel_emergency))
.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.notification_emergency_mode, getString(R.string.app_name)))
.setSmallIcon(R.drawable.logo)
.setContentIntent(pendingIntent)
.setOngoing(true)
.build();
this.startForeground(1, notification);
notificationManager.notify(1, notification);
isRunning = true;
Log.i("SosService", "Service Started");
return START_NOT_STICKY;
}
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
long curTime = System.currentTimeMillis();
if ((curTime - lastShakeTime) > MIN_TIME_BETWEEN_SHAKES) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
double acceleration = Math.sqrt(Math.pow(x, 2) +
Math.pow(y, 2) +
Math.pow(z, 2)) - SensorManager.GRAVITY_EARTH;
if (acceleration > shakeThreshold) {
lastShakeTime = curTime;
deviceShaken();
Log.i("SosService", "Device Shaken");
}
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// do nothing
}
private void deviceShaken() {
if (!Prefs.getBoolean(Constants.SETTINGS_SHAKE_DETECTION, false)) {
stopSiren();
Log.i("SosService", "Stopped Siren");
return;
}
activateSosMode();
}
private void activateSosMode() {
ArrayList contacts = new ArrayList();
Gson gson = new Gson();
String jsonContacts = Prefs.getString(Constants.CONTACTS_LIST, "");
if (!jsonContacts.isEmpty()) {
Type type = new TypeToken() {
}.getType();
contacts.addAll(gson.fromJson(jsonContacts, type));
sendLocation(contacts);
}
if (Prefs.getBoolean(Constants.SETTINGS_PLAY_SIREN, false)) {
playSiren();
Log.i("SosService", "Playing Siren");
} else {
stopSiren();
Log.i("SosService", "Stopped Siren");
}
}
private void sendLocation(ArrayList contacts) {
if (isGPSEnabled() || !mLocation.isEmpty()) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
final int[] numberOfUpdates = {0};
LocationServices.getFusedLocationProviderClient(this)
.requestLocationUpdates(locationRequest, new LocationCallback() {
@Override
public void onLocationResult(@NonNull LocationResult locationResult) {
super.onLocationResult(locationResult);
numberOfUpdates[0]++;
if (numberOfUpdates[0] >= 3) {
LocationServices.getFusedLocationProviderClient(SosService.this)
.removeLocationUpdates(this);
if (locationResult.getLocations().size() > 0) {
int idx = locationResult.getLocations().size() - 1;
double latitude = locationResult.getLocations().get(idx).getLatitude();
double longitude = locationResult.getLocations().get(idx).getLongitude();
mLocation = "https://maps.google.com/maps?q=loc:" + latitude + "," + longitude;
Log.i("SosService", "Location: " + mLocation);
if (Prefs.getBoolean(Constants.SETTINGS_SEND_SMS, true) && !sentSMS) {
sendSMS(contacts);
sentSMS = true;
}
}
}
}
}, Looper.getMainLooper());
}
}
private boolean isGPSEnabled() {
if (locationManager == null) {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
private void sendSMS(ContactModel contact) {
smsManager.sendTextMessage(contact.getPhone(), null, getString(R.string.sos_message, contact.getName(), mLocation), null, null);
Log.i("SosService", "SMS sent to: " + contact.getPhone());
}
private void sendSMS(ArrayList contacts) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED) {
Log.e("SosService", "SEND_SMS permission not granted");
return;
}
for (ContactModel contact : contacts) {
sendSMS(contact);
}
}
private void playSiren() {
try {
mediaPlayer.setDataSource("Your audio file path");
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.prepare();
mediaPlayer.setLooping(true);
mediaPlayer.start();
} catch (IOException e) {
Log.e("SosService", "Error playing siren: " + e.getMessage());
}
}
private void stopSiren() {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.reset();
}
}
private void resetValues() {
lastShakeTime = 0;
sentSMS = false;
isRunning = false;
calledEmergency = false;
sentNotification = false;
mLocation = "";
}
@Override
public void onDestroy() {
super.onDestroy();
isRunning = false;
sensorManager.unregisterListener(this);
stopSiren();
resetValues();
Log.i("SosService", "Service Destroyed");
}
}
//home java
public class HomeFragment extends Fragment {
private FragmentHomeBinding binding;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
binding = FragmentHomeBinding.inflate(inflater, container, false);
View view = binding.getRoot();
NotificationManager notificationManager = (NotificationManager) requireContext().getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel1 = new NotificationChannel(getString(R.string.notification_channel_push), getString(R.string.notification_channel_push), NotificationManager.IMPORTANCE_HIGH);
NotificationChannel channel2 = new NotificationChannel(getString(R.string.notification_channel_emergency), getString(R.string.notification_channel_emergency), NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel1);
notificationManager.createNotificationChannel(channel2);
binding.sosButton.setOnClickListener(v -> {
if (AppUtil.permissionsGranted(getContext()) && SosUtil.isGPSEnabled(requireContext())) {
SosUtil.activateInstantSosMode(requireContext());
} else if (!AppUtil.permissionsGranted(getContext())) {
multiplePermissions.launch(AppUtil.REQUIRED_PERMISSIONS);
} else {
SosUtil.turnOnGPS(requireContext());
}
});
MainActivity.shakeDetection.setValue(Prefs.getBoolean(Constants.SETTINGS_SHAKE_DETECTION, false));
MainActivity.shakeDetection.setOnChangeListener(newValue -> {
binding.btnShakeDetection.setVisibility(newValue ? View.VISIBLE : View.GONE);
updateButtonText();
if (!newValue) {
SosUtil.stopSosNotificationService(requireContext());
}
});
binding.btnShakeDetection.setVisibility(Prefs.getBoolean(Constants.SETTINGS_SHAKE_DETECTION, false) ? View.VISIBLE : View.GONE);
updateButtonText();
binding.btnShakeDetection.setOnClickListener(v -> {
if (!SosService.isRunning) {
if (AppUtil.permissionsGranted(getContext()) && SosUtil.isGPSEnabled(requireContext())) {
SosUtil.startSosNotificationService(requireContext());
Snackbar.make(requireActivity().findViewById(android.R.id.content), getString(R.string.service_started), Snackbar.LENGTH_LONG).show();
} else if (!AppUtil.permissionsGranted(getContext())) {
multiplePermissions.launch(AppUtil.REQUIRED_PERMISSIONS);
} else {
SosUtil.turnOnGPS(requireContext());
}
} else {
SosUtil.stopSosNotificationService(requireContext());
Snackbar.make(requireActivity().findViewById(android.R.id.content), getString(R.string.service_stopped), Snackbar.LENGTH_LONG).show();
}
updateButtonText();
});
FirebaseUtil.updateToken();
initializeDrawerItems();
return view;
}
private void initializeDrawerItems() {
((NavigationView) requireActivity().findViewById(R.id.navView)).setNavigationItemSelectedListener(item -> {
int id = item.getItemId();
NavOptions navOptions = new NavOptions.Builder()
.setEnterAnim(0)
.setExitAnim(0)
.setPopEnterAnim(R.anim.slide_out)
.setPopExitAnim(R.anim.fade_in)
.build();
if (id == R.id.nav_profile) {
public void setUserNameOnTitle() {
final String[] userName = {getString(R.string.unknown_user)};
FirebaseFirestore.getInstance()
.collection(Constants.FIRESTORE_COLLECTION_USERLIST)
.document(Objects.requireNonNull(FirebaseAuth.getInstance().getCurrentUser()).getUid())
.get()
.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
userName[0] = document.getString("name");
Prefs.putString(Constants.PREFS_USER_NAME, userName[0]);
}
}
if (getContext() != null) {
binding.header.collapsingToolbar.setSubtitle(getString(R.string.activity_home_desc, userName[0]));
}
});
}
private void updateButtonText() {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
if (getContext() != null) {
binding.btnShakeDetection.setText(SosService.isRunning ? getString(R.string.btn_stop_service) : getString(R.string.btn_start_service));
}
}, 200);
}
private final ActivityResultLauncher multiplePermissions = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback() {
@Override
public void onActivityResult(Map result) {
Iterator it = result.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = it.next();
if (!pair.getValue()) {
Snackbar snackbar = Snackbar.make(requireActivity().findViewById(android.R.id.content), R.string.permission_must_be_granted, Snackbar.LENGTH_INDEFINITE);
snackbar.setAction(R.string.grant, v -> {
multiplePermissions.launch(new String[]{pair.getKey()});
snackbar.dismiss();
});
snackbar.show();
}
if (!it.hasNext() && AppUtil.permissionsGranted(getActivity())) {
binding.btnShakeDetection.performClick();
}
}
}
});
}
Я хочу, чтобы, когда пользователь нажимал кнопку паники, а затем встряхивал устройство, SMS-оповещение немедленно отправлялось контакту в сообщении.
Подробнее здесь:
https://stackoverflow.com/questions/787 ... ct-in-java
1720454645
Anonymous
Я хочу создать функцию SOS в мобильном приложении, которая может отправлять SMS-оповещения, включающие текущее местоположение пользователя, на сохраненный контакт для экстренных случаев при встряхивании телефона с помощью Java в студии Android. но мой код не работает. [code]public class SosService extends Service implements SensorEventListener { private String mLocation = ""; private long lastShakeTime = 0; private boolean sentSMS = false; public static boolean isRunning = false; private boolean calledEmergency = false; private boolean sentNotification = false; private AudioManager audioManager = null; private final Float shakeThreshold = 10.2f; private SensorManager sensorManager = null; private LocationManager locationManager = null; private LocationRequest locationRequest = null; private static final int MIN_TIME_BETWEEN_SHAKES = 1000; private final SmsManager smsManager = SmsManager.getDefault(); private static final MediaPlayer mediaPlayer = new MediaPlayer(); @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); if (locationRequest == null) { locationRequest = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 5000) .setWaitForAccurateLocation(false) .setMinUpdateIntervalMillis(2000) .setMaxUpdateDelayMillis(5000) .build(); } if (sensorManager != null) { Sensor accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL); } } @Override public int onStartCommand(Intent intent, int flags, int startId) { if (intent.getAction() != null) { if (intent.getAction().equalsIgnoreCase("STOP")) { if (isRunning) { this.stopForeground(true); this.stopSelf(); stopSiren(); resetValues(); Log.i("SosService", "Service Stopped"); } } else { Intent notificationIntent = new Intent(this, MainActivity.class); notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, notificationIntent, PendingIntent.FLAG_IMMUTABLE); NotificationChannel channel = new NotificationChannel(getString(R.string.notification_channel_emergency), getString(R.string.notification_channel_emergency), NotificationManager.IMPORTANCE_DEFAULT); channel.setDescription(getString(R.string.notification_channel_emergency_desc)); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.createNotificationChannel(channel); Notification notification = new Notification.Builder(this, getString(R.string.notification_channel_emergency)) .setContentTitle(getString(R.string.app_name)) .setContentText(getString(R.string.notification_emergency_mode, getString(R.string.app_name))) .setSmallIcon(R.drawable.logo) .setContentIntent(pendingIntent) .setOngoing(true) .build(); this.startForeground(1, notification); notificationManager.notify(1, notification); isRunning = true; Log.i("SosService", "Service Started"); return START_NOT_STICKY; } } return super.onStartCommand(intent, flags, startId); } @Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { long curTime = System.currentTimeMillis(); if ((curTime - lastShakeTime) > MIN_TIME_BETWEEN_SHAKES) { float x = event.values[0]; float y = event.values[1]; float z = event.values[2]; double acceleration = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2)) - SensorManager.GRAVITY_EARTH; if (acceleration > shakeThreshold) { lastShakeTime = curTime; deviceShaken(); Log.i("SosService", "Device Shaken"); } } } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // do nothing } private void deviceShaken() { if (!Prefs.getBoolean(Constants.SETTINGS_SHAKE_DETECTION, false)) { stopSiren(); Log.i("SosService", "Stopped Siren"); return; } activateSosMode(); } private void activateSosMode() { ArrayList contacts = new ArrayList(); Gson gson = new Gson(); String jsonContacts = Prefs.getString(Constants.CONTACTS_LIST, ""); if (!jsonContacts.isEmpty()) { Type type = new TypeToken() { }.getType(); contacts.addAll(gson.fromJson(jsonContacts, type)); sendLocation(contacts); } if (Prefs.getBoolean(Constants.SETTINGS_PLAY_SIREN, false)) { playSiren(); Log.i("SosService", "Playing Siren"); } else { stopSiren(); Log.i("SosService", "Stopped Siren"); } } private void sendLocation(ArrayList contacts) { if (isGPSEnabled() || !mLocation.isEmpty()) { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } final int[] numberOfUpdates = {0}; LocationServices.getFusedLocationProviderClient(this) .requestLocationUpdates(locationRequest, new LocationCallback() { @Override public void onLocationResult(@NonNull LocationResult locationResult) { super.onLocationResult(locationResult); numberOfUpdates[0]++; if (numberOfUpdates[0] >= 3) { LocationServices.getFusedLocationProviderClient(SosService.this) .removeLocationUpdates(this); if (locationResult.getLocations().size() > 0) { int idx = locationResult.getLocations().size() - 1; double latitude = locationResult.getLocations().get(idx).getLatitude(); double longitude = locationResult.getLocations().get(idx).getLongitude(); mLocation = "https://maps.google.com/maps?q=loc:" + latitude + "," + longitude; Log.i("SosService", "Location: " + mLocation); if (Prefs.getBoolean(Constants.SETTINGS_SEND_SMS, true) && !sentSMS) { sendSMS(contacts); sentSMS = true; } } } } }, Looper.getMainLooper()); } } private boolean isGPSEnabled() { if (locationManager == null) { locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); } return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); } private void sendSMS(ContactModel contact) { smsManager.sendTextMessage(contact.getPhone(), null, getString(R.string.sos_message, contact.getName(), mLocation), null, null); Log.i("SosService", "SMS sent to: " + contact.getPhone()); } private void sendSMS(ArrayList contacts) { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED) { Log.e("SosService", "SEND_SMS permission not granted"); return; } for (ContactModel contact : contacts) { sendSMS(contact); } } private void playSiren() { try { mediaPlayer.setDataSource("Your audio file path"); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.prepare(); mediaPlayer.setLooping(true); mediaPlayer.start(); } catch (IOException e) { Log.e("SosService", "Error playing siren: " + e.getMessage()); } } private void stopSiren() { if (mediaPlayer.isPlaying()) { mediaPlayer.stop(); mediaPlayer.reset(); } } private void resetValues() { lastShakeTime = 0; sentSMS = false; isRunning = false; calledEmergency = false; sentNotification = false; mLocation = ""; } @Override public void onDestroy() { super.onDestroy(); isRunning = false; sensorManager.unregisterListener(this); stopSiren(); resetValues(); Log.i("SosService", "Service Destroyed"); } } //home java public class HomeFragment extends Fragment { private FragmentHomeBinding binding; @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { binding = FragmentHomeBinding.inflate(inflater, container, false); View view = binding.getRoot(); NotificationManager notificationManager = (NotificationManager) requireContext().getSystemService(Context.NOTIFICATION_SERVICE); NotificationChannel channel1 = new NotificationChannel(getString(R.string.notification_channel_push), getString(R.string.notification_channel_push), NotificationManager.IMPORTANCE_HIGH); NotificationChannel channel2 = new NotificationChannel(getString(R.string.notification_channel_emergency), getString(R.string.notification_channel_emergency), NotificationManager.IMPORTANCE_DEFAULT); notificationManager.createNotificationChannel(channel1); notificationManager.createNotificationChannel(channel2); binding.sosButton.setOnClickListener(v -> { if (AppUtil.permissionsGranted(getContext()) && SosUtil.isGPSEnabled(requireContext())) { SosUtil.activateInstantSosMode(requireContext()); } else if (!AppUtil.permissionsGranted(getContext())) { multiplePermissions.launch(AppUtil.REQUIRED_PERMISSIONS); } else { SosUtil.turnOnGPS(requireContext()); } }); MainActivity.shakeDetection.setValue(Prefs.getBoolean(Constants.SETTINGS_SHAKE_DETECTION, false)); MainActivity.shakeDetection.setOnChangeListener(newValue -> { binding.btnShakeDetection.setVisibility(newValue ? View.VISIBLE : View.GONE); updateButtonText(); if (!newValue) { SosUtil.stopSosNotificationService(requireContext()); } }); binding.btnShakeDetection.setVisibility(Prefs.getBoolean(Constants.SETTINGS_SHAKE_DETECTION, false) ? View.VISIBLE : View.GONE); updateButtonText(); binding.btnShakeDetection.setOnClickListener(v -> { if (!SosService.isRunning) { if (AppUtil.permissionsGranted(getContext()) && SosUtil.isGPSEnabled(requireContext())) { SosUtil.startSosNotificationService(requireContext()); Snackbar.make(requireActivity().findViewById(android.R.id.content), getString(R.string.service_started), Snackbar.LENGTH_LONG).show(); } else if (!AppUtil.permissionsGranted(getContext())) { multiplePermissions.launch(AppUtil.REQUIRED_PERMISSIONS); } else { SosUtil.turnOnGPS(requireContext()); } } else { SosUtil.stopSosNotificationService(requireContext()); Snackbar.make(requireActivity().findViewById(android.R.id.content), getString(R.string.service_stopped), Snackbar.LENGTH_LONG).show(); } updateButtonText(); }); FirebaseUtil.updateToken(); initializeDrawerItems(); return view; } private void initializeDrawerItems() { ((NavigationView) requireActivity().findViewById(R.id.navView)).setNavigationItemSelectedListener(item -> { int id = item.getItemId(); NavOptions navOptions = new NavOptions.Builder() .setEnterAnim(0) .setExitAnim(0) .setPopEnterAnim(R.anim.slide_out) .setPopExitAnim(R.anim.fade_in) .build(); if (id == R.id.nav_profile) { public void setUserNameOnTitle() { final String[] userName = {getString(R.string.unknown_user)}; FirebaseFirestore.getInstance() .collection(Constants.FIRESTORE_COLLECTION_USERLIST) .document(Objects.requireNonNull(FirebaseAuth.getInstance().getCurrentUser()).getUid()) .get() .addOnCompleteListener(task -> { if (task.isSuccessful()) { DocumentSnapshot document = task.getResult(); if (document.exists()) { userName[0] = document.getString("name"); Prefs.putString(Constants.PREFS_USER_NAME, userName[0]); } } if (getContext() != null) { binding.header.collapsingToolbar.setSubtitle(getString(R.string.activity_home_desc, userName[0])); } }); } private void updateButtonText() { new Handler(Looper.getMainLooper()).postDelayed(() -> { if (getContext() != null) { binding.btnShakeDetection.setText(SosService.isRunning ? getString(R.string.btn_stop_service) : getString(R.string.btn_start_service)); } }, 200); } private final ActivityResultLauncher multiplePermissions = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback() { @Override public void onActivityResult(Map result) { Iterator it = result.entrySet().iterator(); while (it.hasNext()) { Map.Entry pair = it.next(); if (!pair.getValue()) { Snackbar snackbar = Snackbar.make(requireActivity().findViewById(android.R.id.content), R.string.permission_must_be_granted, Snackbar.LENGTH_INDEFINITE); snackbar.setAction(R.string.grant, v -> { multiplePermissions.launch(new String[]{pair.getKey()}); snackbar.dismiss(); }); snackbar.show(); } if (!it.hasNext() && AppUtil.permissionsGranted(getActivity())) { binding.btnShakeDetection.performClick(); } } } }); } [/code] Я хочу, чтобы, когда пользователь нажимал кнопку паники, а затем встряхивал устройство, SMS-оповещение немедленно отправлялось контакту в сообщении. Подробнее здесь: [url]https://stackoverflow.com/questions/78719366/send-sms-alert-to-saved-contact-in-java[/url]