launch/cancel activity immediatly when conditions are met in a service - java

So I'm building an application locker for android.Ive written a service for my locker activity to launch as soon as a particular activity is detected on top on the android application stack.The list of applications to be locked are stored in a table in a database.For the most part my service works fine.But I'm facing some issues which i do not know how to overcome. Any help is greatfully accepted
I want to resolve the following issues.
1) When i press the back button i want my locker activity and The app which was being to locked to stop executing. In my case,the lockeractivity keeps on launching again and again when i press the back button.
2) When a particular app which need to be be locked launches, the app is shown on the screen for a 1 second or 2 before my locker activity gets called.i want my locker activity to be invoked directly.
3) And some times my locker activity is called again once a user has already verified himself which is do not want. (i think this is cause of the timing of the service to check the foreground activity)
My Service
public class LockerService extends Service {
private static final String TAG = "MyService";
String LockedApps[];
String allowedapp = null;
DataBaseHandler handler;
private final static Handler servicehandler = new Handler() {
#Override
public void handleMessage(Message msg) {
}
};
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
handler = new DataBaseHandler(this);
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
private Runnable checkforeground = new Runnable() {
public void run() {
// / Any thing you want to do put the code here like web service
// procees it will run in ever 1 second
handler.open();
LockedApps = handler.getPackages();
handler.close();
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfo = am
.getRunningAppProcesses();
String foregroundapp = runningAppProcessInfo.get(0).processName
.toString();
SharedPreferences sp = PreferenceManager
.getDefaultSharedPreferences(LockerService.this);
allowedapp = sp.getString("allowedapp", "anon");
if ((Arrays.asList(LockedApps).contains(foregroundapp))
&& (allowedapp.equals(foregroundapp))) {
// do nothing
} else if (Arrays.asList(LockedApps).contains(foregroundapp)) {
// show your activity here on top of
// PACKAGE_NAME.ACTIVITY_NAME
Intent lockIntent = new Intent(getBaseContext(), Locker.class);
lockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getBaseContext().startActivity(lockIntent);
}
servicehandler.postDelayed(this, 1500); // 1.5 seconds
}
};
#Override
public void onStart(Intent intent, int startId) {
servicehandler.removeCallbacks(checkforeground);
servicehandler.postDelayed(checkforeground, 1500);// 1.5 second
Log.d(TAG, "onStart");
}
}

Just Override onBackPressed() method in locker activity and fire a intent to the home launcher. that is nothing but it will takes you to the home screen.

Related

Android service running but overlay activity flicks and disappears

Background info: I'm trying to create a service. I create it in my main activity. I know the service is running because the notification is showing. So the service doesn't stop at any point.
What i want to happen: when the screen is locked/turned off i want a certain activity to be displayed for when the screen is turned back on.
What is happening: first, When the screen is turned back on the main activity shows and then the activity i want shows over that. I dont want the main activity to show at all when the screen is turned on .
Then i changed a few things: and now the desired activity flickers on the main screen and then vanishes. It seems very unreliable and only comes a few times.
That should be enough info, here is the code so far (specifically onReceive())
public class OverlayService extends Service{
//IN THIS CLASS CHECK WHETHER LOCK BUTTON WAS PRESSED OR IF PHONE WHEN TO SLEEP.. UPON AWAKENING START THE OVERLAY ACTIVITY...
private BroadcastReceiver mReceiver;
private boolean isShowing = false;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
private WindowManager windowManager;
WindowManager.LayoutParams params;
#Override
public void onCreate() {
super.onCreate();
windowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
//Register receiver for determining screen off and if user is present
mReceiver = new OverlayStateReceiver();
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_USER_PRESENT);
filter.addAction(Intent.ACTION_SCREEN_ON);
registerReceiver(mReceiver, filter);
makeNotification();
}
void makeNotification() {
Notification notification = new NotificationCompat.Builder(this)
//TODO change icon
.setSmallIcon(R.drawable.test)
.setContentTitle("App")
.setContentText("service is running...")
.setPriority(Notification.PRIORITY_LOW)
.build();
startForeground(1, notification);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
public class OverlayStateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.i("app", "load view");
showOverlayActivity(context);
}
}
}
private void showOverlayActivity(Context context) {
Intent intent = new Intent(context, OverlayActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
#Override
public void onDestroy() {
//unregister receiver when the service is destroy
if (mReceiver != null) {
unregisterReceiver(mReceiver);
}
//TODO remove view if it is showing and the service is destroy
super.onDestroy();
}
}

android run class in service with new thread

i just use service to make something like chathead and this is my result
but only i have two problem
first some time my service killed i notice that's on weak device so how can i prevent it from killed in same time the facebook messenger never killed
second my class animation not smooth i think i must run the class on new thread
xxx = new classanimation (mContext);
i tried this
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
xxx = new classanimation (mContext);
}
});
but i see it same no different
and this is my service code
public class MyCustomService extends Service {
private volatile HandlerThread mHandlerThread;
private ServiceHandler mServiceHandler;
private static Context mContext;
Handler mHandler;
IBinder mBinder = new LocalBinder();
public static Socket client;
public classanimation xxx;
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public class LocalBinder extends Binder {
public MyCustomService getServerInstance() {
return MyCustomService.this;
}
}
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
// Define how to handle any incoming messages here
#Override
public void handleMessage(Message message) {
// ...
// When needed, stop the service with
// stopSelf();
}
}
public void onCreate() {
super.onCreate();
this.mContext = this;
xxx= new classanimation(mContext); //class i run it but its not smooth
mHandler = new Handler(Looper.getMainLooper());
// An Android handler thread internally operates on a looper.
mHandlerThread = new HandlerThread("MyCustomService.HandlerThread");
mHandlerThread.start();
// An Android service handler is a handler running on a specific background thread.
mServiceHandler = new ServiceHandler(mHandlerThread.getLooper());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Send empty message to background thread
mServiceHandler.sendEmptyMessageDelayed(0, 500);
// or run code in background
mServiceHandler.post(new Runnable() {
#Override
public void run() {
// Do something here in background!
SessionManager session = new SessionManager(mContext);
// If desired, stop the service
//stopSelf();
}
});
// Keep service around "sticky"
return START_STICKY;
}
#Override
public void onDestroy() {
// Cleanup service before destruction
mHandlerThread.quit();
}
}
To ensure that your service is never killed, you can make your service a foreground service by using a notifiaction. This means that there will always be a notification icon when the service is running, but it will never be killed. For example :
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text), System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title), getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION_ID, notification);
You can't prevent from killing,Yes but you can minimize probability of killing by starting service in different process than your app process.

