Open an url in android browser, avoid multiple tabs - android

My project is mostly a web application. Now I have an android app with a home screen widget and would like to open a web page in the built-in browser on some user actions. That is easy. In MyAppWidgetProvider.onUpdate I create a new intent:
Intent intent = new Intent("android.intent.action.VIEW",
Uri.parse("http://my.example.com/"));
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.text, pendingIntent);
Unfortunately, a new browser window/tab is opened every time the user clicks the widget. My page contains some fancy AJAX/javascript running in the background and regularly sending http requests. So I end up having 8 tabs containing the same page and continuously sending 8-fold amount of http requests.
Is there any way, e.g. different action or additional parameters to avoid opening new tabs?
As a workaround I am now thinking about creating a new activity containing a WebView, but would like to avoid this complexity.

Yes, this is possible.
Use http://developer.android.com/reference/android/provider/Browser.html#EXTRA_APPLICATION_ID to ensure that the same browser tab is reused for your application. For example:
Context context = widget.getContext();
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());

To the best of my knowledge there is no way to specify if a new tab is opened or not using the Intent. I even did some looking and could not find anyway to check which tabs were open.
Another thing you may be able to try is keeping track of if the user has recently been sent to the browser activity from your application, and check if the browser is still open, but once again I can see this going wrong in numerous ways.
Your activity idea would probably be one of the best bets in this situation, though I can understand why you would want to avoid that.

Related

Always open a new/fresh tab/window using Android browser intent

It's a simple request from a simple man.
I am running some OAuth challenge stuff in my code and I want the user to always see a fresh new page on the browser.
I have seen a whole bunch of threads; but none of them really answer this question.
Here's how I am creating an Android browser intent (using c#/Xamarin):
static void GoToAndroidBrowserWithLoginUri(Activity activity, Uri uri)
{
Intent oauthIntent = new Intent(Intent.ActionView, uri);
activity.StartActivity(oauthIntent);
}
with intent flags you can do this:
oauthIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
update: what happens if you add this category to the intent:
oauthIntent.addCategory("android.intent.category.LAUNCHER");
if that doesn't work, lets create a separate task for these activities. Add these flags only:
oauthIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); //clear whats already in your task list
oauthIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//create a new task to contain the activity

Invoke system contact app and retrieve data android

Im developing an application where in I have 2 text views and a button.
when I click the button, it should open default system contacts application and upon selecting a contact, it should display the name and number in the text fields respectively.
Now I have implemented ContactsContract and getContentResolver. But, I have seen other apps having this feature, which is quite easy because you need not create a list view and stuffs.
Now how do I start? how do I invoke default contact app and retrieve data from it.
I don't know the details about your problem, but I am pretty sure that you need to use an Implicit Intent (because the Contacts app may be different on different devices). Hopefully this page will help.
You may need to start by using this code:
Intent i = new Intent(); // Declare intent
// Start the intent
startActivity(i);
You may want to use ACTION_GET_CONTENT.
Thanks for the replies. I found out that this is what i need.
Intent localIntent = new Intent("android.intent.action.PICK",ContactsContract.Contacts.CONTENT_URI);

Android deep-linking. Intent doesn't reset when app is opened from history

