how to share links with my app? - android

how do i open links in my webview shared by other apps?
I have tried this but it doesn't list my app anywhere-
TextView uri = (TextView) findViewById(R.id.urlField);
//if (Intent.ACTION_MAIN.equals(getIntent().getAction())) {
String intentUri = (new Intent("com.example.browsableintent.MY_ACTION"))
.toUri(Intent.URI_INTENT_SCHEME).toString();
uri.setText(intentUri);
Log.w("URLHandler", intentUri);
//} else {
Uri data = getIntent().getData();
if (data == null) {
uri.setText(" ");
} else {
uri.setText(getIntent().getData().toString());
}
//}
// Load URL from Browsable intent filter if there is a valid URL pasted
if (uri.length() > 0)
webView.loadUrl(url);
else
// dont load
manifest
<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" />
<data android:scheme="http" />
<data android:scheme="https" />
</intent-filter>

To allow other apps to start your activity, you need to add an <intent-filter> element in your manifest file for the corresponding <activity> element.
<intent-filter > ... </intent-filter>
intent filter defines the Intents that your activity "listens for" in order to launch.
<action android:name="ndroid.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT"/>
Action and category are both fields that get set on an Intent before it is "fired off" into the system. The system will then look for any activities that match both the action and category and if it finds one then it will launch that activity, or if it finds multiple it will show the user all of them and let them pick.
When your app is installed on a device, the system identifies your intent filters and adds the information to an internal catalog of intents supported by all installed apps. When an app calls startActivity() or startActivityForResult(), with an implicit intent, the system finds which activity (or activities) can respond to the intent.
Inside your Activity to the following
#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 ...
}
}
If you want to return a result to the activity that invoked yours, simply call setResult() to specify the result code and result Intent. When your operation is done and the user should return to the original activity, call finish() to close (and destroy) your activity. For example:
// Create intent to deliver some kind of result data
Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri"));
setResult(Activity.RESULT_OK, result);
finish();
To read more on how to implements click here

how do i open links in my webview shared by other apps? I want my app to be here in this list
I have tried this but it doesn't list my app anywhere-
TextView uri = (TextView) findViewById(R.id.urlField);
// Get the intent that started this activity
Intent intent = getIntent();
String link = intent.getDataString();
uri.seText(link);

Taken from Chromium AndroidManifest.xml : https://cs.chromium.org/chromium/src/chrome/android/java/AndroidManifest.xml?q=AndroidManife&sq=package:chromium&l=1
<!-- Matches the common case of intents with no MIME type.-->
<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="http" />
<data android:scheme="https" />
</intent-filter>
<!-- Same filter as above but with MIME types.-->
<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="http" />
<data android:scheme="https" />
<data android:mimeType="text/html"/>
</intent-filter>
Then from other apps it's enought to use:
String url = "http://www.example.com";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
and Android will list you in Select App dialog.
Complete example for client app:
In AndroidManifest.xml :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.j2ko.myapplication">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity"
android:launchMode="singleTask">
<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="https"/>
<data android:scheme="http"/>
</intent-filter>
</activity>
</application>
</manifest>
In activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.j2ko.myapplication.MainActivity">
<WebView
android:id="#+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</WebView>
</RelativeLayout>
In Main Activity:
package com.j2ko.myapplication;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.webkit.WebView;
public class MainActivity extends AppCompatActivity {
private WebView mWebView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWebView = (WebView) findViewById(R.id.webView);
final Intent intent = getIntent();
if (intent != null) {
handleIntent(intent);
}
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
handleIntent(intent);
}
private void handleIntent(final Intent intent) {
if (intent.getAction() == Intent.ACTION_VIEW) {
final String url = intent.getDataString();
mWebView.loadUrl(url);
}
}
}

Related

How to get intent content in receiving app when launched with getLaunchIntentForPackage()?

