Perform a task at a specific time - java

I am new to Android Studio. I have 0 Experience with Java and was still successful to send SMS using my app.
How to Send that SMS at a specific time. E.g; at 5 o'clock.
I have tried com.google.android.gms.gcm.ACTION_TASK_READY, etc but unable to get the permission to send SMS in my other task name MyTask.java
The code is used in mainactivity.java is
package com.example.ssss;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.telephony.SmsManager;
import com.google.android.gms.gcm.GcmNetworkManager;
import com.google.android.gms.gcm.PeriodicTask;
public class MainActivity extends AppCompatActivity {
int MY_PERMISSIONS_REQUEST_SEND_SMS = 1;
String SENT = "SMS_SEND";
String DELIVERED = "SMS_DELIVERED";
PendingIntent sentPI, deliveredPI;
BroadcastReceiver smsSentReceiver, smsDeliveredReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GcmNetworkManager networkManager=GcmNetworkManager.getInstance(this);
String s1 = "MY MSG";
String TellNO = "THE NUMBER";
sentPI = PendingIntent.getBroadcast(this, 0, new Intent(SENT), 0);
deliveredPI = PendingIntent.getBroadcast(this, 0, new Intent(DELIVERED), 0);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS)
!= PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.SEND_SMS},
MY_PERMISSIONS_REQUEST_SEND_SMS);
}
else
{
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(TellNO, null, s1, sentPI, deliveredPI);
}
}
}
Thanks

Use alarmmanager to schedual a call to a method which fetch no. from your database and send your desired message to that number.
From android docs:
AlarmManager:This class provides access to the system alarm services. These allow you to schedule your application to be run at some point in the future. When an alarm goes off, the Intent that had been registered for it is broadcast by the system, automatically starting the target application if it is not already running.

Related

Foreground service gets stopped after 1 minute (Android 12)

