I created an Android application to get all the call logs after the user ends the call. I used Broadcast Receiver to identify the changes then Run the service to get the information about the last call. But sometimes App is killed by the system after one or two days. I read the Broadcast Documentation, Android Service Documentation, and Android <OREO Restriction. Is there any way to keep the Call Broadcast Receiver all the time?
Is there any way to use work manager?
Is there any good approaches, please share here
Service class
public class CallReceiver extends BroadcastReceiver{
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onReceive(Context context, Intent intent) {
Intent startServiceIntent = new Intent(context, HammerService.class);
context.startForegroundService(startServiceIntent);
}
}
Service class
public class HammerService extends Service {
#Override
public void onCreate() {
super.onCreate();
IntentFilter ifilter = new IntentFilter();
ifilter.addAction(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED);
registerReceiver(receiver, ifilter);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String input = intent.getStringExtra("inputExtra");
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Hammer Service")
.setContentText(input)
.setSmallIcon(R.drawable.ic_android)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
//do heavy work on a background thread
//stopSelf();
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(final Context context, final Intent intent) {
String action = intent.getAction();
if(action.equals("android.provider.Telephony.SMS_RECEIVED")){
//action for sms received
}
else if(action.equals(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED)){
runfirstTime(context,intent);
}
}
};
Related
My background service starts at certain time using alarmmanager to play an audio track, and stops at completion of this track.
I want to enable user to stop the service when he expands notifications bar or any such user events (if it's impossible by notifications bar).
Code of receiver:
public class TimeReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context,TimeService.class));
}
}
Code of service:
public class TimeService extends Service implements MediaPlayer.OnCompletionListener {
private MediaPlayer mediaPlayer;
#Override
public void onCreate() {
super.onCreate();
mediaPlayer = MediaPlayer.create(this, R.raw.hi);
mediaPlayer.setOnCompletionListener(this);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mediaPlayer.start();
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
this.mediaPlayer.stop();
stopSelf();
}
}
Create Notification on start and remove on stop.
Use PendingIntent to call on touch event on the notification (hint: you can use also Notification.Action).
Create a BroadcastReceiver to receive an action from PendingIntent.
PendingIntent pi_my_action = PendingIntent.getBroadcast( this, 0, new Intent( TimeService.MY_ACTION ), 0);
Notification.Builder builder = new Notification.Builder(this)
.setSmallIcon( R.mipmap.ic_launcher )
.setContentTitle( title )
.setContentText( message )
.setContentIntent( pi_my_action );
BroadcastReceiver br = new BroadcastReceiver() {
#Override
public void onReceive( Context context, Intent intent) {
if (intent.getAction().equals( TimeService.MY_ACTION )) {DoSomething();}}};
I have a Service that listens to both incoming and outgoing calls.The Service runs when the app is started and keeps on running for some time even after the app is closed.But somehow is the Service is destroyed or something later.I have put START_STICKY as the return of the startCommand() method.I know the System kills the Service when the memory is high.But then how are the call recording apps able to listen to calls continuously?Is there a work around for this kind of problem?How do I make my app listen to phone calls continuously?
Code
PhoneListenerService.class
public class PhoneListenerService extends Service{
private TelephonyManager telephonyManager;
private File file;
OutgoingReceiver outgoingReceiver;
#Override
public void onCreate()
{
super.onCreate();
outgoingReceiver=new OutgoingReceiver();
IntentFilter intentFilter=new IntentFilter();
intentFilter.addAction("android.intent.action.NEW_OUTGOING_CALL");
registerReceiver(outgoingReceiver,intentFilter);
file=new File(Environment.getExternalStorageDirectory().getAbsolutePath());
telephonyManager=(TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
file=new File(Environment.getExternalStorageDirectory(),"AutoCall");
if (!file.exists())
{
Log.e("File","Created");
file.mkdir();
}
else
{
Log.e("File",file.getPath());
}
telephonyManager.listen(new TeleListener(getApplicationContext(),file.getAbsolutePath()),PhoneStateListener.LISTEN_CALL_STATE);
Log.e("Oncreate","Service");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("OnCommand","Service");
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(outgoingReceiver);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
public class OutgoingReceiver extends BroadcastReceiver {
public OutgoingReceiver()
{
}
#Override
public void onReceive(Context context, Intent intent) {
Log.e("Out","Track");
String phone_number=intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Toast.makeText(context,"Outgoing call identified",Toast.LENGTH_SHORT).show();
}
}
}
Start the service as FOREGROUND Service like this
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Register your reporting alarms here.
Log.e("SmsAndCallService", "IN onStartCommand");
startForeground(105, getCompatNotification());
return Service.START_STICKY;
}
private Notification getCompatNotification() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "105");
builder.setSmallIcon(R.mipmap.ic_launcher).setContentTitle(getString(R.string.app_name) + " running").setTicker("Recording");
Intent intent = new Intent(new Intent(getApplicationContext(), SplashActivity.class));
PendingIntent pendingIntent = PendingIntent.getActivity(this, 2003, intent, 0);
builder.setContentIntent(pendingIntent);
Notification notification = builder.build();
return notification;
}
So system cant kills this service when system run out of resources. `
FOREGROUND SERVICE means some sort of notification stuff keep showing to make the system to aware that service is still running.
Use a static system define broadcast receiver for incoming calls.don't forgot to declare this in manifest
Yea.I use MediaRecorder for that.I have a question.If the deveice is restarted will the service and receiver still run in the background
Like this way you need to have broadcast receiver for reboot restarting your service and jobscheduler for Higher versoin than marshmallow Android 6.0
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
Intent iService = new Intent(context, PhotoService.class);
context.startService(iService);
} else
JobInfoServ.scheduleJob(context);
}
}
AndroidManifest.xml
<receiver
android:name="com.your.package.broadcast.BootReceiver"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
I'm implementing an app that requires to monitor the device's battery level. So I implemented a Service like this:
public class BatteryService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
registerReceiver(batteryReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
return super.onStartCommand(intent, flags, startId);
}
private final BroadcastReceiver batteryReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Save the data
}
};
}
I start this service in my MainActivity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(this, BatteryService.class));
}
}
and in a android.intent.action.BOOT_COMPLETED receiver:
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context,BatteryService.class));
}
}
I have two problems:
Testing app after some time, it stops registering battery changed events
After rebooting the phone the app crashes with the following error
Caused by java.lang.IllegalStateException: Not allowed to start service Intent {...} app is in background
Maybe my questions are self-related:
How do I avoid the service to stop running after some time?
How do I avoid the crash on boot? I have read that using "startForegroundService" but, it does require to present a notification to the user.
How can I run in background and monitor the battery properly without constantly showing a notification?
Thanks!
Actually it was because of Android built-in security. They discouraged background services for user's protection. To allow such action, user must be aware that your service is running by starting it in foreground.
Intent intent = new Intent(this, typeof(SomeActivityInYourApp));
PendingIntent pi = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setSmallIcon(R.Drawable.my_icon);
builder.setTicker("App info string");
builder.setContentTitle("Hey there");
builder.setContentText("My battery service is running!")
builder.setContentIntent(pi);
builder.setOngoing(true);
Notification notification = builder.build();
startForeground(SERVICE_NOTIFICATION_ID, notification);
I am creating an application on Android which has a MySql server. I want a notification if there is any data present in the File (The User has the job to remove it all but after verifying them). So, I need a good background worker which activates after one hour, checks if any data is there, send a notification, close itself and then again activate after one hour. The time one hour can be changed. I use a AsyncTask for downloading(Unavoidable). I am good at sending notifications and using AsyncTask.
I am a bit lazy so have not done any experiment before verifying that it will complete my task.
I think it may use the Service class. Please provide detailed information. Please give a whole tutorial when telling to use any Github Library cause I am new to Github.
Thank You,
Yours Respectfully,
India's youngest android application developer
I found out the solution Myself and so decided to help out any other new Programmer. Here it is-
AlarmReceiverLifeLog.java
public class AlarmReceiverLifeLog extends BroadcastReceiver {
private static final String TAG = "LL24";
static Context context;
#Override
public void onReceive(Context context, Intent intent) {
Log.v(TAG, "Alarm for LifeLog...");
Intent serviceIntent = new Intent(context,MyReciever.class);
context.startService(serviceIntent);
}
}
MyReciever.java
public class MyReciever extends Service {
int mStartMode;
IBinder mBinder;
boolean mAllowRebind;
#Override
public void onCreate() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//Your Method to get Data from Server
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
#Override
public boolean onUnbind(Intent intent) {
return mAllowRebind;
}
#Override
public void onRebind(Intent intent) {
}
#Override
public void onDestroy() {
}
//method to show notification to be called when you finally decide that you have to notify the user
public void showNotification(String title,String message){
Log.d("Service","Going to show notification");
NotificationCompat.Builder builder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.app_icon)
.setContentTitle(title)
.setContentText(message);
Intent notificationIntent = new Intent(this, NavigationActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(contentIntent);
// Add as notification
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(0, builder.build());
}
}
Add this in your AndroidManifest.xml
<receiver android:name=".AlarmReceiverLifeLog" >
</receiver>
<service android:name=".MyReciever" />
Activating the reciever
Intent ll24 = new Intent(this, AlarmReceiverLifeLog.class);
PendingIntent recurringLl24 = PendingIntent.getBroadcast(this, 0, ll24, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarms = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarms.setRepeating(AlarmManager.RTC_WAKEUP, 0, AlarmManager.INTERVAL_HALF_DAY, recurringLl24);//For waking it after each 12hrs.
I have a service to show notification at a specific time and one broadcastreceiver for starting this service. When the app is started, the service is started and shows notification and shows the service in app running on the device, but sometimes in the running app service is a Restarting and the message does not display.
my service code is:
public class NotificationService extends Service {
private boolean flag=false;
public static NotificationCompat.Builder mBuilder;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Timer timer=new Timer();
final Context context=getApplicationContext();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
if(CheckTime()){
//Intent intent = new Intent(context, NotificationReciver.class);
//sendBroadcast(intent);
showNotification();
}
}
},0,(1000*60));
return START_NOT_STICKY;
}
private boolean CheckTime(){
final Context context=getBaseContext();
Calendar calendar=Calendar.getInstance();
int hour=calendar.get(Calendar.HOUR_OF_DAY);
int minute=calendar.get(Calendar.MINUTE);
if(hour==16 && minute==11){
return true;
}else {
return false;
}
}
private void showNotification() {
Context context=getApplicationContext();
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Intent intent=new Intent(context, QuestionActivity.class);
PendingIntent pendingIntent=PendingIntent.getActivity(context,0,intent,0);
mBuilder = new NotificationCompat.Builder(context).
setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Feelinger")
.setContentText("How are you feeling today?")
.setSound(alarmSound)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.setVibrate(new long[]{300, 200, 200, 200});
android.app.NotificationManager mNotificationManager = (android.app.NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(100, mBuilder.build());
}
and BroadcastReceiver code is:
public class NotificationManager extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context,NotificationService.class));
}
How to solve this problem?
Write inside service
#Override
public int onStartCommand (Intent intent, int flags, int startId)
{
return START_NOT_STICKY;
}