I have an intent filter for receiving intents with a specific URI. When another app opens my app with that specific URI, I use that deeplink/unilink, and redirect in the app using a Flutter plugin, depending on which query parameters are included in the URI.
In AndroidManifest:
<activity android:name=".MainActivity" android:theme="#style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize" android:screenOrientation="portrait">
<meta-data android:name="io.flutter.embedding.android.SplashScreenDrawable" android:resource="#drawable/launch_background" />
<meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="#style/NormalTheme"/>
<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="appspecifictheme" />
</intent-filter>
<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"
android:host="www.myappslandingpage.com"
android:pathPrefix="/myappspath" />
<data
android:scheme="https"
android:host="www.myappslandingpage.com"
android:pathPrefix="/myspecificpathprefix" />
</intent-filter>
</activity>
This is working fine when launching from another app with uri https://www.myappslandingpage.com/myspecificpathprefix/?param1=xxxx&param2=xxxx&param3=xxxx
Now to my issue: another app wants to launch my app using this intent from package manager, and passing the query parameters as extras instead:
Intent launchIntent = getPackageManager().getLaunchIntentForPackage("receiving.apps.package.name");
launchIntent.putExtra("param1", "xxxx");
launchIntent.putExtra("param2", "xxxx");
launchIntent.putExtra("param3", "xxxx");
startActivity(launchIntent);
Question 1: When I launch my app from another app using above code, and the app is opened, but how do I get the content from the intent? I have tried using getIntent() in my MainActivity's onCreate(), but it doesn't seem to be working (stringExtras and other data in the intent is null).
#Override
protected void onCreate(Bundle savedInstanceState) {
checkIntent(getIntent());
FlutterMain.startInitialization(this);
super.onCreate(savedInstanceState);
}
void checkIntent(Intent i) {
final String param1 = i.getStringExtra("param1");
final String param2 = i.getStringExtra("param2");
final String param3 = i.getStringExtra("param3");
final Bundle extras = i.getExtras();
if(extras != null) {
for (String key : extras.keySet()) {
L.d(TAG, "checkIntent() extra: " + key + " : " + (extras.get(key) !=
null ? extras.get(key) : "NULL"));
//Above logs nothing - there are no keys in extras.
}
}
if(param1 != null) {
//Do something
} else {
L.d(TAG,"checkIntent(): param1 is null");
}
}
I have also tried adding URI to the intent using launchIntent.setData("uri") before running startActivity() from the other app, and changing the intent filter in my receiving app as below, but getIntent().getData() in MainActivity also returns null.
<category android:name="android.intent.category.LAUNCHER" />
Question 2: If I find a way to receive the intent and get the stringExtras, is there a simple way to "transform" that intent so that it is interpreted the same way as if the app was opened with a deeplink?

How to make my app appear in share board of other apps - example whatsApp

I am trying to read the text file of chat that exported from WhatsApp to my android app.
When I am trying to export the chat text file to my app, it does not appear in the share board of WhatsApp, although I have added the following to the manifest.xml:
<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.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
Also, here is the Java Code:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
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 {
// 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) {
Log.d(TAG, sharedText);
// Update UI to reflect text being shared
}
}}
I went through many explanations, but I could not figure out what is the problem. Thank you.
Have you added the intent-filter under the correct activity in AndroidManifest.xml?
This should work in theory, but some apps might not send the proper intent for your app. It is possible that WhatsApp is using "VIEW" instead of "SEND", so try with this:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:mimeType="text/plain" />
</intent-filter>
Let me know if it works for you.

How to create two entry points to application using deeplink?

I want to create an application which will have two entry points.
The first will be a regular entry when the user clicks the app icon.
The second one will be through a deeplink which will be sent through push notifications.
I used this tutorial to build the deeplink.
I tried to use the deeplink to open the second entry point using adb, however I keep getting
Activity not started, unable to resolve Intent.
Here is my manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.edwardkeselman.siemens">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".Login">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ReportActivity" />
<activity android:name=".DetailsActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Accepts URIs that begin with "example://gizmos” -->
<data android:scheme="example"
android:host="gizmos" />
</intent-filter>
</activity>
</application>
</manifest>
Here is my DetailsActivity:
public class DetailsActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Intent intent = getIntent();
String action = intent.getAction();
Uri data = intent.getData();
}
}
This is the adb command that I use to try to open the DetailsActivity:
adb shell am start -W -a android.intent.action.BROWSE -d "example://gizmoz" com.example.myname
Help will be much appreciated.
manifest.xml
<activity android:name=".DeepLinking">
<intent-filter android:label="#string/filter_deeplinking">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Accepts URIs that begin with "http://www.example.com/gizmos” -->
<data
android:host="domain.in"
android:scheme="http" />
<!-- note that the leading "/" is required for pathPrefix -->
<!-- Accepts URIs that begin with "example://gizmos” -->
<data android:scheme="example"
android:host="gizmos" />
</intent-filter>
</activity>
DeepLinking.java
import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.net.URLDecoder;
public class DeepLinking extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_deep_linking);
Intent intent = getIntent();
String action = intent.getAction();
Uri uri_data = intent.getData();
String data=uri_data.toString();
Log.d("DATA : ",""+uri_data.toString());
if(data.equals("domain.in") || data.equals("http://domain.in") )
{
Intent i = new Intent(getApplicationContext(), Splash.class);
startActivity(i);
finish();
}
else if (!data.equals(null))
{
Intent i = new Intent(getApplicationContext(), DetailActivity.class);
startActivity(i);
finish();
}
else
{
Intent i = new Intent(getApplicationContext(), Splash.class);
startActivity(i);
finish();
}
}
}

Why isn't my app on the list of apps to open txt file?