I'm trying to make a service that works 24/7 and it's been working until I updated to Android 12. I've checked the new foreground restrictions but still don't understand why it isn't working since I'm starting it from an activity.
ACTIVITY
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class TestActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
startForegroundService(new Intent(TestActivity.this, TestService.class));
}
}
SERVICE
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.media.MediaBrowserCompat;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.media.MediaBrowserServiceCompat;
import java.util.List;
public class TestService extends MediaBrowserServiceCompat {
#Override
public BrowserRoot onGetRoot(#NonNull String clientPackageName, int clientUid, #Nullable Bundle rootHints) { return null; }
#Override
public void onLoadChildren(#NonNull String parentId, #NonNull Result<List<MediaBrowserCompat.MediaItem>> result) { result.sendResult(null); }
#Override
public int onStartCommand(Intent ii, int flags, int startId) {
//CREATE NOTI CHANNEL
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
"test", "Test Notifications",
NotificationManager.IMPORTANCE_HIGH);
((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);
}
//CREATE NOTI
Notification notification = new NotificationCompat.Builder(this, "test")
.setSmallIcon(R.drawable.icon)
.setContentTitle("title")
.setContentText("test")
.setChannelId("test")
.setOngoing(true)
.setSilent(true)
.build();
//START FOREGROUND
startForeground(101, notification);
return START_STICKY;
}
}
I tried creating a new app with just these lines of code and it works fine so it must be something else making the service close after a minute.
Turns out samsung put my app on deep sleep which caused it to close itself if not used for a minute. Also thanks to the people who took their time to try and help.
Even though you are correct in wanting a foreground Service here, it seems as if you want it to stay alive whenever you app in the background, or not running at all, as you don't intend your app to be running 24/7, do you?
Since it seems as if you're trying to use a MediaBrowserServiceCompat in your example, I would suggest you do so using a companion instance of a MediaSessionCompat in order to have the media session control the lifecycle of your Service on it's own.
Implementing a media Service is not the most straightforward task in Android; they're still trying to fix some of its prevailing issues with the latest release of Android 13. Therefore, I would also suggest you follow this official Android guide if you're attempting to create an audio app with a media foreground Service.

Service does not execute when app is closed, but it does execute when it's in the background

I have been trying to make an alarm application. I have been struggling with making a full screen notification. I finally did manage to do it, but it only works when the app is running in the background.
It also needs to work when you have closed the app. I don't understand what I am supposed to do to achieve this. I know it is possible because my alarm clock app I use every day is able to do this.
Mainactivity.java
package com.example.wekkerapp;
import java.util.Calendar;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import android.app.AlarmManager;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private static final String CHANNEL_ID = "my_channel";
static final String FULL_SCREEN_ACTION = "full_screen_action";
static final int NOTIFICATION_ID = 1;
private void createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "Alarm";
String description = "Het alarm gaat";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel("2", name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = (NotificationManager) getSystemService(this.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(channel);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
createNotificationChannel(this);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TimePicker klok = findViewById(R.id.timePicker1);
klok.setIs24HourView(true);
final Button getTimeBtn = findViewById(R.id.getTimeBtn);
final TextView showText = findViewById(R.id.showText);
final AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
getTimeBtn.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onClick(View view) {
Intent intent = new Intent(FULL_SCREEN_ACTION, null, getApplicationContext(), WekkerService.class);
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
int uur = klok.getHour();
int minuut = klok.getMinute();
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, uur);
cal.set(Calendar.MINUTE, minuut);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
Toast.makeText(getApplication().getApplicationContext(), "Alarm gaat om " + uur + ":" + minuut,Toast.LENGTH_LONG).show();
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
showText.setText(Integer.toString(uur) + ':' + Integer.toString(minuut));
NotificationManagerCompat.from(getApplicationContext()).cancel(NOTIFICATION_ID);
}
});
}
static void CreateFullScreenNotification(Context context) {
Intent intent = new Intent(context, MainActivity2.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_USER_ACTION | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentTitle("Alarm")
.setContentText("Het alarm gaat")
.setPriority(NotificationCompat.PRIORITY_MAX)
.setCategory(NotificationCompat.CATEGORY_ALARM)
.setContentIntent(pendingIntent)
.setFullScreenIntent(pendingIntent, true);
NotificationManagerCompat.from(context).notify(NOTIFICATION_ID, notificationBuilder.build());
}
private static void createNotificationChannel(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
if (notificationManager.getNotificationChannel(CHANNEL_ID) == null) {
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "channel_name", NotificationManager.IMPORTANCE_HIGH);
channel.setDescription("channel_description");
notificationManager.createNotificationChannel(channel);
}
}
}
}
Wekkerservice.java
package com.example.wekkerapp;
import android.app.AlarmManager;
import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.util.Log;
import androidx.annotation.Nullable;
public class WekkerService extends IntentService {
public static MediaPlayer mediaPlayer;
public WekkerService() {
super("WekkerService");
}
#Override
public void onCreate() {
super.onCreate(); // if you override onCreate(), make sure to call super().
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
Log.d("test", "onHandleIntent: ");
mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.alarmpie);
if (MainActivity.FULL_SCREEN_ACTION.equals(intent.getAction()))
mediaPlayer.setLooping(true);
mediaPlayer.start(); // no need to call prepare(); create() does that for you
MainActivity.CreateFullScreenNotification(getApplicationContext());
}
}
Mainactivity2.java
package com.example.wekkerapp;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.NotificationCompat;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
public class MainActivity2 extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Button stopbutton = findViewById(R.id.button2);
stopbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
WekkerService.mediaPlayer.stop();
}
});
}
}
I would suggest you use a BroadcastReceiver and then start the service from its onReceive method.
So in your MainActivity's onClick listener you should change the following pending intent
as follows:
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
to
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
and the intent you pass in should launch a BroadcastReceiver.
Immediately after the BroadcastReceiver is launched by the alarm manager, you should start the service from its onReceive method.
Remember that due to the recent changes the OS won't just let you start a service or background service just whenever and however you want!
If the app is closed and you want to start the service, you SHOULD start it as a ForgroundService and show a notification(you have 5 seconds to make this call) otherwise it will throw RemoteServiceException and that's why the code in your service will not run.
I highly encourage you to take a look at this answer:
https://stackoverflow.com/a/56471104/9023032
Here is also another useful answer which might become handy:
https://stackoverflow.com/a/54035247/9023032

