I want to begin the receiver class by programmatically,I got some idea about how to start service programmatically and what is the difference between beginning service programmatically and receiver programmatically.Share your solutions and ideas.
If you add receiver in service and get data from your activity. I add Activity and Service class below.
This is your main activity when you get receive data from service.
public class YourActivity extends Activity {
private MyReceiver receiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this);
receiver = new MyReceiver();
IntentFilter filter = new IntentFilter(YourServices.ACTION);
manager.registerReceiver(receiver, filter);
if (!YourServices.isRunning) {
startService(new Intent(this, YourServices.class));
}
}
class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction() != null) {
if (intent.getAction().equals(YourServices.ACTION)) {
AlarmManager service = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, MyServiceReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(context, 0, i,PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
// Start 20 seconds after boot completed
cal.add(Calendar.SECOND, 20);
Log.v("background service", "STARTED////\\");
//
// Fetch every 1 hour
// InexactRepeating allows Android to optimize the energy consumption
service.setInexactRepeating(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), REPEAT_TIME, pending);
}
}
}
}
}
Here your service that send data when starting.
public class YourServices extends Service {
public static String ACTION = "your_action";
public static boolean isRunning = true;
private void broadcastData() {
Intent intent = new Intent(ACTION);
LocalBroadcastManager.getInstance(getApplicationContext())
.sendBroadcast(intent);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
broadcastData();
return START_STICKY;
}
}
Related
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);
}
}
};
I'm new to services and BroadcastReceiver so maybe this question is newbie, but I didn't found the solution for my question after a long search on the web.
I need to run a CountDownTimer inside service, so the time keep moving even the application was finished.
In my code I based on THIS EXAMPLE.
My code works fine, but after the application is finished the CountDownTimer stopped(The service doesn't destroyed, just the timer).
I tried to implement it in different ways, but nothing works for me.
This is the part of my code that relevant:
AlarmReciver:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent background = new Intent(context, BackgroundService.class);
Bundle bundle = intent.getExtras();
background.putExtra("time", bundle.getInt("time"));
context.startService(background);
}
}
BackgroundService :
public class BackgroundService extends Service {
private final static String TAG = "BroadcastService";
private CountDownTimer cdt = null;
private Bundle bundle;
private boolean isRunning;
private Context context;
private int timeInMili;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
this.context = this;
this.isRunning = false;
}
#Override
public void onDestroy() {
//cdt.cancel();
Log.i(TAG, "Timer cancelled");
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
bundle = intent.getExtras();
timeInMili = bundle.getInt("time");
if(!this.isRunning) {
this.isRunning = true;
}
cdt = new CountDownTimer(timeInMili, 1000) {
#Override
public void onTick(long millisUntilFinished) {
Log.i(TAG, "Countdown seconds remaining: " + millisUntilFinished / 1000);
}
#Override
public void onFinish() {
Log.i(TAG, "Timer finished");
stopSelf();
}
};
cdt.start();
return START_STICKY;
}
}
MainActivity (extends FragmentActivity):
public void StartBackgroundAlarm(int timeInMili)
{
Intent alarm = new Intent(this, AlarmReceiver.class);
alarm.putExtra("time", timeInMili);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarm, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), pendingIntent);
}
MANIFEST :
<service android:enabled="true" android:name= "com.MES.yo.servicemanager.BackgroundService" />
<receiver android:name="com.MES.yo.servicemanager.AlarmReceiver"></receiver>
I want to check notifications from background receivers or services.
The notification is shown, but it should also invoke an activity.
MainActicityClass
Here I have created the alarm class which would call broadcast manager at specific interval
public class MainActivity extends AppCompatActivity {
private Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.context = this;
Intent alarm = new Intent(this.context, AlarmReceiver.class);
boolean alarmRunning = (PendingIntent.getBroadcast(this.context, 0, alarm, PendingIntent.FLAG_NO_CREATE) != null);
if(alarmRunning == false) {
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.context, 0, alarm, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), 60000, pendingIntent);
}
}
Alarm Receiver Class
This is the broadcast class to invoke from back ground
public class AlarmReceiver extends BroadcastReceiver {
public AlarmReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
Intent background = new Intent(context, MyListenerServices.class);
context.startService(background);
}
}
MyListener
This is subclass of notificationlistener services
Its reads any incoming notification but unable to read the notification from inactive class
Integrate class read any kind of incoming notification from background
public class MyListenerServices extends NotificationListenerService{
public MyListenerServices() {
}
private boolean isRunning;
private Context context;
private Thread backgroundThread;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
this.context = this;
this.isRunning = false;
this.backgroundThread = new Thread(myTask);
}
private Runnable myTask = new Runnable() {
public void run() {
// Do something here
Log.d("MSG", "ServiceRunning");
StatusBarNotification[] statusBarNotifications = getActiveNotifications();
Log.d("MSG", "New Object2 "+statusBarNotificationsArray);
if (statusBarNotifications.length > 0) {
Log.d("MSG", "New Object "+statusBarNotifications.length);
//
Intent i = new Intent(context, AutomaticCameraActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
// }
// }catch (Exception e){
// Log.d("MSG",e.getMessage());
}
stopSelf();
}
};
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
Notification mNotification=sbn.getNotification();
Log.v("MSG"," Notification"+ mNotification);
}
#Override
public void onDestroy() {
this.isRunning = false;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(!this.isRunning) {
this.isRunning = true;
this.backgroundThread.start();
}
return START_STICKY;
}
}
Any help would be appreciated
Thanks in advance
Create a pending intent
Intent resultIntent = new Intent(this, ResultActivity.class);
//Change ResultActivity by your activity you want invoke
...
// Because clicking the notification opens a new ("special") activity, there's
// no need to create an artificial back stack.
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
this,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
More information in Create Notification
I am new to android. I was playing with the AlarmManager and had successufully go a piece of code running with the BroadcastReceiver as a separate class.
I am now trying to put the BroadcastReceiver as inner class but have no luck on firing the BroadcastReceiver. I had no idea what might have gone wrong after hours looking at the code...
Here is my code:
public class InnerService extends Service{
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter(InnerBroadcastReceiver.class.toString());
Log.d("InnerService","InnerService starts!");
Log.d("InnerService","class : "+InnerBroadcastReceiver.class.toString());
this.registerReceiver(new InnerBroadcastReceiver(), filter);
scheduleTestAlarmReceiver(this);
}
public static void scheduleTestAlarmReceiver(Context context) {
Log.d("scheduleTestAlarmReceiver", "scheduleTestAlarmReceiver start");
Intent receiverIntent = new Intent(context, InnerBroadcastReceiver.class);
receiverIntent.setAction("com.example.alarmmanagertest.InnerService$InnerBroadcastReceiver");
PendingIntent sender = PendingIntent.getBroadcast(context, 123456789,
receiverIntent, 0);
AlarmManager alarmManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime(), 1000, sender);
Log.d("scheduleTestAlarmReceiver", "scheduleTestAlarmReceiver complete");
}
private class InnerBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.d("InnerBroadcastReceiver","InnerBroadcastReceiver ALARM Manager fires success!");
}
}
}
It looks like the AlarmManager tried to fire the BroadcastReceiver every second but failed
Logcat:
V/AlarmManager(2439): waitForAlarm result :4
V/AlarmManager(2439): trigger ELAPSED_REALTIME_WAKEUP or RTC_WAKEUP
UPDATE
I have tried to change the code for creating intent in onCreate() and scheduleTestAlarmReceiver() to intent = new intent("action_string") and it works. It seems that intent.setAction() is not working.
What will be the pros and cons for creating intent with and without context (Intent(Context packageContext, Class<?> cls) and Intent(String action))?
But I would still like to know why the above code failed. Can anyone explain?
True, it works!
Small changes in my code. Apk with AsyncTask (downloading file from web and parsing it). "OneMeeting" is my class from project.
public class MainActivity extends AppCompatActivity {
public static final String INPUT_FILE_URL = "https://.../";
private RecyclerView recyclerView;
private String getFilesDir;
private ArrayList<OneMeeting> meetingsArr = new ArrayList<>();
private BroadcastReceiver receiver;
private RefreshFile refreshFile;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
getFilesDir = getFilesDir().getAbsolutePath();
recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setItemAnimator(new DefaultItemAnimator());
meetingsArr.add(new OneMeeting("Launching..." , "", "", ""));
recyclerView.setAdapter(new MyAdapter(meetingsArr, recyclerView));
Intent alarmIntent = new Intent("commaciejprogramuje.facebook.conferenceapplication.MainActivity$RefreshFile");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 111, alarmIntent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * 5, pendingIntent);
}
#Override
protected void onResume() {
super.onResume();
refreshFile = new RefreshFile();
IntentFilter filter = new IntentFilter("commaciejprogramuje.facebook.conferenceapplication.MainActivity$RefreshFile");
this.registerReceiver(refreshFile, filter);
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(refreshFile);
}
private class RefreshFile extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Refresh", Toast.LENGTH_LONG).show();
ParsePage refreshParsingPage = new ParsePage(new ParsePage.OnTaskCompletedListener() {
#Override
public void onTaskCompletedListener(ArrayList<OneMeeting> parsingResultArr) {
meetingsArr = parsingResultArr;
recyclerView.setAdapter(new MyAdapter(meetingsArr, recyclerView));
}
});
refreshParsingPage.execute(getFilesDir);
}
}
}
I have my alarms that calls onReceive() in my broadcast receiver.
public class MainActivity extends ActionBarActivity {
private Button bLoggOut, bStartTracking, bStop;
final private static String myAction = "com.brucemax.MY_ALARM_OCCURED";
Context ctx;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ctx = this;
setContentView(R.layout.activity_main);
Log.d("myTag", "Alarm set "+String.valueOf(isAlarmSet()));
bStartTracking = (Button) findViewById(R.id.bStartTracking);
bStartTracking.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(myAction);
PendingIntent pendingIntent = PendingIntent.getBroadcast(ContextHolder.getAppContext(), 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) ctx.getSystemService(ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, 0/*updateTime.getTimeInMillis()*/, 5 * 1000, pendingIntent);
}
});
bStop = (Button) findViewById(R.id.bStop);
bStop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
canselSetWakeUpMode();
}
});
}
public void canselSetWakeUpMode() {
Log.d("myTag", "MainActivity canselSetWakeUpMode()");
Intent myAlarm = new Intent(myAction);
// myAlarm.putExtra("project_id",project_id); //put the SAME extras
PendingIntent recurringAlarm = PendingIntent.getBroadcast(ctx, 1, myAlarm, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarms = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);
alarms.cancel(recurringAlarm);
}
public boolean isAlarmSet() {
Intent myAlarm = new Intent(myAction);
return (PendingIntent.getBroadcast(ctx,1, myAlarm, PendingIntent.FLAG_NO_CREATE) != null) ;
}
}
MyReciever in manifest:
<receiver android:name=".Service.StartServiseWakefulReceiver">
<intent-filter>
<action android:name="com.brucemax.MY_ALARM_OCCURED"/>
</intent-filter>
</receiver>
Receiver:
public class StartServiseWakefulReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// This is the Intent to deliver to our service.
Intent service = new Intent(context, HandleLocationService.class);
Log.d("myTag", "StartServiseWakefulReceiver onReceive()");
// Start the service, keeping the device awake while it is launching.
//Log.i("SimpleWakefulReceiver", "Starting service # " + SystemClock.elapsedRealtime());
startWakefulService(context, service);
}
}
It is work. When i run app at first isAlarmSet() is false. I start alarming, it is work, then I stop alarming (and it is realy stops), close app. But when I start app again the isAlarmSet() is true!!! But alarming not run. Why???
Regards!