I have an text reader app that is designed to receive intent from Android system when I click on a text file to open it. But my app isn't on the list popped up by the system. Below are my codes:
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.broadcastreceivertest1"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:label="#string/app_name"
android:name=".BroadcastReceiverTest1Activity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.ACTION_VIEW" />
<action android:name="android.intent.action.ACTION_EDIT" />
<action android:name="android.intent.action.ACTION_PICK" />
<data android:scheme="file" />
<data android:mimeType="*/*" />
<data android:pathPattern=".*\\.txt" />
<data android:host="*" />
</intent-filter>
</receiver>
</application>
</manifest>
My extended BroadcastReceiver
public final class MyBroadcastReceiver extends BroadcastReceiver {
private String TAG = "MyBroadcastReceiver";
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Intent i = new Intent(context, BroadcastReceiverTest1Activity.class);
i.putExtra("URI", intent.getData());
context.startActivity(i);
Log.d(TAG, "Leaving onReceived...");
}
}
My activity to be opened by the broadcast receiver
public class BroadcastReceiverTest1Activity extends Activity {
private String uri ="";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final Intent intent = getIntent();
final String action = intent.getAction();
if(Intent.ACTION_VIEW.equals(action)){
uri = intent.getStringExtra("URI");
TextView textView = (TextView)findViewById(R.id.textView);
textView.setText(uri);
}
}
}
Thanks!
You need to associate your app with file extension. To do so, add these two line within intent filter and u'r good to go
<data android:scheme="file" />
<data android:mimeType="*/*"/>
<data android:pathPattern=".*\\.pdf" />
And your manifest would be look like this
<activity name="com.your.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="file" />
<data android:mimeType="*/*" />
<data android:pathPattern=".*\\.txt" />
</intent-filter>
</activity>
<data android:scheme="file" /> => this define that the file must be local, not from http or else
<data android:mimeType="*/*" /> => match any mime type
<data android:pathPattern=".*\\.txt" /> => this is where you specify what extension you want to match
Hope this help
elaborating on HERO's pseudo code, this effectively works:
change the <manifest> like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.broadcastreceivertest1"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="9" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:label="#string/app_name"
android:name=".BroadcastReceiverTest1Activity" >
<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="file" />
<data android:mimeType="*/*" />
<data android:pathPattern=".*\\.txt" />
</intent-filter>
</activity>
</application>
</manifest>
drop your broadcast receiver, because it is unnecessary.
change your BroadcastReceiverTest1Activity class (it does NOT need to be your MAIN activity, see BONUS below):
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class BroadcastReceiverTest1Activity extends Activity {
private String TAG = "TagOpenTxt";
private String uri ="";
private Uri uri2;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Intent intent = getIntent();
final String action = intent.getAction();
if(Intent.ACTION_VIEW.equals(action)){
//uri = intent.getStringExtra("URI");
uri2 = intent.getData();
uri = uri2.getEncodedPath() + " complete: " + uri2.toString();
TextView textView = (TextView)findViewById(R.id.textView);
textView.setText(uri);
// now you call whatever function your app uses
// to consume the txt file whose location you now know
} else {
Log.d(TAG, "intent was something else: "+action);
}
}
}
you have effectively created an intent listener for TXT files, which will call your app IF the user decides to use it (unless the user has previously associated file type TXT to another app...)
your app does NOT need to be active to catch intents. once installed, the system recognizes it as one of the "goto apps" for the particular mime types and/or extensions (less easy than associating by mime type) you chose.
BONUS: you can have a separate MAIN activity and when your BroadcastReceiver is called, it will execute within the same sandbox as your application, without impacting it (you will have to implement that in your MAIN activity's onResume method).
you can read the text data into static variable(s) [sloppy] OR you can place it in a SQLite db, which is permanent AND safe, regardless of app and/or phone shutting down, for example.
you could have the activity selfterminating and never even firing up a layout/window - which is sort of weird in case your user wants some kind of confirmation that the txt file was correctly and completely consumed by app.
You have to register an ACTIVITY not a broadcast receiver with the filter attributes.

Browsable intent filter does not open my application

I am trying to use intent filter to open URLs in my application (as opening http://market.android.com/ opens the Android Market).
According to docs I've found, with this code, opening http://seenthis.net/people/progval in the browser should open my application:
<activity android:name=".ShowUserActivity" android:permission="android.permission.INTERNET">
<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="http"
android:host="seenthis.net"
android:pathPattern="/people/.*" />
</intent-filter>
</activity>
But it does not.
Here is the activity:
public class ShowUserActivity extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("SeenDroid", "called");
String url = getIntent().getDataString();
if (url != null) {
Log.d("SeenDroid", url);
}
// ...
}
// ...
}
But nothing is logged to the logcat.
Regards,
ProgVal
You need to remove android:permission="android.permission.INTERNET" from your activity declaration.

Categories

Resources