I want to kill/ close a particular app by pressing a button in my current app. How can I do this?

Here's what i want:
My app is having a button for closing another independent application say - Google map. I want to know if the process has started and if it does then i want to close it by pressing that button.
You can use the BroadcastReceiver Class.
Try this way.
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (isAppForground(context)) {
// App is in Foreground
} else {
// App is in Background
}
}
public boolean isAppForground(Context mContext) {
ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> tasks = am.getRunningTasks(1);
if (!tasks.isEmpty()) {
ComponentName topActivity = tasks.get(0).topActivity;
if (!topActivity.getPackageName().equals(mContext.getPackageName())) {
return false;
}
}
return true;
}

Service containing BroadCastReceiver not functioning correctly

Please see edits before answering!
I have an app which contains a BackgroundService class:
public class BackgroundService extends Service {
#Override
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter();
filter.addAction("com.spotify.music.playbackstatechanged");
filter.addAction("com.spotify.music.metadatachanged");
filter.addAction("com.spotify.music.queuechanged");
registerReceiver(receiver, filter);
Log.e("Playing:", "APP IS PLAYING");
Notification notification = new Notification();
startForeground(1, notification);
}
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
long timeSentInMs = intent.getLongExtra("timeSent", 0L);
String action = intent.getAction();
if (action.equals(BroadcastTypes.METADATA_CHANGED)) {
String trackId = intent.getStringExtra("id");
String artistName = intent.getStringExtra("artist");
String albumName = intent.getStringExtra("album");
String trackName = intent.getStringExtra("track");
int trackLengthInSec = intent.getIntExtra("length", 0);
// Do something with extracted information...
} else if (action.equals(BroadcastTypes.PLAYBACK_STATE_CHANGED)) {
boolean playing = intent.getBooleanExtra("playing", false);
Log.e("Playing:","TRUE");
}
}
};
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
static final class BroadcastTypes {
static final String SPOTIFY_PACKAGE = "com.spotify.music";
static final String PLAYBACK_STATE_CHANGED = SPOTIFY_PACKAGE + ".playbackstatechanged";
static final String METADATA_CHANGED = SPOTIFY_PACKAGE + ".metadatachanged";
}
}
and this is declared in my manifest:
<service
android:name=".BackgroundService"
android:enabled="true" >
<intent-filter>
<action android:name="com.spotify.music.playbackstatechanged" />
<action android:name="com.spotify.music.metadatachanged" />
<action android:name="com.spotify.music.queuechanged" />
</intent-filter>
</service>
So essentially my objective is to have my BackgroundService initialized when my app is opened, and to have it continue to run in the Background doing whatever I need it to do. As of now, I am using logs to determine whether my "setup" is working, but when I run my app, I am unable to see an logs even after I tested all actions that should have triggered my BroadCastReceiver. Furthermore, my persistent notification should have changed had my service been running, but it does not...
Edit::
So, I added logs to my BackgroundService's onCreate() and onReceive() methods, however, neither seem to be appearing. Im wondering, do I need to do something in my launcher activity to initialize the service? Furthermore, no notification is shown so I assume the Service is not being started for some reason...
Latest Edit:
So I added the following code to my Main activity to see if it would make a difference:
startService(new Intent(this,BackgroundService.class));
And after debugging my app, I began to see the following error:
java.lang.RuntimeException: Unable to create service com.aurum.mutify.BackgroundService: java.lang.SecurityException: Isolated process not allowed to call registerReceiver
pointing to my BroadCast Receiver class.
Intent services are designed for short tasks. And your intent handling method is empty.
If you need long running task in the background use standard service and call start foreground. This will minimize chance of system destroying your service.
To learn more go here
EDIT
Try overriding onStartCommand method. this method is called when service is started and usually you do all stuff here. Remember that there are 3 options to return.
Edit 2:
try something like this
in on create
PendingIntent pi;
BroadcastReceiver br;
Intent myIntent;
#Override
public void onCreate()
{
super.onCreate();
myIntent = new Intent("something")
if(Build.Version.SDK_INT >= 16) //The flag we used here was only added at API 16
myIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
//use myIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); if you want to add more than one flag to this intent;
pi = PendingIntent.getBroadcast(context, 1, myIntent, 0);
br = new BroadcastReceiver ()
{
public void onReceive (Context context, Intent i) {
new thread(new Runnable()
{
public void run()
{
//do something
}
}).start();
}
};
And then in on start command
this.registerReceiver(br, new IntentFilter("something"));

How to create and start a dream service atomatically android

I am trying to start a dream service. Currently, this is my code:
#SuppressLint("NewApi")
public class DreamLockService extends DreamService {
private static final String TAG = "DreamLockService";
public Utility utilObj = new Utility();
//private Button btnExit;
private Button btnlogin;
private EditText lgPass;
#Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
// Exit dream upon user touch
setInteractive(true);
// Hide system UI
setFullscreen(true);
// Set the dream layout
setContentView(R.layout.lockservice);
//setClickListener();
Toast.makeText(this, "Lock Service Created", Toast.LENGTH_LONG).show();
}
//Use this for initial setup, such as calling setContentView().
#Override
public void onDreamingStarted() {
super.onDreamingStarted();
// Exit dream upon user touch
setInteractive(true);
// Hide system UI
setFullscreen(true);
// Set the dream layout
setContentView(R.layout.lockservice);
Toast.makeText(this, "Lock Service Created", Toast.LENGTH_LONG).show();
}
//Your dream has started, so you should begin animations or other behaviors here.
public void onDreamingStopped()
{
super.onDreamingStopped();
}
//Use this to stop the things you started in onDreamingStarted().
public void onDetachedFromWindow()
{
super.onDetachedFromWindow();
}
}
I was unable to start the dream service from another activity. This is what I used:
Intent tempLock = new Intent(MainActivity.this, DreamLockService.class);
//DreamLockService test = new DreamLockService();
startService(tempLock);
I don't understand why it didn't work. How can a dream service be started from another activity?
To start a Dream service from our own app, please try this.
IBinder binder = ServiceManager.getService("dreams");
Parcel data = Parcel.obtain();
data.writeInterfaceToken("android.service.dreams.IDreamManager");
Parcel reply = Parcel.obtain();
try {
if (binder != null)
binder.transact(1, data,reply, Binder.FLAG_ONEWAY);
else
Log.e("TAG", "dreams service is not running");
} catch (RemoteException e) {
e.printStackTrace();
}
To use this, your app should be system app and should have dream permissions in the Manifest file and enable dream setting in Settings.
I tried this and it is working.
You can start the currently selected screen saver using this code:
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setClassName("com.android.systemui", "com.android.systemui.Somnambulator");
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
Just need to make sure that your dream service is set and enabled.
Did you include it in your manifest and have an <intent-filter> that matches your action?
If it's ok, then try with:
startService(new Intent(this, DreamLockService.class));
An excellent Services tutorial: http://www.vogella.com/articles/AndroidServices/article.html#scheduleservice_startauto
UPDATE:
As it seems you are not sure if your service is running, you can use this solution found here:
private boolean isMyServiceRunning() {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (MyService.class.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}

Categories

Resources