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;
}
Related
I have an Unity app, that has Android plugin that can launch other applications that installed on my smartphone. Here My Java class:
public class LaunchOtherApp extends Activity
{
public static Activity mainActivity;
protected static final String LOGTAG = "MyApp";
private Activity currentActivity;
private Intent i;
private static final LaunchOtherApp ourInstance = new LaunchOtherApp();
public static LaunchOtherApp getInstance() {
return ourInstance;
}
public LaunchOtherApp(){
Log.i(LOGTAG,"Created LaunchOtherApp");
}
public void Launch( final String pack)
{
mainActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
Intent intent = new Intent();
intent.setPackage(pack);
currentActivity = UnityPlayer.currentActivity;
Context context = currentActivity.getApplicationContext();
PackageManager pm = context.getPackageManager();
List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
Collections.sort(resolveInfos, new ResolveInfo.DisplayNameComparator(pm));
if (resolveInfos.size() > 0)
{
try
{
ResolveInfo launchable = resolveInfos.get(0);
ActivityInfo activity = launchable.activityInfo;
ComponentName name = new ComponentName(activity.applicationInfo.packageName, activity.name);
i = new Intent(Intent.ACTION_MAIN);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
i.setComponent(name);
context.startActivity(i);
}
catch (SecurityException e)
{
intent = getPackageManager().getLaunchIntentForPackage(pack);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
startActivity(intent);
}
}
}
});
}
#Override
public void onBackPressed() {
finish();
}
Launch - it is method that starting when I click on button in my Unity app... pack variable - it is variable that my Java method receive, and in this variable instantiate Application id. For Example I launched Youtube from my app, and when I pressing Back on my phone, I want to close Youtube, and back to my Unity app... I think I must use onBackPressed method that start when I press Back, but what I must write in this method?
finish(); doesn't help me(( Please, help... Thank you in advance!
Actually, YouTube app is a separate app (might be installed) and you cannot modify that app's behavior. On your button press, Launch method is called and assume YouTube app has started. With the intent:
If you use Intent.FLAG_ACTIVITY_NEW_TASK
YouTube app will start in a new task than yours and pressing back will not return to your app.
If you do not use Intent.FLAG_ACTIVITY_NEW_TASK
The new intent (here YouTube) will be launched in the task of calling activity (your app/game) by default and calling activity will go background. So, pressing back will again return to your app/game as you desired. Because back button press always pops from the backstack of the current task.
So, in the try block of your Launch method, removing the following line should help.
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
For more information about task and back stack, here is the official doc.
Edit
I missed that you have used application context. But, you have to launch from your calling activity context, otherwise you must use this flag. So, I have modified your Launch method and put it here, just replace your Launch method with following:
/* Method to launch an app with its package name */
public void Launch( final String pack)
{
mainActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
// Using activity context instead of application context
currentActivity = UnityPlayer.currentActivity;
Context context = currentActivity;
PackageManager pm = context.getPackageManager();
// Similar code to launch from package name
Intent intent = pm.getLaunchIntentForPackage(pack);
if (intent == null) {
// The activity cannot be found or the package name cannot be recognized
// Show some message or do something
Toast.makeText(context, "Cannot launch...", Toast.LENGTH_SHORT).show();
} else {
context.startActivity(intent);
}
}
});
}
So I'm working for a company that requires a VPN in order to connect to the database server. I'm facing an issue with disconnecting programmatically from the VPN service (or disabling it) upon onPause / onStop.
In order to ensure the user is indeed connected to a VPN, I'm using a network listener and if the user is not connected, a dialog is being shown and navigates the user to the VPN Settings Configuration. Once the user connects and resumes the application, the listener recognizes the VPN IP and everything runs great.
My issue is that I want to disable the VPN connection once the user has stopped using the application. Therefore, I've been trying to search for a solution that disables the VPN connection without requesting the user to go to the VPN Settings again. Is there an option to toggle the VPN off programmatically without navigating to the VPN Settings page?
Network Service:
public class NetworkSchedulerService extends JobService implements
ConnectivityReceiver.ConnectivityReceiverListener {
private ConnectivityReceiver mConnectivityReceiver;
#Override
public void onCreate() {
super.onCreate();
mConnectivityReceiver = new ConnectivityReceiver(this);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
#Override
public boolean onStartJob(JobParameters params) {
registerReceiver(mConnectivityReceiver, new IntentFilter(Constants.CONNECTIVITY_ACTION));
return true;
}
#Override
public boolean onStopJob(JobParameters params) {
unregisterReceiver(mConnectivityReceiver);
return true;
}
#Override
public void onNetworkConnectionChanged(boolean isConnected) {
String message = isConnected ? "מחובר לרשת" : "אין חיבור פעיל לרשת";
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
}
Listener:
private void scheduleJob() {
JobInfo myJob = new JobInfo.Builder(0, new ComponentName(this, NetworkSchedulerService.class))
.setRequiresCharging(true)
.setMinimumLatency(1000)
.setOverrideDeadline(2000)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setPersisted(true)
.build();
JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(myJob);
}
#Override
protected void onStop() {
stopService(new Intent(this, NetworkSchedulerService.class));
super.onStop();
}
#Override
protected void onStart() {
super.onStart();
Intent startServiceIntent = new Intent(this, NetworkSchedulerService.class);
startService(startServiceIntent); // INTERNET LISTENER
}
Dialog:
public void dialogVPN() {
builder = new AlertDialog.Builder(LoadingSplash.this);
builder.setMessage("Please ensure VPN Connection");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent("android.net.vpn.SETTINGS");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivityForResult(intent, 10);
}
});
builder.show();
}
And the returnConnType:
public String returnConnType() {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(this.CONNECTIVITY_SERVICE);
String result = "None";
if (connectivityManager != null) {
Network network = connectivityManager.getActiveNetwork();
NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
if (capabilities == null) {
result = "None";
}
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
result = "WIFI";
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
result = "MOBILE";
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) {
result = "VPN";
}
}
return result;
}
Any suggestions as to how to solve this? A proper solution or an alternative one would be appreciated.
I don't think you can disable the VPN settings from inside the app using an API provided by Android, as I do not know about any such APIs. However, as a workaround, you can consider doing the following.
While exiting the application (on a back button press), you can use the same listener to pop up another dialog saying the user to turn off the VPN. Hence, turning off the VPN will follow the same tasks that the user had to do while turning on the VPN.
When a user exits the application using a home button press, you might consider using a JobScheduler in your onDestroy function of the exiting activity, so that you can check if the VPN connection is alive in a background service when the application is not running and create a notification which will tell the user that, the VPN is alive. Then on clicking the notification, redirect the user to the VPN configuration settings and guide the user to turn it off.
Hope that helps!
So thanks to #Reaz I've managed to find the proper solution for now.
Tested on Oreo
In case someone else is intrested..
app
implementation 'android.arch.lifecycle:extensions:1.1.1'
AppLifecycleObserver
public class AppLifecycleObserver extends MultiDexApplication implements LifecycleObserver {
public static final String TAG = AppLifecycleObserver.class.getName();
Notifications notif = new Notifications();
Context mContext;
public AppLifecycleObserver(Context context) {
mContext = context;
}
#OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onEnterForeground() {
Log.v(TAG,"FOREGROUND");
}
#OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onEnterBackground() {
Log.v(TAG,"BACKGROUND");
notif.createVPNNotification(mContext,"VPN","Please make sure to turn VPN off");
}
}
on Any activity you wish to implement # onCreate:
AppLifecycleObserver appLifecycleObserver = new AppLifecycleObserver(this);
ProcessLifecycleOwner.get().getLifecycle().addObserver(appLifecycleObserver);
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;
}
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.
I create a lock screen widget app recently. It always has the exception:
( java.lang.SecurityException: No active admin owned by uid 10034 for policy #3)
I try many methods and can not eliminate the exception. I open the activity to realize the purpose of the lock screen when the condition was founded.
public class tempActivity extends Activity {
private static final String TAG = "tempActivity";
private DevicePolicyManager policyManager;
private ComponentName componentName;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.temp);
Log.e(TAG, "Activity created~");
policyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
componentName = new ComponentName(this, AdminReceiver.class);
mylock();
}
private void mylock() {
boolean active = policyManager.isAdminActive(componentName);
if (!active) { // Without permission
Log.e(TAG, "No authority~");
activeManage(); // To get access
policyManager.lockNow(); // And lock screen
} else {
Log.e(TAG, "Has authority");
policyManager.lockNow(); // lock screen directly
}
this.finish();
}
private void activeManage() {
Log.e(TAG, "activeManage");
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, componentName);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "developers:liushuaikobe");
startActivityForResult(intent, 1);
}
}
The point is when the device admin is not active, your call to prompt it (ACTION_ADD_DEVICE_ADMIN) only ensures that the user is shown the activation intent. If he or she chooses not to activate (and which is quite likely) the lock command in the next line will fail and give the error you are encountering now.
So, basically you can only prompt the users to activate the device admin, not force them.
Delete the lockNow call in the if not active block to avoid the error.
Hope this helps.
-SB
Try:
if(Build.VERSION.SDK_INT > 8){
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}