How to write Background Service in Android 6.0 and above? - android-service

I have created a background service and that service is working fine in below Android 6.0 when I kill app.
Also working in Android 6.0 and above but only when I minimize app.
When I kill app in Android 6.0 and above service also kill and not get restart and also not get start on BOOT_COMPLETE.
What to DO?
Can I get a simple example.
I tried this:
MyService.java
public class MyService extends Service {
private MediaPlayer player;
#Nullable
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet started");
}
public A_ExampleMyService() {
super();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
player = MediaPlayer.create(this, Settings.System.DEFAULT_RINGTONE_URI);
player.setLooping(true);
player.start();
return START_STICKY;
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Intent restartServiceIntent = new Intent(getApplicationContext(), this.getClass());
restartServiceIntent.setPackage(getPackageName());
startService(restartServiceIntent);
super.onTaskRemoved(rootIntent);
}
}
MyActivity.java
public class MyActivity extends Activity {
private Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.a_example_activity);
this.context = this;
Intent background = new Intent(MyActivity.this,MyService.class);
context.startService(background);
}
}
manifest.xml
<manifest>
<application>
<service>
<android:name=".MyService">
<android:enabled="true">
<android:exported="true"/>
</application>
</manifest>

Related

Is there any way to not stop service even if app is stopped through the multitasking screen?

My service gets stopped when app is closed.
Code already provided.
My Service code is:
public class MusicService extends Service {
MediaPlayer myPlayer;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Toast.makeText(this, "Service Created", Toast.LENGTH_LONG).show();
myPlayer = MediaPlayer.create(this, R.raw.nokiatune);
myPlayer.setLooping(false); // Set looping
}
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
myPlayer.start();
}
#Override
public void onDestroy() {
Toast.makeText(this, "Service Stopped", Toast.LENGTH_LONG).show();
myPlayer.stop();
}
}
I have developed a Service in android. It is working fine. The only thing is that service stops when app is closed through the multitasking screen. Is there any way to not stop the service even if the app is closed through the multitasking screen ?
You could try the approach discussed here. Basically, you register a BroadcastReceiver that restarts your Service if it is destroyed. On your AndroidManifest.xml:
<receiver
android:name="yourpackagename.RestartServiceBroadcastReceiver"
android:enabled="true"
android:exported="true"
android:label="RestartServiceWhenStopped">
</receiver
Your BroadcastReceiver:
public class RestartServiceBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, MusicService.class));
}
}
Then on your Service's onDestroy, you send a Broadcast so that the BroadcastReceiver can restart your service.
#Override
public void onDestroy() {
Intent broadcastIntent = new Intent(this,RestartServiceBroadcastReceiver .class);
sendBroadcast(broadcastIntent);
myPlayer.stop();
}
Also, you have to move your logic inside the onStart to your Service's onStartCommand and have it return START_STICKY, like this:
#Override
public int onStartCommand() {
myPlayer.start();
return START_STICKY;
}
Returning this tells Android not to kill your service--however, there's no guarantee that Android will honor this and can still kill your service.
Finally in the Activity where you start the Service, you need to make sure that you check first if the service is already existing before starting the service, and stop the service during onDestroy, so that the BroadcastReceiver can restart the service.
A warning though: this approach will not work above Android O, please see this for more details.

Toast from JobIntentService

I am a beginner.
I want Toast from jobintentservice (onHandleWork) but crash my app.
logcat error is : " can't toast on a thread that has not called looper.prepare()"
i want learn work with handler in jobintentservice
please help me.
public class NotificationService extends JobIntentService {
public static final String TAG = NotificationService.class.getSimpleName();
Handler handler;
public static void enqueuWork(Context context,Intent intent){
enqueueWork(context,NotificationService.class,20,intent);
}
public void onCreate() {
super.onCreate();
Toast.makeText(this, "Start background Service", Toast.LENGTH_SHORT).show();
}
#Override
public int onStartCommand(#Nullable Intent intent, int flags, int startId) {
handler = new Handler();
return super.onStartCommand(intent, flags, startId);
}
#Override
protected void onHandleWork(#NonNull Intent intent) {
handler.post(new Runnable() {
#Override
public void run()
Toast.makeText(NotificationService.this, "onhandlework", Toast.LENGTH_SHORT).show();
}
});
you probebly figured it out by now, but for future readers, the error "can't toast on a thread that has not called looper.prepare()" simply means you must call ui related from ui thread.
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
showToast(activity);
}});
you can find similiar questions here and here

