Intercepting clicked URL opening more than 1 instance - android

I am trying to intercept a clicked URL to open my APP
<intent-filter>
<data
android:host="myurl.open"
android:path="/import"
android:scheme="http" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
In MainActivity
String linkClicked = getIntent().getDataString();
new AlertDialog.....
It almost works correctly but the problem is that:
Every new clicked link it open a new instance of my app, but I don't want this, I want it to display in the same opened instance
Example:
click myurl.open/import?=1
Open the first instance showing the dialog that the user clicked in the link
click myurl.open/import?=2
Open the first instance and display the dialog showing the new clicked URL, but its opening a new instance, so I now have 2 running apks, and if I click in the third link it will open the third, how can I make it to open only the same?
If I click in the same URL again it open the first instance opened from this URL, but it doesn't display an AlertDialog

1) To open a single instance of your app, use android:launchMode="singleTask" or android:launchMode="singleInstance" in AndroidManifest.xml in your activity tag.
2) To get the data from the new intent, just override onNewIntent() method:
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent); // to attach the new intent to your Activity
//now getIntent() will return the last data
}

Related

Why starting the Activity by an intent (Intent.ACTION_VIEW) doesn't always start a new activity and call onCreate()?

I have two Android applications.
The first application is the "browser". It gets an URL and displays it in a WebView. The corresponding activity is declared as:
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
</intent-filter>
</activity>
The second application has a few buttons. Tapping each button opens the first application and sends the URL to it using Intent.ACTION_VIEW:
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.parse(urlString);
intent.setData(uri);
intent.setComponent(new ComponentName("com.custom.browser", "com.custom.browser.MainActivity"));
startActivity(intent);
I expect this code to start a new activity as per https://developer.android.com/reference/android/app/Activity. So the browser application retrieves the URL in onCreate() by using the code:
#Override
protected void onCreate(Bundle savedInstanceState) {
...
Intent intent = getIntent();
if (intent != null && Intent.ACTION_VIEW.equals(intent.getAction())) {
displayUrl(intent.getDataString());
}
...
}
However I found that sometimes onCreate() is not called. After calling startActivity(intent), the browser application is just brought to the front, therefore displaying a previous URL.
I can override this behavior by moving the intent retrieval code in the onResume().
However I'd like to understand what am I doing wrong? Shouldn't the method startActivity(Intent) always start a new activity and always call onCreate(), as suggested by the Android documentation?
I expect this code to start a new activity
That is not necessarily what will happen.
However I found that sometimes onCreate() is not called. After calling startActivity(intent), the browser application is just brought to the front,
Yes, that will happen if the activity you are starting is already running at the front of a task. See the documentation for tasks.
I can override this behavior by moving the intent retrieval code in the onResume().
That will not work. Override onNewIntent() and get the new Intent there. Or, adjust the flags in your Intent, or adjust the manifest settings for the activity that you are starting, as is discussed in the documentation for tasks.

Clearing getIntent() data when using singleTask activity

My app can receive new files using "file open" intents:
<activity android:launchMode="singleTask" >
<intent-filter android:label="Text document" android:priority="1">
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="content"/>
<data android:scheme="file"/>
<data android:host="*"/>
<data android:mimeType="*/*"/>
<data android:pathPattern=".*\\.txt"/>
</intent-filter>
</activity>
The actual data is processed in the onCreate or onNewIntent methods:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// process intent data using getIntent().getData();
// When the app is started from a file request then the intent contains the file data.
// Settings the intent to some dummy data after processing to prevent getting the same data
// when the task is brought back again from background does not work:
setIntent(new Intent());
}
When the task is already running then this is called:
#Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
// process intent data here using intent.getData();
}
All this works fine unless the app is restarted from the Android backgrounded task selection viewer ("recent list of apps"). Each time the app is started from the task selection viewer then the getIntent().getData() is reset to the initial data which causes my app to get the same file data again.
To be more specific these are the steps:
Launch the app by clicking on a *.txt file. onCreate gets the file info.
Press the "back" key to exit the app.
Show the Android task viewer and click on the screenshot of my app. onCreate gets the same file info again. How can this be prevent?
The problem does not occur here:
Launch the app by clicking on a *.txt file. onCreate gets the file info.
Press the "back" key to exit the app.
Now I click on my app's icon in the Android launcher. onCreate does not get the file info again. This is what I want.
Is there a way to clear the getIntent() object so that it is not reset each time my app is created?
Regards,
I found a working solution:
if (((getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)) == 0) {
// process intent data
}

How to open URL in my webViewApp from outside

