For example, when I open Facebook Login page from an application that screen (activity) is loaded in the same Task stack.
In the same way, I want to open an activity of another application from my application, to be loaded in the same Task Stack, not starting New Task.
Normally, when we access other application we use "FLAG_ACTIVITY_NEW_TASK", which creates new task.
But How do I load the other application's activity in the same Task ?
Targeted new application is not android built-in Intent activities (like email, contact, call etc.)
I am trying to open activity of my another application from one application.
UPDATE
I think I couldnt make it enough clear. I have application A and Application B installed in device, both apps made by me, not system built. Now I want to access main_activity of Application B from an activity of application A, and still remain in the same Task. Thanks
But How do I load the other application's activity in the same Task ?
First, do not use FLAG_ACTIVITY_NEW_TASK. This says that you do not want a new task.
Second, ensure that the activity that you are starting does not have a taskAffinity or launchMode that would interfere with this.
So, for example, startActivity(new Intent(android.provider.Settings.ACTION_DATE_SETTINGS)); will start the date-and-time Settings screen in your task. Most Settings screens have a taskAffinity, where this would still wind up in a separate task.
for inbulit mail application :
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("message/rfc822");
intent.putExtra(Intent.EXTRA_EMAIL , new String[]{"test#gmail.com"});
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
intent.putExtra(Intent.EXTRA_TEXT , "Content");
try {
startActivity(Intent.createChooser(intent, "Send mail..."));
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(MyActivity.this, "No email clients installed.", Toast.LENGTH_SHORT).show();
}
Related
I have a situation with the intent flag FLAG_ACTIVITY_NEW_TASK
The Scenario
I have a service which launches an activity. This service is used by my android wear application. When I launch the activity I specify the FLAG ACTIVITY NEW TASK flag as mandated by android OS (When you call an activity from a service , it is necessary to apply the NEW TASK flag).
Intent intent = new Intent(this, GoodOlActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Supposedly My application is already running and I access my service and get GoodOlActivity to launch , it would be launched on the top of the task stack (NO NEW TASK WILL BE CREATED , BECAUSE OF AFFINITIES). If i keep on launching this activity , it will keep on having its copies made on the task stack .
The Problem
Supposedly my application is not in the history stack and I have pressed home and removed it. In such a situation a user uses the android wear application and invokes the service. The service in turn invokes GoodOlActivity. Okay Good . However subsequently GoodOlActivity is never launched and remains the only activity in the task stack .
Presumption
I believe that in the first case , the multiple activites were launched on top of another because the new task was not actually created. The reason being that a task for the target activity existed.
However in the second case a new task was created , hence the constraints of that come into play . The constraints being that if an activity is already in the task stack, just that activity would be brought to the foreground.
Target
Well both the scenarios (one with the application running , and the other with it being swiped out) should be the same . I should be able to run GoodOl multiple times. Helppp ?
When user taps gallery button I want user to redirect to my application's activity which will ask the user to enter password and then redirect user back to gallery ..
I want to know which permissions should i use and which broadcast should i accept .
Well If you want to lock the gallery you can do it in encrypt Decrypt way...
You can use MediaStore to access the images and then encrypt using your application and when user Again want to access that you can allow him to show by decrypting ...
Read the following link
Can I create password protected folder in Android?
You would need to replace the gallery application entirely to do what you're proposing.
When a user taps the Gallery icon, it doesn't fire a broadcast. It sends a directed intent with the action set to MAIN.
Anything that anyone tells you for how to do this is going to be wrong. You cannot do it.
The closest you could get is to use the MediaStore in your own app to access the same images that the gallery accesses.
Start a thread from your app which should periodically monitor foreground app name which in this case should be the Gallery (I cant remember the exact name But you can find it out using below logic).
Then if it is Gallery, open up your activity by blocking it.
If password success close activity & background will be the Gellery or otherwise redirect to Home.
For monitor foreground app
try {
ActivityManager activityManager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> runningTasks = activityManager.getRunningTasks(1);
PackageManager pm = getApplicationContext().getPackageManager();
output1 = pm.getApplicationLabel(pm.getApplicationInfo(runningTasks.get(0).baseActivity.getPackageName(),PackageManager.GET_META_DATA)).toString();
String className = runningTasks.get(0).topActivity.getClassName();
if( className.contains("Gallery")) {
//better to create this object globally outside the thread.
Intent intentSettingLock = new Intent();
intentSettingLock.setClass(oContext,SettingsLockNew.class);
intentSettingLock.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
oContext.startActivity(intentSettingLock);
}
}
catch(Exception e) {
}
To redirect to home on invalid password
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
this.finish();
You can not perform this as you described because pressing the gallery app icon from the launcher the system fires an intent with action=MAIN and category=LAUNCHER for the specific application package.
Since you cannot name your application package as the gallery package name you cant filter this intent.
Here is my problem. I am developing app that loads some documents from server. I open document in another app via Intent.ACTION_VIEW. This is all working just fine. Problem is that whole app is pin protected so I have to capture events such "sent to background" or "screen lock" to bring up pin screen afterwards and this is not working when another app is opened above mine. So if user opens document then press home button, click on my launch icon from menu then he gets again external app with opened document and with back button access my app again. This is security issue that needs to be fixed.
Here are some code snippets:
Opening document:
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri uri = Uri.fromFile(downloadedFile);
String mimeType = document.getMimeType();
intent.setDataAndType(uri, mimeType);
startActivityForResult(intent, 1);
capture sent to background:
ActivityManager am = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> tasks = am.getRunningTasks(1);
if (!tasks.isEmpty()) {
ComponentName topActivity = tasks.get(0).topActivity;
if (!topActivity.getPackageName().equals(context.getPackageName())) {
IN_BACKGROUND = true;
Log.i(PinUtil.class.getSimpleName(), "App sent to background ");
} else {
IN_BACKGROUND = false;
}
}
My question is: Is it possible to detect if my app is sent to background when another app is opened? How not to open another app when my launcher icon is pressed.
Thanks for all responses.
Regards
Lubos
In order to fix this problem:
So if user opens document then press home button, click on my launch
icon from menu then he gets again external app with opened document
and with back button access my app again. This is security issue that
needs to be fixed. Here are some code snippets:
You need to make sure that, when you launch an external app for the user to view a document, that the external app does not run in the same task as your application. It needs to run in a new, separate task. You can do this like this:
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // Ensure app runs in separate task
Uri uri = Uri.fromFile(downloadedFile);
String mimeType = document.getMimeType();
intent.setDataAndType(uri, mimeType);
startActivity(intent); // Can't use startActivityForResult() here
However, you can't use startActivityForResult() when you launch the external viewer, because an activity running in another task cannot return a result to you. However, most external applications won't return a result when launched with ACTION_VIEW anyway, so it probably isn't a problem.
Then you asked this:
My question is: Is it possible to detect if my app is sent to
background when another app is opened? How not to open another app
when my launcher icon is pressed.
There should be some answers on StackOverflow that can help you determine if your application is in the background (it isn't actually that easy to determine this).
My explanation above should answer your 2nd question. If you don't launch other apps in your task, then only your app will be launched when your launcher icon is pressed.
I am working on a phonegap application, with some native pieces.
So far I have notifications running natively, to make sure javascript and phonegap is not required at all. The problem I am having however, is when the notification is clicked I'd like to open the app, or otherwise just bring the app to the front.
How do I do this? I tried setting the main activity in the intent, but it restarts my application every time.
Intent notificationIntent = new Intent(context, main.app.class);
notificationIntent.putExtra(NOTIF_RESPOND, runThis);
notificationIntent.setAction(Intent.ACTION_VIEW);
notificationIntent = notificationIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
Actually in Android there is almost no such thing as "restarting application". Basically the Application - is a bundle of all your services/activities/providers etc. It's either running or not.
If user starts a new Activity - system will check, if application is running - it will create this activity inside the application. If no - will create new Application instance.
So I think you mean that if you set intent for your Main activity - another instance of Activity is launching, am I right?
If so - take a look at the following flag for activity, you should try to set in in the Manifest(or whatever in PhoneGap, sorry). http://developer.android.com/guide/topics/manifest/activity-element.html#lmode
<activity android:name=".YourActivity"
android:launchMode="singleTask"
...
This flag will tell the system not to create a new Activity each type it will be needed, but to reuse already-existing one. Be careful, you should properly implement onNewIntent method in this case to handle this "relaunches", and I'm not 100% sure that it's implemented in PhoneGap.
Good luck
I am trying to open the browser window from my service with a link that opens in the current tab of the browser. when I use
Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("http://www.google.com"));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
context.startActivity(intent);
If the browser was opened and in the foreground before my service starts the intent and the browser opens the link in the same window/tab. If the Browser was minimized and the service starts the intent, the browser opens the webpage in a new window/tab.
I cannot use a web-view as it needs to be in the web browser and it will only be dealing with the default browser. I have checked out the thread at Open an url in android browser, avoid multiple tabs but it did not have an answer. I also have tried force closing the browser but that is also does not work.
Thank you for any help!
If you want to use your app to fire that intent .. so call your app directly through package name
check the following code:
Intent in = getPackageManager().getLaunchIntentForPackage("com.package.myappweb");
in.putExtra("myURL","http://www.google.com");
in.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity( in );
you can pass the URL through intent and get it in your app by:
String url=getIntent().getStringExtra("myURL");
if(url!=null){
/// launch app and use one tab for showing the webpage
}else{
//launch app normally.
}
the code you mentioned used for using app as web-app ..that will show popup window to use to pick up any browser to deal with the link .. not that would be for any app wanna open link
good luck,
The way to avoid multiple tabs is as follows:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
intent.putExtra(Browser.EXTRA_APPLICATION_ID, getPackageName());
startActivity(intent);
The EXTRA_APPLICATION_ID will contain an ID of your app, and the browser will recycle a tab that was opened by your application, rather than opening a new tab. In this way, all the pages opened by your application will share the same tab, and you will not have "tab inflation" in the browser.
None of the solutions above involving Browser.EXTRA_APPLICATION_ID work.
However, Google's Custom Tabs which is now the standard for opening URL's was easy to implement and works like a charm. Here's all you need to open a tab:
implementation "androidx.browser:browser:1.4.0"
String url = "https://google.com/";
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
CustomTabsIntent customTabsIntent = builder.build();
customTabsIntent.launchUrl(this, Uri.parse(url));
More can be found here.