Detached ExpoKit and Headless JS

Cross-posting from Expo's forums:
I have been having problems trying to get Headless JS task to execute on a detached ExpoKit project (SDK25). I have used the React Native documentation to do this.
I have a broadcast receiver
public class MessageReceivedReceiver extends BroadcastReceiver {
private static final String TAG = "MessageReceivedReceiver";
#Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "onReceive");
if (!isAppOnForeground((context))) {
Log.i(TAG, "Not in foreground");
/**
We will start our service and send extra info about
network connections
**/
Intent serviceIntent = new Intent(context, JSBackgroundService.class);
serviceIntent.putExtras(intent.getExtras());
context.startService(serviceIntent);
HeadlessJsTaskService.acquireWakeLockNow(context);
}
}
...
A HeadlessJS Task Service:
public class JSBackgroundService extends HeadlessJsTaskService {
final static String TAG = "JSBackgroundService";
#Override
protected #Nullable
HeadlessJsTaskConfig getTaskConfig(Intent intent) {
Bundle extras = intent.getExtras();
Log.i(TAG, String.format("getTaskConfig: %s", extras));
if (extras != null) {
return new HeadlessJsTaskConfig(
"Test",
Arguments.fromBundle(extras),
5000, // timeout for the task
false // optional: defines whether or not the task is allowed in foreground. Default is false
);
}
return null;
}
}
My MainApplication implements ReactApplication:
public class MainApplication extends ExpoApplication implements ReactApplication {
private static final String TAG = MainApplication.class.getSimpleName();
private List<ReactPackage> packages = Arrays.<ReactPackage>asList(
// new MainReactPackage(),
new MyReactPackage()
);
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
#Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
#Override
protected List<ReactPackage> getPackages() {
return packages;
}
};
#Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
…
In App.js I have:
…
import JSBackgroundService from ‘./services/jsbackgroundservice’;
AppRegistry.registerHeadlessTask(‘Test’, () => {console.log(“Got it”); return JSBackgroundService; });
export default class App extends React.Component {
…
And JsBackgroundService:
module.exports = async (e) => {
// do stuff
console.log("Running the background service");
console.log(e);
};
Based on logs I know that getTaskConfig is executed but for some reason, I don’t see anything in the console logs, looks like the javascript never gets executed. I have tried also running the Headless JS in foreground for testing purposes but to no avail.
Does anyone have any ideas what could I be doing wrong?
Any help is appreciated :)

how to onUnbind AccessibilityService

