I have option in my app to start browser and load imdb website.
I'm using ActionView for this.
Intent intent1 = new Intent(android.content.Intent.ACTION_VIEW,
Uri.parse(website));
try {
activity.startActivity(intent1);
} catch (Exception e) {
Toast.makeText(activity, R.string.no_imdb, Toast.LENGTH_SHORT)
.show();
}
The problem occurs when I tap on back button.
When default browser app is launched everything is ok.
When Opera Mini app is launched, when I tap on back button, it seems like my app receives two back actions, and finish my current activity.
How to prevent this?
Try starting the intent in a new task:
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Or
intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Please add this code to your android manifest for activity that you need return
<activity
android:name="YourActivityName"
android:launchMode="singleTask">
<intent-filter>
<action android:name="schemas.your_package.YourActivityName" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.ALTERNATIVE" />
</intent-filter>
</activity>
and add this to your web page
click to load app
because only one app has this action name (schemas.your_package.YourActivityName) on your phone, web page directly return to app
Also You can Use Airbnb DeepLink lib
Example
Here's an example where we register SampleActivity to pull out an ID from a deep link like example://example.com/deepLink/123. We annotated with #DeepLink and specify there will be a parameter that we'll identify with id.
#DeepLink("example://example.com/deepLink/{id}")
public class SampleActivity extends Activity {
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
if (intent.getBooleanExtra(DeepLink.IS_DEEP_LINK, false)) {
Bundle parameters = intent.getExtras();
String idString = parameters.getString("id");
// Do something with idString
}
}
}
Related
I have an application that accepts deeplink.
Manifest.xml:
<activity
android:name=".activities.unsigned.MagicLink"
android:label="Some test">
<intent-filter android:label="Test">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="com.myapp" />
</intent-filter>
</activity>
<activity
android:name=".activities.unsigned.MainScreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Activity:
public class MagicLink extends BusAppCompatActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
if (intent != null && intent.getAction() != null) {
Uri data = intent.getData();
ServicesApi servicesApi = ServicesApi.init(this);
servicesApi.setSessionId(data.getQueryParameter(HttpRemoteApi.SESSION_ID));
startActivity(new Intent(this, LoginActivity.class));
}
}
}
This thing works perfectly if user use it. Well I want to create a test for it now. So I write something like this:
androidTest:
#RunWith(AndroidJUnit4.class)
#LargeTest
public class LoginTest {
#Rule
public final ActivityTestRule<MainScreen> main = new ActivityTestRule<>(MainScreen.class);
#Test
public void checkSmth() {
clickMagicLink();
//...
}
private void clickMagicLink() {
String url = "com.myapp://login?session_id="+utils.getSessionId();
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
main.launchActivity(i);
}
}
But instead of starting MagicLink activity this thing starts MainScreen activity (which is MAIN). What do I do wrong?
P.s. I also saw something like this: new ActivityTestRule<>(MainScreen.class,true, false);. But with this constructor my test start, but android app doesn't (I mean emulator starts but app doesn't)
ActivityTestRule.launchActivity() always starts the activity being tested. You cannot use it to start any other activity. In this case, it will always start MainActivity. The Intent parameter is passed to the activity. This allows you to send extras during a test. The intent is not used to select which activity to launch.
Also note that the docs say
Don't call this method directly, unless you explicitly requested not to lazily launch the Activity manually using the launchActivity flag in ActivityTestRule(Class, boolean, boolean).
If you want to test your MagicLink activity, you can use ActivityTestRule<MagicLink>:
#RunWith(AndroidJUnit4.class)
#LargeTest
public class MagicLinkTest {
#Rule
public final ActivityTestRule<MagicLink> main = new ActivityTestRule<>(MainScreen.class, false, false);
#Test
public void testMagicLink() {
String url = "com.myapp://login?session_id="+utils.getSessionId();
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
main.launchActivity(i);
// assertions go here
}
}
You can also use ActivityTestRule<MainScreen> but you have to simulate the exact same actions as an actual user.
I want to launch app using my own app but not by giving the package name, I want to open a custom URL.
I do this to start an application.
Intent intent = getPackageManager().getLaunchIntentForPackage(packageInfo.packageName);
startActivity(intent);
Instead of package name is it possible to give a deep-link for example:
"mobiledeeplinkingprojectdemo://product/123"
Reference
You need to define a activity that will subscribe to required intent filters:
<activity
android:name="DeepLinkListener"
android:exported="true" >
<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="host"
android:pathPattern="some regex"
android:scheme="scheme" />
</intent-filter>
</activity>
Then in onCreate of your DeepLinkListener activity you can access the host, scheme etc.:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent deepLinkingIntent= getIntent();
deepLinkingIntent.getScheme();
deepLinkingIntent.getData().getPath();
}
Perform check on path and again fire a Intent to take the user to corresponding activity. Refer data documentation for more help.
Now fire a Intent:
Intent intent = new Intent (Intent.ACTION_VIEW);
intent.setData(Uri.parse(DEEP_LINK_URL));
Don't forget to handle the exception. If there is no activity that can handle the deep link, startActivity will return an exception.
try {
context.startActivity(
Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse(deepLink)
}
)
} catch (exception: Exception) {
Toast.makeText(context, exception.localizedMessage, Toast.LENGTH_LONG).show()
}
i'm trying to develope an app for a tablet (ICS 4.0.3) that will be used in public places like bar, resturant ecc..
The user that uses that tablet ( so my application ) could not go in home and only administrator, setting a code, can go out.
What i've done is:
public class MainActivity extends Activity {
private Activity actual;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if (getIntent().getBooleanExtra("EXIT", false)) {
finish(); // it doesn't work
}
}
#Override
public void onBackPressed() {
// do nothing!
}
}
MANIFEST:
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_name"
android:screenOrientation="landscape" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY"/>
</intent-filter>
</activity>
ADMINISTRATION DIALOG:
TEST1: // application is relaunched
Intent homeIntent= new Intent(Intent.ACTION_MAIN);
homeIntent.addCategory(Intent.CATEGORY_HOME);
homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(homeIntent);
TEST2: // application is relaunched
System.exit(0);
TEST3: // it open settings (o.O)
Intent h = new Intent(Intent.ACTION_MAIN);
h.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
h.putExtra("EXIT", true);
context.startActivity(h);
My problem is that i can't go out from application.. how can i solve?
In TEST3 you've only provided ACTION_MAIN in the Intent. Android looks for apps that can handle this action and finds a long list of them. How should it know that it should launch yours?
I assume you've set your app as a HOME-screen replacement. Try adding this to the code for TEST3:
h.addCategory(Intent.CATEGORY_HOME);
I added the intent-filter to ApplicationManifest.xml to take my app to "Share via" Dialog:
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
How can I handle the request from another app.
1 Is it possible to differentiate between directly app-start and sharing start?
2 How to get access to sharing data?
In onCreate you can call getIntent() to see if there is any data in the bundle. Use the getData() method to retrieve a Uri or one of the get...Extra methods to retrieve any other expected data.
void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.id.main);
...
Intent i = getIntent();
Uri data = i.getUri();
if(data != null) {
// do something interesting
}
/* or */
String text = i.getStringExtra(Intent.EXTRA_TEXT);
/ * do something interesting with the text */
}
regarding question 1: in direct app-start case, the intent action would not be SEND.
for question 2 see my comment.
My Android application uses Java OAuth library, found here for authorization on Twitter. I am able to get a request token, authorize the token and get an acknowlegement but when the browser tries the call back url to reconnect with my application, it does not use the URL I provide in code, but uses the one I supplied while registering with Twitter.
Note:
1. When registering my application with twitter, I provided a hypothetical call back url:http://abz.xyc.com and set the application type as browser.
2. I provided a callback url in my code "myapp" and have added an intent filter for my activity with Browsable category and data scheme as "myapp".
3. URL called when authorizing does contain te callback url, I specified in code.
Any idea what I am doing wrong here?
Relevant Code:
public class FirstActivity extends Activity
{
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
OAuthAccessor client = defaultClient();
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(client.consumer.serviceProvider.userAuthorizationURL + "?oauth_token="
+ client.requestToken + "&oauth_callback=" + client.consumer.callbackURL));
startActivity(i);
}
OAuthServiceProvider defaultProvider()
{
return new OAuthServiceProvider(GeneralRuntimeConstants.request_token_URL,
GeneralRuntimeConstants.authorize_url, GeneralRuntimeConstants.access_token_url);
}
OAuthAccessor defaultClient()
{
String callbackUrl = "myapp:///";
OAuthServiceProvider provider = defaultProvider();
OAuthConsumer consumer = new OAuthConsumer(callbackUrl,
GeneralRuntimeConstants.consumer_key, GeneralRuntimeConstants.consumer_secret,
provider);
OAuthAccessor accessor = new OAuthAccessor(consumer);
OAuthClient client = new OAuthClient(new HttpClient4());
try
{
client.getRequestToken(accessor);
} catch (Exception e)
{
e.printStackTrace();
}
return accessor;
}
#Override
protected void onResume()
{
// TODO Auto-generated method stub
super.onResume();
Uri uri = this.getIntent().getData();
if (uri != null)
{
String access_token = uri.getQueryParameter("oauth_token");
}
}
}
// Manifest file
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".FirstActivity"
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:scheme="myapp"/>
</intent-filter>
</activity>
</application>
Twitter does not honor callbacks requested in OAuth requests (Twitter API Announce) and will only redirect to the callback URL specified in the Application Settings (note that "localhost" is not allowed).
I assume you checked Oauth-callback-on-android question.
Android guesswork--
After a bit of reading up, I see Android browser redirects MyApp:/// to your application and I'm guessing Twitter doesn't like this bespoke URI prefix. I'm no android developer but one suggestion I might make is to get "www.myapp.com" on the web and have a re-redirect there.
So have your OAuth return to http://www.myapp.com/redirect.aspx?oauth_token=abc and have that page redirect to myapp:///oauth_token=... (the desired result)
In my case, i have this working:
String authURL = m_provider.retrieveRequestToken (m_consumer, CALLBACK_URL);
And in the Manifest:
<activity android:configChanges = "keyboardHidden|orientation" android:name = "xxxx.android.xxxxx">
<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="myapp" android:host="tweet" />
</intent-filter>
In this case the callback url will be: myapp://tweet
It looks to me like you're doing the correct thing and Twitter is screwing up by always accepting your registered callback URL. Is there any way to change the registered URL? Maybe you could re-register and try an Android callback next time, see what happens.
My problem was that I was trying to log in with the same account I made the Twitter app. After I logged in with my personal profile the call back works (so far).