Start Service in Android and communicate with it from multiple Activities - android

Well I would like to communicate to a Service from multiple Activities, like everyone listen to a broadcast channel and update their Twitter statuses ..
My recent effort is to use Broadcast Receiver on each Activity to receive the broadcast sent from the Service. But I would like to know that it's a good way or not and what is the property way?
Furthermore, I would like to ask if i should use Binder to start this kind of service or use startService method (I am a beginner in using Service actually..).
Thanks in advance.

OKay you are a beginner in Service means Refer this below Link
http://developer.android.com/guide/components/services.html
in your Question while you using service you must register in Manifest file..
like this..
for example i did unlock screen using service and broadcast receiver.
<service
android:name="com.services.Unlock_Service"
android:enabled="true"
android:icon="#drawable/ic_launcher" >
</service>
unlockservice.java
package com.services;
import java.util.List;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.KeyguardManager;
import android.app.Service;
import android.app.KeyguardManager.KeyguardLock;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.util.Log;
import android.widget.Toast;
#SuppressWarnings("deprecation")
public class Unlock_Service extends Service {
ScreenBroadcastReceiver m_receiver;
public String activityname;
PowerManager pm;
WakeLock wl;
#Override
public void onCreate() {
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
m_receiver = new ScreenBroadcastReceiver();
registerReceiver(m_receiver, filter);
Log.d("Widgettool", "works");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
start();
Toast.makeText(getBaseContext(), "SERVICE ON", Toast.LENGTH_SHORT)
.show();
return START_STICKY;
}
#Override
public void onDestroy() {
stop();
unregisterReceiver(m_receiver);
}
#SuppressLint("Wakelock")
public void start() {
try {
pm = (PowerManager) getSystemService(POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
| PowerManager.ACQUIRE_CAUSES_WAKEUP, ".SensorActivity");
wl.acquire();
KeyguardManager mgr = (KeyguardManager) getSystemService(Activity.KEYGUARD_SERVICE);
KeyguardLock lock = mgr.newKeyguardLock(KEYGUARD_SERVICE);
lock.disableKeyguard();
// new TabActivityPacs().service();
} catch (Exception e) {
}
}
public void stop() {
ActivityManager am = (ActivityManager) this
.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
Log.d("topActivity", "CURRENT Activity ::"
+ taskInfo.get(0).topActivity.getClassName());
activityname = taskInfo.get(0).topActivity.getClassName();
ComponentName componentInfo = taskInfo.get(0).topActivity;
componentInfo.getPackageName();
}
private class ScreenBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Log.d("ON SCREEN ON", "might hang here");
// start();
stop();
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
start();
Log.d("SCREEN OFF", "might hang here");
}
}
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
in your question... you have to use broadcast receiver in all activity then only you receive your corresponding information using service..

Related

Broadcast Receiver not calling Service while app was killed