I have created an ActivityMonitorService which extends AccessibilityService to capture TYPE_WINDOW_STATE_CHANGED events. But when I force close my app, the phone restart all the time. The onUnbind() was called when the main activity onDestroy(),But every time after phone restart, the ActivityMonitorService restart and cause my phone restarted for some reasons. Give me some advice,please.
ActivityMonitorService.java
public class ActivityMonitorService extends AccessibilityService {
public static final String LOG_TAG = "ActivityMonitorService";
private MyBinder myBinder = new MyBinder();
public class MyBinder extends Binder {
public ActivityMonitorService getService()
{
return ActivityMonitorService.this;
}
}
#Override
public void onRebind(Intent intent) {
super.onRebind(intent);
Log.i(LOG_TAG, "--------onRebind--------");
}
#Override
public boolean onUnbind(Intent intent) {
Log.i(LOG_TAG, "--------onUnbind--------");
return super.onUnbind(intent);
}
#Override
public void onCreate() {
super.onCreate();
Log.i(LOG_TAG, "--------onCreate--------");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(LOG_TAG, "--------onStartCommand--------");
int i = super.onStartCommand(intent, flags, startId);
Log.e(LOG_TAG,"--------onStartCommand--------, i = " + i +",START_NOT_STICKY="+ START_NOT_STICKY);
return START_NOT_STICKY;
}
#Override
protected void onServiceConnected() {
Log.i(LOG_TAG,"onServiceConnected enter");
super.onServiceConnected();
//Configure these here for compatibility with API 13 and below.
AccessibilityServiceInfo config = new AccessibilityServiceInfo();
config.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
config.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
config.notificationTimeout = 100;
if (Build.VERSION.SDK_INT >= 16)
//Just in case this helps
config.flags = AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
setServiceInfo(config);
Log.i(LOG_TAG,"onServiceConnected");
}
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
Log.i(LOG_TAG,"onAccessibilityEvent");
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
ComponentName componentName = new ComponentName(
event.getPackageName().toString(),
event.getClassName().toString()
);
ActivityInfo activityInfo = tryGetActivity(componentName);
boolean isActivity = activityInfo != null;
if (isActivity)
Log.i("CurrentActivity", componentName.flattenToShortString());
}
}
private ActivityInfo tryGetActivity(ComponentName componentName) {
try {
return getPackageManager().getActivityInfo(componentName, 0);
} catch (PackageManager.NameNotFoundException e) {
return null;
}
}
#Override
public void onInterrupt() {}
#Override
public void onDestroy() {
Log.i(LOG_TAG, "--------onDestroy--------");
super.onDestroy();
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final String LOG_TAG = "MainActivity";
public static int OVERLAY_PERMISSION_REQ_CODE = 1234;
private boolean isBoundMonitorService = false;
private ActivityMonitorService monitorService = null;//get minitor service through binder
private ActivityMonitorService.MyBinder myBinder = null;
private ServiceConnection monitorConnection = new ServiceConnection() {
#Override
public void onServiceDisconnected(ComponentName name) {
Log.e(ActivityMonitorService.LOG_TAG, "------onServiceDisconnected---------");
isBoundMonitorService = false;
};
public void onServiceConnected(ComponentName name, IBinder service) {
isBoundMonitorService = true;
Log.e(ActivityMonitorService.LOG_TAG, "------onServiceConnected---------");
//myBinder = (ActivityMonitorService.MyBinder)service;
//monitorService = myBinder.getService();
};
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
Toast.makeText(MainActivity.this, "no permission", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
}
}
Log.d(LOG_TAG, "onCreate");
//WindowUtils.showPopupWindow(getApplicationContext());
Intent ServiceIntent = new Intent(this, ServiceUtils.class);
startService(ServiceIntent);
Intent AndroidMonitorServiceIntent = new Intent(this, ActivityMonitorService.class);
bindService(AndroidMonitorServiceIntent,monitorConnection,BIND_AUTO_CREATE);//
Log.e(ActivityMonitorService.LOG_TAG, "------bindService---------");
//finish();
}
#Override
protected void onDestroy(){
if(isBoundMonitorService)
{
Log.e(ActivityMonitorService.LOG_TAG, "------unbindService---------");
unbindService(monitorConnection);
isBoundMonitorService = false;
}
super.onDestroy();
//Intent ServiceIntent = new Intent(this, ServiceUtils.class);
//stopService(ServiceIntent);
//finish();
}
}
AndroidManifest.xml
<service
android:name=".util.ActivityMonitorService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
android:enabled = "true"
android:exported = "false">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService"/>
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="#xml/accessibilityservice"/>
</service>
xml/accessibilityservice.xml
<accessibility-service
xmlns:tools="http://schemas.android.com/tools"
android:accessibilityEventTypes="typeWindowStateChanged"
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagIncludeNotImportantViews"
xmlns:android="http://schemas.android.com/apk/res/android"
tools:ignore="UnusedAttribute"/>
Add some logs
05-24 08:32:44.989 8313-8313/? I/HwLauncher: Launcher Launcher.onStart() cost 1 ms
05-24 08:32:44.989 6778-6814/? W/WindowManager: Attempted to remove non-existing token: android.os.Binder#342478f
05-24 08:32:44.989 8313-8313/? I/HwLauncher: Launcher onResume()
05-24 08:32:44.989 8313-8430/? E/HwLauncher: SettingsEx , no such field.
05-24 08:32:44.989 8313-8313/? I/HwLauncher: Launcher doResumeWork()
05-24 08:32:44.989 8313-8430/? W/HwLauncher: Clock getDataFormat the getSystemString failed.
05-24 08:32:44.990 6778-6814/? E/AndroidRuntime: *** FATAL EXCEPTION IN SYSTEM PROCESS: android.bg
java.lang.RuntimeException: Error receiving broadcast Intent { act=android.intent.action.PACKAGE_RESTARTED dat=package:com.example.org.floatwindow flg=0x10 (has extras) } in com.android.server.accessibility.AccessibilityManagerService$1#5de13ec
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:1235)
at android.os.Handler.handleCallback(Handler.java:761)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:156)
at android.os.HandlerThread.run(HandlerThread.java:61)
Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'boolean android.os.IBinder.unlinkToDeath(android.os.IBinder$DeathRecipient, int)' on a null object reference
at com.android.server.accessibility.AccessibilityManagerService$Service.unlinkToOwnDeathLocked(AccessibilityManagerService.java:3122)
at com.android.server.accessibility.AccessibilityManagerService$Service.onRemoved(AccessibilityManagerService.java:3113)
at com.android.server.accessibility.AccessibilityManagerService.removeServiceLocked(AccessibilityManagerService.java:1145)
at com.android.server.accessibility.AccessibilityManagerService.-wrap22(AccessibilityManagerService.java)
at com.android.server.accessibility.AccessibilityManagerService$Service.unbindLocked(AccessibilityManagerService.java:2385)
at com.android.server.accessibility.AccessibilityManagerService.updateServicesLocked(AccessibilityManagerService.java:1307)
at com.android.server.accessibility.AccessibilityManagerService.onUserStateChangedLocked(AccessibilityManagerService.java:1445)
at com.android.server.accessibility.AccessibilityManagerService.-wrap19(AccessibilityManagerService.java)
at com.android.server.accessibility.AccessibilityManagerService$1.onHandleForceStop(AccessibilityManagerService.java:343)
at com.android.internal.content.PackageMonitor.onReceive(PackageMonitor.java:388)
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:1222)
at android.os.Handler.handleCallback(Handler.java:761)?
at android.os.Handler.dispatchMessage(Handler.java:98)?
at android.os.Looper.loop(Looper.java:156)?
at android.os.HandlerThread.run(HandlerThread.java:61)?
You don't start AccessibilityServices from activities. Accessibility services are started from the
Settings > Accessibility
area on the phone. You cannot start an Accessibility Service in the way you are attempting.