I created a android app, which has webview to load pages.
In my app, home page is EditText and Button, if user enters a URL in textbox then enters button, webview will loads the webpage. This works fine.
If user clicks URL in WhatsApp, mobile has options to open that URL in browsers.
I added the following code in my manifest file, to list my app along with browsers to open URLs
<intent-filter>
<action android:name="redacted.MainActivity" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<action android:name="android.intent.action.VIEW" />
</intent-filter>
Now, my app name is also available as option to open the URLs. When I select my app to open the URL, it doesn't paste the url in edit text.
What I need to add more.
In your main activity you need to describe how will onCreate behave when application is opened from an intent.
Reference link:- Link
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Get the intent that started this activity
Intent intent = getIntent();
Uri data = intent.getData();
// Figure out what to do based on the intent type
if (intent.getType().indexOf("image/") != -1) {
// Handle intents with image data ...
} else if (intent.getType().equals("text/plain")) {
// Handle intents with text ...
}
}

Is there an Android intent-filter that triggers whenever the user switches to the app?

I'm very new to configuring the AndroidManifest.xml file in an Android app, and the app I'm building is using Phonegap with Javascript and HTML, not native code.
I have some actions in my Javascript code that I want to trigger every time the user "opens" the app. What I've discovered is that the concept of "open" has more to it than I first understood. If the user opens the app, and then switches to another app, and then comes back to the first app, the first app has actually still been running in the background, so it's not starting up. I guess it would be more accurate to describe that as "switching" back to the first app.
My issue is that I have some Javascript that runs every single time the user switches to my app, whether opening it for the first time or if it had been running in the background. I didn't have to do any particular configuration to make that happen, it seems to be the default behavior.
However, some actions I need to execute are based on settings in the AndroidManifest.xml, but they ony execute if the app is being opened for the first time, not if the user is switching back to an app currently running in the background. Specifically, I want to execute actions based on whether or not the user opens the app from a link in an email, for which I set up an <intent-filter>.
Is there a way I can listen for when the user has launched my app from a link in an email, regardless of whether or not the app is already running in the background?
I think it might be relevant, so here is my <activity> tag in my AndroidManifest.xml that "listens" for the app being launched via URL:
<activity
android:name="com.xxxxxxx.xxxxxxx.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="xxxxxxx.com"
android:scheme="http" />
<data
android:host="xxxxxxx.com"
android:scheme="https" />
</intent-filter>
</activity>
Here is the the onCreate() function in my MainActivity.java file:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setIntegerProperty("splashscreen", R.drawable.splash);
super.loadUrl(Config.getStartUrl(), 3000);
adView = new AdView(this, AdSize.BANNER, AdMob_Ad_Unit);
LinearLayout layout = super.root;
layout.addView(adView);
AdRequest request = new AdRequest();
adView.loadAd(request);
}
Place this in your Launcher activity:
//this method is called every time the Activity is Created or Re-Created
//we check for null to see if the activity was only Created instead of Recreated
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState == null){
myMethod(getIntent());
}
}
//This method will be called only when the Activity is already created and receives
//a new Intent
#Override
protected void onNewIntent(Intent it){
super.onNewIntent(it);
myMethod(it)
}
private void myMethod(Intent intent){
if(intent.getAction().equals("put here the WebIntent action string or URL as they call it"){
//your code here
}
}

Need to call an activity back from javascript interface made for WebView

I am working on an application which uses web view in one of it's activities. I have attached a java script interface with the web content. I need to call an activity with data in bundle based on the click event(can say touch event). I can pass data back to Java script interface but it's not letting me call startActivity(Intent). Is there any other way I can call an activity. Thanks in advance!!
Here are the things that you need to do to support this :
For the activity to be launched :
Handle the android.intent.category.BROWSABLE category with the a particular scheme.
In WebView onClick, load the url starting with scheme handled by the app.
For ex :
TestActivity
<manifest>
<application>
<activity>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="test-app"/>
</intent-filter>
</activity>
</application>
</manifest>
URL to load after web view click :
webView.loadUrl( "test-app://data-that-you-want-to-transfer" );
HTH !
You can use the WebView OnClick to check which link was clicked and take action accordingly. Like this:
wv.setOnClickListener(new OnClickListener() {
public boolean onClick(View v){
HitTestResult result = wv.getHitTestResult();
String url = result.getExtra();
//Log.i(myTag, url);
if(url.equals("which-ever-url-you-want-to-override.com"){
Intent i = new Intent(getApplicationContext(), yourActivity.class);
startActivity(i);
}
}
});
getHitTestResult() will give you an object that will tell you where the URL of the link points. You can use this to make different links do different things within your app.

Categories

Resources