My target was Restarting the Service when app is in background or even killed from home page by sweeping. App & Service is working nice while app is in foreground and background but while I killed the app by force(sweeping out from home page), the Service stopped working. That's okay but I implemented a Broadcast Receiver to restart the Service but it seems like its (Broadcast Receiver) not even called itself or the Service while app was killed forcefully / sweeping from home page.
My device is : Xiaomi Redmi Note 4
I included my codes here :
MainActivity.java
package com.turzo.servicetest;
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
private String TAG = "ServiceTest";
Intent mServiceIntent;
private SensorService mSensorService;
Context ctx;
public Context getCtx() {
return ctx;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ctx = this;
registerRec();
setContentView(R.layout.activity_main);
mSensorService = new SensorService(getCtx());
mServiceIntent = new Intent(getCtx(), mSensorService.getClass());
if (!isMyServiceRunning(mSensorService.getClass())) {
startService(mServiceIntent);
}
}
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
Log.i (TAG, true+"");
return true;
}
}
Log.i (TAG, false+"");
return false;
}
#Override
protected void onDestroy() {
stopService(mServiceIntent);
Log.i(TAG, "onDestroy!");
super.onDestroy();
}
public void registerRec(){
SensorRestarterBroadcastReceiver myreceiver = new SensorRestarterBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver((BroadcastReceiver) myreceiver, intentFilter);
}
}
SensorService.java
package com.turzo.servicetest;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
import java.util.Timer;
import java.util.TimerTask;
public class SensorService extends Service {
public int counter=0;
private String TAG = "ServiceTest";
public SensorService(Context applicationContext) {
super();
Log.i(TAG , "here I am!");
}
public SensorService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
startTimer();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG , "ondestroy!");
Intent broadcastIntent = new Intent("com.turzo.servicetest.ActivityRecognition.RestartSensor");
sendBroadcast(broadcastIntent);
stoptimertask();
}
private Timer timer;
private TimerTask timerTask;
long oldTime=0;
public void startTimer() {
//set a new Timer
timer = new Timer();
//initialize the TimerTask's job
initializeTimerTask();
//schedule the timer, to wake up every 1 second
timer.schedule(timerTask, 1000, 1000); //
}
/**
* it sets the timer to print the counter every x seconds
*/
public void initializeTimerTask() {
timerTask = new TimerTask() {
public void run() {
Log.i(TAG , "in timer ++++ "+ (counter++));
}
};
}
/**
* not needed
*/
public void stoptimertask() {
//stop the timer, if it's not already null
if (timer != null) {
timer.cancel();
timer = null;
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
SensorRestarterBroadcastReceiver.java
package com.turzo.servicetest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class SensorRestarterBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i(SensorRestarterBroadcastReceiver.class.getSimpleName(), "Service Stops! Oooooooooooooppppssssss!!!!");
context.startService(new Intent(context, SensorService.class));
}
}
AndroidManifext.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.turzo.servicetest">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="com.turzo.servicetest.SensorService"
android:enabled="true" >
</service>
<receiver
android:name="com.turzo.servicetest.SensorRestarterBroadcastReceiver"
android:enabled="true"
android:exported="true"
android:label="RestartServiceWhenStopped">
<intent-filter>
<action android:name="com.turzo.servicetest.ActivityRecognition.RestartSensor"/>
</intent-filter>
</receiver>
</application>
</manifest>
You should restart Service in onTaskRemoved().
#Override
public void onTaskRemoved(Intent rootIntent) {
Intent restartService = new Intent(getApplicationContext(),
this.getClass());
restartService.setPackage(getPackageName());
PendingIntent restartServicePI = PendingIntent.getService(
getApplicationContext(), 1, restartService,
PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000, restartServicePI);
}
NOTE:- Starting from android O . You can not call startService.
The startService() method now throws an IllegalStateException if an app targeting Android 8.0 tries to use that method in a situation when it isn't permitted to create background services.
This does not apply to foreground services, which are noticeable to the user. It can run in background with a notification on top. By default, these restrictions only apply to apps that target Android 8.0 (API level 26) or higher. However, users can enable most of these restrictions for any app from the Settings screen, even if the app targets an API level lower than 26. So in case if user enables the restrictions for below API 26 your Service will not work.
Read Background Execution Limits.
So Try to avoid using Service if you can . Make use of WorkManager if it fits the requirements.

what will be the permission for calling broadcastReceiver on Runtime in Marshmallow

Basically i have created alarm app but the broadcastReceiver not getting called in the marshmallow i know about the runtime permission required in the marshmallow but i don't know what will be the permission for my problem for calling broadcastReceiver.
Can anybody please suggest me something please.
I simply solve this problem by creating a service by following this link
Link
Service Code Here...
import android.app.Service;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
/**
* Created by waqar on 1/05/2017.
*/
public class LocalService extends Service {
AlarmReceiver alarmReceiver;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
alarmReceiver = new AlarmReceiver();
IntentFilter screenStateFilter = new IntentFilter();
screenStateFilter.addAction(Intent.ACTION_SCREEN_ON);
screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF);
this.registerReceiver(alarmReceiver, screenStateFilter);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(alarmReceiver);
}
}
And start this service from MainActivity in onCreate Method.
Intent intent = new Intent(getApplicationContext(), LocalService.class);
getApplicationContext().startService(intent);
And don't forget to register this service in the manifest.