GoogleApiClient.ConnectionCallbacks methods not called after connecting to the GoogleApiClient

I have this issue:
GoogleApiClient.ConnectionCallbacks methods not being called after connecting to the GoogleApiClient
But the callbacks have been added but still no onConnection callback and no errors why would that be? Can anyone help?
My code:
public class MainActivity extends Activity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private GoogleApiClient mGoogleApiClient ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initGoogleApiClient();
}
private void initGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder( this )
.addApi(Plus.API).addScope(Plus.SCOPE_PLUS_LOGIN)
.addApi(Games.API).addScope(Games.SCOPE_GAMES)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
#Override
public void onConnected(Bundle bundle) {
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
protected void onDestroy() {
super.onDestroy();
mGoogleApiClient.disconnect();
}
#Override
public void onConnectionFailed(com.google.android.gms.common.ConnectionResult connectionResult) {
}
I'll answer my own question - again. The answer is to do with setting up the developer console with a debug key:
https://developers.google.com/games/services/console/enabling#a_create_a_linked_application
I can’t find the Android keytool
How to obtain Signing certificate fingerprint (SHA1) for OAuth 2.0 on Android?
It's ok I've done it! Apparently you can't just debug you app from Eclipse you have to install it with an APK otherwise it wont work. As described here:
https://developers.google.com/games/services/android/quickstart
Good luck to anyone else wading through all the fantastic Google documentation.
:-S