I want to open my application on link click instead of the browser if the application is installed on the device , and open Google play otherwise.
so after searching .. This is my manifest
<activity
android:name="example.com.MyActivity"
android:label="#string/title_activity_open_event_details" >
<intent-filter>
<data
android:host="play.google.com"
android:scheme="http"/>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
and this is my activity
public class MyActivity extends Activity {
private int EventId;
private TextView tv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_open_event_details);
tv = (TextView) findViewById(R.id.testtv);
Uri data = getIntent().getData();
if ( data != null )
{
String scheme = data.getScheme();
String host = data.getHost();
List<String> params = data.getPathSegments();
String first = params.get(0);
String second = params.get(1);
int size = params.size();
// EventId = params.get(size-1);
String third = params.get(size-1);
tv.setText(data.toString());
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.my_activity, menu);
return true;
}
}
when I click on this link https://play.google.com/store/apps/details?id=example.com&evid=117
MyActivity opens successfully but the link that appears in the textview is only https://play.google.com/store/apps/details?id=example.com without &evid=117 which I need to get some data and display it in my activity
could you please help me to know what I am missing ?
Thanks in advance
To get that id try this code:
Uri data = getIntent().getData();
if (data != null) {
String url = data.toString();
try {
List<NameValuePair> params = URLEncodedUtils.parse(new URI(url), "UTF-8");
for (NameValuePair para : params)
if (para.getName().equals("evid")) {
String id = para.getValue(); //my id (117)
Log.v("myId",id);
}
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
Also you are not including the https protocol. Add
<data android:host="play.google.com" android:scheme="https"/>
EDIT
I've tested this code and it's working. I've created a simple activity with the code I provided above and for the intent filter:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<action android:name="android.intent.action.VIEW"/>
<data android:host="play.google.com" android:scheme="http"/>
<data android:host="play.google.com" android:scheme="https"/>
</intent-filter>
The output result is, as expected, 117
Related
I'm new on flutter and never used intent filter. so far I have everything working in my app. but I'm stuck in importing the file to app by open with dialog. I need the user when it click on the file it will go to the page and display the information in the file. I'm using ImportFile plugin and it work fine but it make it harder for the users to put the file they receive.
my app is list it in the open with dialog but when i click it, it just open the app I want it to open the app and view the text in the view text page not the homepage
AndroidManifest.xml
<
intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
<data android:pathPattern="*.*\\.txt" />
</intent-filter>
MainActivity.java
Intent intent = getIntent();
String action = intent.getAction();
String type = intent.getType();
if (Intent.ACTION_SEND.equals(action) && type != null) {
if ("text/plain".equals(type)) {
handleSendText(intent); // Handle text being sent
}
}
new MethodChannel(getFlutterView(), "app.channel.shared.data").setMethodCallHandler(new MethodChannel.MethodCallHandler() {
#Override
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
if (methodCall.method.contentEquals("getSharedText")) {
result.success(sharedText);
sharedText = null;
}
}
});
}
void handleSendText(Intent intent) {
sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
}
Thank you in advance
FlutterView has a setInitialRoute method you can use to specify a non-default route on launch.
Android deep linking is not working
===================================
Android link:-notification://id=notificationid
1:-In manifest
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="id"
android:scheme="notification" />
</intent-filter>
2:-and coding side
#Override
protected void onResume() {
super.onResume();
Intent intent = getIntent();
String string=intent.getAction();
Uri data = intent.getData();
Log.d("hello","cgbdsuyfdkv");
}
but its not working please any body can help me !!!!!
you can simply modify your url
Android link:-notification://id=notificationid instead of
Android link:-notification://page?id=notificationid //page is host name
I tried a lot and find out this is working for me.
manifest code
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="page"
android:scheme="notification" />
</intent-filter>
2.java code #get your notification id here
Intent intent = getIntent();
String string = intent.getAction();
Uri data = intent.getData();
if (data != null) {
String path = data.getPath();
String path1 = data.getPath();
providerUrl = intent.getData().toString();
UrlQuerySanitizer sanitizer = new UrlQuerySanitizer();
sanitizer.setAllowUnregisteredParamaters(true);
sanitizer.parseUrl(providerUrl);
String id = sanitizer.getValue("id");
if (id != null)
Log.d("notification id", id);
}
Add onNewIntent() method to your Activity and then use intent object which is variable in OnNewintent() method , which has updated method.
onNewIntent() is meant as entry point for singleTop or singleTask activities which already run somewhere else in the stack and therefore can't call onCreate(). From activities lifecycle point of view it's therefore needed to call onPause() before onNewIntent(). I suggest you to rewrite your activity to not use these listeners inside of onNewIntent(). For example most of the time my onNewIntent() methods simply looks like this:
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
//use this intent object to get notificationid for second time
}
1st step:
<intent-filter>
<data android:scheme="your_uri_scheme" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
2nd step:
Uri data = this.getIntent().getData();
if (data != null && data.isHierarchical()) {
String uri = this.getIntent().getDataString();
Log.i("MyApp", "Deep link clicked " + uri);
}
I think you Intent Filter is incomplete
<!-- To open app using link -->
<intent-filter>
<action android:name="android.intent.action.VIEW"></action>
<category android:name="android.intent.category.DEFAULT"></category>
<category android:name="android.intent.category.BROWSABLE"></category>
<data android:scheme="http"
android:host="yourdomain.com"
android:pathPrefix="/someurlparam">
</data>
</intent-filter>
I have supported deeplinks in my app
<activity android:name=".DeepLinkActivity" android:noHistory="true"></activity>
<activity-alias
android:name="com.example.Launcher"
android:targetActivity=".DeepLinkActivity">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<data android:scheme="http" />
<data android:scheme="#string/SCHEMA" />
<data android:host="#string/WEB_DOMAIN" />
<data android:host="#string/WWW_WEB_DOMAIN" />
<data android:path="/" />
<data android:path="/x" android:pathPattern="/x/.*" />
</intent-filter>
</activity-alias>
So whenever user clicks on www.example.com the android app asks to open as app or web that is fine, but I do not want when my users are on mobile site they should be asked to open in app. I have gone through many stackoverflow posts but everyone says its not possible but still many websites are handling this scenario.
As per this Article the behaviour depends on user gestures, if user is clicking on any link then Chrome displays a chooser while if user is typing url on browser then it doesn't.
After lot of research I have solved it. You can use either way.
Handle in mobile website : So if you want to render your user to Chrome always when they are on your msite you can achieve this by redirecting all your urls to
googlechrome://navigate?url=https://www.example.com
intent://www.example.com/x#Intent;scheme=https;package=com.android.chrome;S.browser_fallback_url=https://www/example.com/x;action=android.intent.action.VIEW;end;
Handle in app
Create single transparent activity to handle all your deeplinks
Handle all the links using pathpattern = '.*'
Redirect user back to Chrome for urls you do not want to handle in app.
AndroidManifest.xml
<activity
android:name=".DeepLinkActivity"
android:noHistory="true"
android:theme="#style/Theme.Transparent">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<data android:scheme="http" />
<data android:scheme="#string/SCHEMA" />
<data android:host="#string/WEB_DOMAIN" />
<data android:host="#string/WWW_WEB_DOMAIN" />
<data android:pathPattern="/.*" />
</intent-filter>
</activity>
DeepLinkActivity
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
try {
if (Intent.ACTION_VIEW.equals(getIntent().getAction())) {
Uri uri = getIntent().getData();
if (uri == null) throw new IllegalArgumentException("Uri can not be null");
Intent intent = null;
if (getString(R.string.SCHEMA).equals(uri.getScheme()) || uri.toString().matches(Links.REGEX)) {
intent = linkIntent(uri);
}
if (intent == null) SystemUtil.launchUrlInDefaultBrowser(uri, this); else startActivity(intent);
}
} catch (IllegalArgumentException e) {
Toast.makeText(this, R.string.can_not_open_url, Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(this, R.string.can_not_open_url, Toast.LENGTH_SHORT).show();
} finally {
finish();
}
}
/**
* This will open the provided url in browser except the current app.
* #param url Uri
* #param context Activity Context
*/
public static void launchUrlInDefaultBrowser(Uri url, Context context) {
try {
ResolveInfo packageInfo = null;
final Intent browserIntent = new Intent(Intent.ACTION_VIEW);
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
browserIntent.setData(url);
// Try to find anything that we can launch the URL with. Pick up the first one that can.
final List<ResolveInfo> resolveInfoList = context.getPackageManager().queryIntentActivities(browserIntent, PackageManager.MATCH_DEFAULT_ONLY);
if (!resolveInfoList.isEmpty()) {
for (ResolveInfo list : resolveInfoList) {
if (!BuildConfig.APP_PACKAGE_NAME.equals(list.activityInfo.packageName)) {
packageInfo = list;
break;
}
}
}
if (packageInfo != null) {
browserIntent.setClassName(packageInfo.activityInfo.packageName, packageInfo.activityInfo.name);
context.startActivity(browserIntent);
} else {
Toast.makeText(context, R.string.can_not_open_url, Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
Toast.makeText(context, R.string.can_not_open_url, Toast.LENGTH_SHORT).show();
}
}
Here is my activity structure: SplashActivity -> MainActivity. My MainActivity has a Spinner that is populated from ContentProvider. Based on Spinner selection, I present different content to the user. The content map perfectly to the content on my website. My website has long been indexed and is working fine. Now I want to index said content in my app.
Here is my manifest
<activity android:name=".activities.SplashActivity"
android:theme="#style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.MainActivity"/>
<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="www.business.com"
android:scheme="http"/>
<data
android:host="www.business.com"
android:scheme="https"/>
<data
android:host="business.com"
android:scheme="http"/>
<data
android:host="business.com"
android:scheme="https"/>
<data
android:host="/*"
android:scheme="business"/>
<data android:scheme="android-app"
android:host="com.business.android" />
</intent-filter>
</activity>
Here is the app-indexing portion of my MainActivity
#Override
public void onStart() {
super.onStart();
appIndexingTask();
}
private void appIndexingTask() {
new AsyncTask() {
#Override
protected Object doInBackground(Object[] params) {
try {
if(null == mNdxClient){
mNdxClient = new GoogleApiClient.Builder(MainActivity.this)
.enableAutoManage(MainActivity.this, MainActivity.this)
.addApi(AppInvite.API).addApi(AppIndex.API)
.build();
}
if(!mNdxClient.isConnected()){
mNdxClient.blockingConnect();
}
if (mNdxClient != null && mNdxClient.isConnected()) {
HashMap<Uri, Action> indexedActions = new HashMap<>();
List<Content> contentList = getAllFromContentProvider();
for(Content c: contentList){
Uri uri = Uri.parse(FirebaseUtils.appIndexingLink(c.getUrl()));
Action action = getAction(c.getName(), c.getDescription(), uri);
AppIndex.AppIndexApi.start(mNdxClient, action);
indexedActions.put(uri, action);
}
for (Action action : indexedActions.values()) {
AppIndex.AppIndexApi.end(mNdxClient, indexedActions.get(action));
}
}
} catch (Exception e) {
//abandon task
}
return null;
}
public Action getAction(String title, String description, Uri uri) {
Thing object = new Thing.Builder()
.setName(title)
.setDescription(description)
.setUrl(uri)
.build();
return new Action.Builder(Action.TYPE_VIEW)
.setObject(object)
.setActionStatus(Action.STATUS_TYPE_COMPLETED)
.build();
}
}.execute();
}
Here is the Utility method
public static String appIndexingLink(String urlString){
String appNdx= new StringBuilder("android-app://").append(BASE_URL).append(urlString).toString();
return appNdx;
}
Finally, in gradle I am using
classpath 'com.google.gms:google-services:3.0.0'//project level
//app level
compile 'com.google.android.gms:play-services-appindexing:9.0.0'
compile 'com.google.firebase:firebase-core:9.0.0'
compile "com.google.firebase:firebase-messaging:9.0.0"
compile "com.google.firebase:firebase-invites:9.0.0"
Some important points
App-Invite works: I can send an invite and then open the invite (code not shown)
Deep Linking works, if I send myself a link to my site, when I open the link on my android phone, it opens it with the app perfectly.
Google Search has not indexed my app
Fetch as Google fails with “URI unsupported” whether I point to Play Store or local apk.
Notice the filter
<data android:scheme="android-app"
android:host="com. business.android" />
I don’t see it anywhere in documentations. But nothing else works. So I added it. It’s still not working.
Although I am not showing logging. I am logging and so I know that the app-indexing code runs.
I have added my application to the share icon on top in the gallery, but so far it only opens my application, but how do I send the picture URI and stuff to my application? I understand I have to use intent? Are there any guides around I can look at? The easy-share-action guide on google website isn't helping me much here.
Try this way:
<activity
android:name="yourActivity"
android:icon="#drawable/ic_launcher"
android:label="test">
<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.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
</activity>
Handle the Incoming Content
void onCreate (Bundle savedInstanceState) {
...
// Get intent, action and MIME type
Intent intent = getIntent();
String action = intent.getAction();
String type = intent.getType();
if (Intent.ACTION_SEND.equals(action) && type != null) {
if ("text/plain".equals(type)) {
handleSendText(intent); // Handle text being sent
} else if (type.startsWith("image/")) {
handleSendImage(intent); // Handle single image being sent
}
} else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
if (type.startsWith("image/")) {
handleSendMultipleImages(intent); // Handle multiple images being sent
}
} else {
// Handle other intents, such as being started from the home screen
}
...
}
void handleSendText(Intent intent) {
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
if (sharedText != null) {
// Update UI to reflect text being shared
}
}
void handleSendImage(Intent intent) {
Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
if (imageUri != null) {
// Update UI to reflect image being shared
}
}
void handleSendMultipleImages(Intent intent) {
ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
if (imageUris != null) {
// Update UI to reflect multiple images being shared
}
}
For more information go to Receiving Simple Data from Other Apps and Sending Simple Data to Other Apps
To handle an image in your Activity you need to check if the intent has the image.
Intent intent = getIntent();
Bundle extras = intent.getExtras();
String action = intent.getAction();
if (Intent.ACTION_SEND.equals(action)) {
if (extras.containsKey(Intent.EXTRA_STREAM)) {
// Get resource path of the stream, which in this case will be the image
}
}
Furthermore you need to add to your manifest that you want to filter on these sharing image intents.
<activity android:name=".Theme"
android:label="YourImageActivity">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
</activity>