I have a problem regarding Android task and intent management.
Scenario
User gets a push with a deep-link into the app.
We show a notification putting the URI into the Intent Data.
User clicks the notification and is taken into the app and redirected to some Feature1Activity described by the deep-link.
User looks around, and backs out of the app.
Later, user opens the app from history (long-press home or multitasking button).
Now the same intent that were used from the notification (with the deep-link in the Intent Data) is used to start the app.
Hence, user is taken into the Feature1Activity again.
Problem:
Starting the app from history (long-press home or multitasking button) does not reset the Task (which it does when launching from app icon).
I understand that starting an app from history is not supposed to reset the task since it is intended to be used as "get-right-back-where-you-were". However, in my case this is an issue since the launch of the app from a notification is a one time thing.
Anyone else encountered this problem? Anyone know any solution?
More in-depth
The intent inside the PendingIntent is built like this:
Intent intent = new Intent (Intent.ActionView);
intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags (Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags (Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
intent.setData (Uri.Parse (DEEP_LINK_URL));
I found out about the FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET just this day and really thought that it would git rid of my problem but it made no difference.
There are three activities of interest:
SplashActivity (main launcher & listener of the deep-linking schema -- this activity just redirects either to login or OverviewActivity)
OverviewActivity (authorized user's main activity)
Feature1Activity (any feature that the deep-link is pointing to)
What happens when the user clicks the notification is that the SplashActivity acts as a listener for the schema and converts the deep-link url to two intents to start up OverviewActivity and Feature1Activity using Activity.startActivities (Intent[]).
When I look at the intent from the notification inside SplashActivity it always contain the deep-link in the Data.
One work around
There is a work around, setting some booleanExtra field to the notification intent (for instance "ignoreWhenLaunchedFromHistory" = true) and then check in SplashActivity before redirecting
boolean fromHistory = (getIntent().getFlags() & FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY;
if (fromHistory && getIntent().getBooleanExtra ("ignoreWhenLaunchedFromHistory", false))
// Don't follow deep-link even if it exists
else
// Follow deep-link
Except that it hackish and ugly, can you see any problems with this work around?
EDIT: The work around only works when I am responsible for sending the Intent with the deep-link. Since no external source can know about the "ignoreWhenLaunchedFromHistory" extra.
From what I get, maybe using android:excludeFromRecents="true"on your manifest (as a property for the Activity declaration) might ameliorate the issue?

Managing the back stack after oauth login on Android

I am implementing oauth login in Android, and I'm stuck on one point. I am required to redirect to the native browser to initiate the login (rather than use an embedded WebView of my own), but that is causing issues with the back stack. My goal is simple: return to my activity after the redirect with no trace of the native browser in the back stack. Here is the closest I've come so far:
To initiate the login from my activity I use:
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY
| Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
context.startActivity(intent);
I have a separate activity to receive the return redirect and handle the rest of the login process. I don't really care whether it's a separate activity or not, it is just my current solution. In its manifest I set android:noHistory="true". Once it finishes the login process, I attempt to return to the first activity using code like this:
Intent intent = new Intent(context, OrigActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
However, this ends up creating a second copy of the original activity, and when I press back it returns me to the first copy. In other words, it does not seem to respect FLAG_ACTIVITY_CLEAR_TOP. Did I miss something simple to make it work, despite all my searching? Or is there some other way I should go about all of this?
Edit: It turns out the problem stems from the fact that the browser is launched in a separate task. From some Android documentation:
... if your application issues an intent to open the Android Browser, its activity is not placed in the same task as your application. Instead, either a new task starts for the Browser or, if the Browser already has a task running in the background, that task is brought forward to handle the new intent.
If I set my original activity's launch mode to singleTask it properly brings it to the foreground instead of creating a new copy, but a new problem occurs. The browser is now in the back stack behind all of my activities, so now it seems FLAG_ACTIVITY_NO_HISTORY is not being respected. I'm not sure if that brings me any closer to a proper solution ...
Edit 2: Correction: if the browser was not running before I launched it, everything works perfectly. However, if it WAS already running FLAG_ACTIVITY_NO_HISTORY seems to have no effect on it.
What you're seeing makes sense because calling the browser with the FLAG_ACTIVITY_NO_HISTORY wouldn't remove back stack from PRIOR to the start of your application.

Open my application from another in android

My boss asked me to prove that my application behaves properly when summoned by another application (dunno why he asked that).
So I have two apps here, one launches a second one. How I launch the specific app I want? Using Intent launch seemly any generic app that reaches a certain goal, not the app I really want.
Give this a try.
Intent secondIntent = new Intent();
secondIntent.setAction(Intent.ACTION_MAIN);
secondIntent.setClassName("com.example", "com.example.YourSecondApp");
startActivity(secondIntent);
I should point out that com.example should be the package of your second application (the one you want to call) and com.example.YourSecondapp is the class name where you have your onCreate() method.
Intent secondApp = new Intent("com.test.SecondApp");
startActivity(secondApp);
Check out for more examples
http://developer.android.com/resources/faq/commontasks.html#opennewscreen
Create one Intent using the following code
Explicit Intent
When you know the particular component(activity/service) to be loaded
Intent intent = new Intent();
intent.setClass("className/package name");
start<Activity/Service>(intent);
Imlicit Intent
When we do not have the idea which class to load and we know the Action to be perform by the launched application we can go with this intent.
Action needs to set, and the Android run time fallows the intent Resolution technique and list out(one or more components) the components to perform the action. from the list out components (if more than one), user will get the chance to launch his chosen application

Categories

Resources