Android listen to Lock screen displayed

I want to do a method when lock screen displayed (not when unlocked or screen on, just when lock screen displayed).
i try with broadcast and services but they don't work after killing app.
Also In eclips LogCat i see a log like /WindowManager(473): Lock screen displayed! that genymotion produce .
maybe can be done with windowmanager..
Try something like the following:
KeyguardManager myKM = (KeyguardManager)
context.getSystemService(Context.KEYGUARD_SERVICE);
if( myKM.inKeyguardRestrictedInputMode()) {
// it is locked
}
else {
// it is not locked
}
This should allow you to determine the locked status of the device.
I found it.
using service and set it START_STICKY.
after killing service the service restart again.
it is my code :
android manifest :
<application
....
<service android:name=".UpdateService" />
</application>
service class :
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class UpdateService extends Service {
BroadcastReceiver mReceiver;
#Override
public void onCreate() {
super.onCreate();
// register receiver that handles screen on and screen off logic
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
mReceiver = new MyReceiver();
registerReceiver(mReceiver, filter);
}
#Override
public void onDestroy() {
unregisterReceiver(mReceiver);
Log.i("onDestroy Reciever", "Called");
super.onDestroy();
}
#Override
public void onStart(Intent intent, int startId) {
boolean screenOn = intent.getBooleanExtra("screen_state", false);
if ( !screenOn) {
Log.i("screenON", "Called");
Toast.makeText(getApplicationContext(), "Awake", Toast.LENGTH_LONG)
.show();
} else {
Log.i("screenOFF", "Called");
Toast.makeText(getApplicationContext(), "Sleep",
Toast.LENGTH_LONG)
.show();
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_STICKY;
}
}
receiver class :
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class MyReceiver extends BroadcastReceiver {
private boolean screenOff;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOff = true;
Log.i("screenLog", "screen off");
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOff = false;
Log.i("screenLog", "screen on");
}
}
}
in StartupActivity :
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Context context = getApplicationContext();
Intent service = new Intent(context, UpdateService.class);
context.startService(service);
}

Keep a service running even if app is closed

I am implementing Service for receiving push notifications in Android device. The notifications are successfully received when app is in foreground. When app is closed and its instance is cleared from task manager, notifications are not received.
I want to keep the service running at all the times and it should not stop even if the app is cleared from the task manager.
I start the service from my activity in a button click. When i click the button my service starts and it gives me Toast notification every one minute but if I press the back button then also my service is running but , as soon as i clear my app from the recent activity list which is shown on long press of home button my service is stoped and if again i start my app and check the status of the service but its not running.
I want my service to run even if my app is closed.
This is my activity class
package com.example.hello;
import java.util.ArrayList;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ListView;
public class MainActivity extends Activity {
Button btnSer;
int Pointer=0;
ListView lv;
ArrayList<String> alist=new ArrayList<String>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnSer=(Button) findViewById(R.id.btnstart);
btnSer.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
//start the service when the button is clicked
Log.e("","status of service : "+isMyServiceRunning(MyService.class));
//if(!isMyServiceRunning(MyService.class))
startService(new Intent(getApplicationContext(), MyService.class));
}
});
}
//check if the service is running
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
This is my Service class.
package com.example.hello;
import java.util.Calendar;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class MyService extends Service{
private Handler handlerList = new Handler();
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//TODO do something useful
Toast.makeText(getApplicationContext(), "On start command called", Toast.LENGTH_LONG).show();
return Service.START_STICKY;
}
public void updateLists(){
handlerList.postDelayed(mUpdateListTask, 1000*60);
}
private Runnable mUpdateListTask = new Runnable() {
public void run() { //will make a toast notification every 1 minute.
Calendar cal = Calendar.getInstance();
Log.e("","Thread executed at "+cal.get(Calendar.HOUR_OF_DAY)+":"+cal.get(Calendar.MINUTE)+":"+cal.get(Calendar.SECOND)+":");
Toast.makeText(getApplicationContext(), "Thread executed at "+cal.get(Calendar.HOUR_OF_DAY)+":"+cal.get(Calendar.MINUTE)+":"+cal.get(Calendar.SECOND)+":", Toast.LENGTH_LONG).show();
handlerList.postDelayed(this, 1000*60);
}};
#Override
public void onCreate() {
updateLists();
Toast.makeText(this, "Congrats! MyService Created", Toast.LENGTH_LONG).show();
Log.d("", "onCreate in service");
}
#Override
public void onStart(Intent intent, int startId) {
Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
Log.d("", "onStart in service");
}
#Override
public void onDestroy() {
Toast.makeText(this, "MyService Stopped", Toast.LENGTH_LONG).show();
Log.d("", "onDestroy in service");
}
}
also added the permission in manifest file
<uses-permission android:name="android.permission.WAKE_LOCK" />
Start it as foreground service in the activity use startforeground(intent name) and return it as sticky in the service onstartCommand() method.