PendingIntent() is not public in PendingIntent; cannot be accessed from outside package

I know that this type of question asked but they are unable to solve my problem, Hence I am asking it again for having exact solution to my problem, I am using android studio 3.0.1 for creating simple notification application, when i run this application it shows me errors as show as follow:
Error:(40, 25) error: PendingIntent() is not public in PendingIntent; cannot be accessed from outside package
and my MainActivity.java as follow
package com.example.ram.notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
NotificationCompat.Builder notification;
private static final int uniqueID = 45612;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
notification = new NotificationCompat.Builder(this);
notification.setAutoCancel(true);
}
public void ClickNotification(View view){
//build the notification
notification.setSmallIcon(R.drawable.myimage);
notification.setTicker("this is the ticker");
notification.setWhen(System.currentTimeMillis());
notification.setContentTitle("Here is the title");
notification.setContentText("I am the body of your notificattion");
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = new PendingIntent().getActivity(this, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
notification.setContentIntent(pendingIntent);
//build notification and issues it
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.notify(uniqueID, notification.build());
}
}
Please help me what should i do?
Simply delete "new" keyword in 40 row
must be
pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

How do I get the NMEA data from a serial GPS connected to my android device?

I am working on a project where I have to connect my android device to a GPS with usb. I can't figure out how I can get the data out of my GPS and I do not want to use the device it's internall GPS because I need to be pretty accurate. I have read the tutorial on the android website and I have tried to work with it but I still do not understand how I have to make connection to the GPS.
Here is my code.
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import java.util.HashMap;
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
UsbDevice device = deviceList.get("deviceName");
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)){
if(device != null){
//roep hier de method aan om communicatie met he apparaat te maken
}
}
else{
Log.d(TAG, "permission denied for device " + device);
}
}
}
}
}
}
You might want to give this a shot: http://code.google.com/p/usb-serial-for-android/. Captures all serial data, does not require rooting. You would need to use Service. Let us know if you need more help. I have done this before, not on Android though.

Time Sensitive Notifications

I am trying to build a simple app that sends notifications to the device but only on a specific day/time. I have been able to get the notification part to work but cant seem to get the day & time problem solved. Any ideas?
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class NotificationsActivity extends Activity {
int notificationID = 1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void onClick(View view) {
displayNotification();
}
protected void displayNotification()
{
Intent i = new Intent(this, NotificationView.class);
i.putExtra("notificationID", notificationID);
PendingIntent pendingIntent =
PendingIntent.getActivity(this, 0, i, 0);
NotificationManager nm = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
Notification notif = new Notification(
R.drawable.ic_launcher,
"Reminder: Meeting starts in 5 minutes",
System.currentTimeMillis());
CharSequence from = "System Alarm";
CharSequence message = "Meeting with customer at 3pm...";
notif.setLatestEventInfo(this, from, message, pendingIntent);
notif.vibrate = new long[] { 100, 250, 100, 500};
nm.notify(notificationID, notif);
}
}
You need to use an AlarmManager to schedule these events. Then, from the callbacks, you show the notifications.
See for example Creating a Notification at a particular time through Alarm Manager
Be careful, as AlarManager will be cleared when the device reboots (you may need to re-register then on boot completed if necessary).
See this link Notification in Android Using AlarmManager, BoradCastReceiver & Services
It may be help you.

Categories