I have code running a service behind the scenes. It is set to run when we copy the text to the phone. This code works fine on Android 8 below But the problem is when I run the app on Android 8 and above
In my searches, I realized that I had to use FOREGROUND_SERVICEs and give specific access to the project.
What solutions do you suggest now?
public class AutoDownloadService extends Service {
private ClipboardManager mClipboardManager;
public static final String CHANNEL_ID = "ForegroundServiceChannel";
@Override
public void onCreate() {
super.onCreate();
mClipboardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
mClipboardManager.addPrimaryClipChangedListener(mOnPrimaryClipChangedListener);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String input = intent.getStringExtra("inputExtra");
createNotificationChannel();
Intent notificationIntent = new Intent(this, SettingsActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service")
.setContentText(input)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
// stopSelf();
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
if (mClipboardManager != null) {
mClipboardManager.removePrimaryClipChangedListener(mOnPrimaryClipChangedListener);
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(
CHANNEL_ID,
"Foreground Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
}
}
private ClipboardManager.OnPrimaryClipChangedListener mOnPrimaryClipChangedListener =
new ClipboardManager.OnPrimaryClipChangedListener() {
@Override
public void onPrimaryClipChanged() {
ClipData clip = mClipboardManager.getPrimaryClip();
String textClipBoard = clip.getItemAt(0).getText().toString();
Toast.makeText(AutoDownloadService.this, textClipBoard, Toast.LENGTH_SHORT).show();
}
};
}
<service
android:name=".services.AutoDownloadService"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
I think you should use Intent Service instead of service. what you can do is if system shutdown your service you can again trigger it after sometime using alarm manger.
As stated in documentation
While an app is in the foreground, it can create and run both foreground and background services freely. When an app goes into the background, it has a window of several minutes in which it is still allowed to create and use services. At the end of that window, the app is considered to be idle. At this time, the system stops the app's background services, just as if the app had called the services' Service.stopSelf() methods.
So, you solution is to run foreground service on Android >= 8.0 and do something like this
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(Intent(this, AutoDownloadService.class))
} else {
startService(Intent(this, AutoDownloadService.class))
}
}
First of all, you should not do this. Monitoring clipboard in background is not something right.
Android 8 added some protection on this, so you should run as foreground services, to let the end user aware your app is monitoring the clipboard.
Anyway clipboard access only available to default IME from Android 10. So, your apps will not work in Android 10.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With