Creating an android service

I'm trying to create a service which will start by the user request in the application.
After the user will choose an update interval, the service will run in the operation system background, and will send a non-relevant message.
I've tried to write the service according to the example for Service class API.
For some reason, I figured in debug (when running doBindService() method) that mUpdateBoundService is getting null.
My second question is whether I can use "Toast" inform message outside an application ? (As kind of a desktop notification).
Can anyone help ? Here is my short code:
UpdateService.java
package android.update;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.widget.Toast;
public class UpdateService extends Service {
private NotificationManager mNM;
private final IBinder mBinder = new UpdateBinder();
private int updateInterval;
public class UpdateBinder extends Binder {
UpdateService getService() {
return UpdateService.this;
}
}
public void onCreate() {
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Timer timer = new Timer();
timer.schedule(new UpdateTimeTask(), 100, updateInterval);
}
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
class UpdateTimeTask extends TimerTask {
public void run() {
showNotification();
}
}
public void showNotification() {
Toast.makeText(this, "Hi", 10);
}
#Override
public IBinder onBind(Intent intent) {
updateInterval = intent.getExtras().getInt(getString(R.string.keyUpdateInterval));
return mBinder;
}
}
UpdateActivity.java
package android.update;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class UpdateActivity extends Activity {
private UpdateService mUpdateBoundService;
private boolean mIsBound = false;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void onClickStartUpdateService(View view) {
switch (view.getId()) {
case R.id.btnStartUpdateService:
doBindService();
//Toast.makeText(this,"Service Started",Toast.LENGTH_LONG).show();
mUpdateBoundService.showNotification();
break;
}
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
mUpdateBoundService = ((UpdateService.UpdateBinder)service).getService();
}
public void onServiceDisconnected(ComponentName className) {
mUpdateBoundService = null;
}
};
private void doBindService() {
Intent updateActivityIntent = new Intent(UpdateActivity.this,
UpdateService.class);
EditText txtUpdateInterval = (EditText) findViewById(R.id.txtUpdateInterval);
int interval = Integer.parseInt(txtUpdateInterval.getText().toString());
updateActivityIntent.putExtra(getString(R.string.keyUpdateInterval), interval);
bindService(updateActivityIntent, mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
void doUnbindService() {
if (mIsBound) {
unbindService(mConnection);
mIsBound = false;
}
}
#Override
protected void onDestroy() {
super.onDestroy();
doUnbindService();
}
}
Your toast is not showing because you are not telling it to. Try:
public void showNotification() {
Toast.makeText(this, "Hi", 10).show();
}
For your service issue, I think that you do not properly understand how services & activities work together. A service can run independently of a service, or you can have a service whose lifecycle matches that of a given activity. From your code, it is not clear which of these models you are following. Your implementation will cause the service to wake periodically, but only while your activity is running. If the user switches to another activity, your service will no longer be woken.
If you want a service to wake periodically independently of the activity, then you need to run your timer event in the service itself. Better still use an Alarm to wake your service: Register an Alarm with AlarmManager which will fire an Intent at a future point (or regular intervals, if you prefer), and extend your service from IntentService, override onHandleIntent() and add the necessary Intent Filter to your Service entry in the manifest.

Categories

Resources