I have 2 activities - MainActivity and DeepLinkActivity. MainActivity generates a link. When I click on the DeepLink from an sms, I expect the DeepLinkActivity to open however the MainActivity always opens.
Manifest file is as follows:
<activity
android:name=".MainActivity"
android:theme="#style/Theme.AppCompat"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".DeepLinkActivity"
android:label="#string/app_name"
android:theme="#style/ThemeOverlay.MyDialogActivity">
<!-- [START deep_link_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="blessd.mobi" android:scheme="http"/>
<data android:host="blessd.mobi" android:scheme="https"/>
</intent-filter>
<!-- [END deep_link_filter] -->
</activity>
Snippet of both activities
MainActivity
public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_referral);
//long
String link = "http://www.blessd.mobi";
DynamicLink m = FirebaseDynamicLinks.getInstance().createDynamicLink()
.setLink(Uri.parse(link))....
DeepLinkActivity
public class DeepLinkActivity extends AppCompatActivity implements
View.OnClickListener {
private static final String TAG = DeepLinkActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.deep_link_activity);
Log.d(TAG,"Deep Activity" );
FirebaseDynamicLinks.getInstance()
.getDynamicLink(getIntent())
.addOnSuccessListener(this, new OnSuccessListener<PendingDynamicLinkData>() {
#Override
public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) {
// Get deep link from result (may be null if no link is found)
Uri deepLink = null;
if (pendingDynamicLinkData != null) {
deepLink = pendingDynamicLinkData.getLink();
}...
Thanks
In your manifest activity, you must have 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="yourlinkhost.com"
android:scheme="http" />
<data
android:host="yourlinkhost.com"
android:scheme="https" />
</intent-filter>
And it should handle your links. Maby your links have wrong host scheme - I had such problem when my link had wrong host. But the solution you have - seems good and the same I had worked well for me.
You must add the additional data on your intent filters.
<data
android:host=""
android:path=""
android:scheme="" />
And you must have set that data while you were creating share intent.
builder.scheme(getString(R.string.config_scheme)) // "http"
.authority("your url") // your host
.appendPath(getString(R.string.path)) // "your path"
.appendQueryParameter(QUERY_PARAM, data)
Related
How to manage the deeplink and applink in one Activity?
This is current AndroidManifest.xml setting.
<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="peterworks" android:host="open"/>
</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" android:host="peterworks.io"/>
</intent-filter>
</activity>
You can try using the following library to make the process easier: https://github.com/airbnb/DeepLinkDispatch
It provides an annotation-based approach to integrate deep links.
Example from its documentation:
#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
}
}
}
This is sample code that manage your deeplinkActivity with deeplink and Android Applink.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// onNewIntent Method will process every deeplink data.
onNewIntent(MainActivity.this.getIntent());
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
// setIntent should be called for get new deeplink data. If this is not called, always same deeplink will called
setIntent(intent);
// Deeplink data process start
Uri myDeeplink = intent.getData();
if (myDeeplink != null){
if(myDeeplink.getScheme().equals("https")) {
// Do your things when Android Applink is open your app.
} else {
// Do your things when Deeplink is open your app.
}
}
}
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.
I have an Activity, where under rare situation, its getIntent().getExtras() will return null.
public class NewNoteChecklistLauncherFragmentActivity extends AppCompatActivity {
private static final String NEW_NOTE_CHECKLIST_LAUNCHER_FRAGMENT = "NEW_NOTE_CHECKLIST_LAUNCHER_FRAGMENT";
private int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.mAppWidgetId = getIntent().getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
FragmentManager fm = getSupportFragmentManager();
NewNoteChecklistLauncherFragment newNoteChecklistLauncherFragment = (NewNoteChecklistLauncherFragment) fm.findFragmentByTag(NEW_NOTE_CHECKLIST_LAUNCHER_FRAGMENT);
if (newNoteChecklistLauncherFragment == null) {
Bundle bundle = this.getIntent().getExtras();
if (bundle == null) {
// WHY?
throw new java.lang.RuntimeException();
}
I'm not really sure how that happen. As, every-time, I'm launching the Activity with call to putExtra
Intent i = new Intent(context, NewNoteChecklistLauncherFragmentActivity.class);
Note note = new Note();
i.putExtra(NewNoteChecklistLauncherFragment.INTENT_EXTRA_NOTE, note);
At the same time, it also act as intent filter for "share" action.
<activity android:name="com.yocto.wenote.note.NewNoteChecklistLauncherFragmentActivity"
android:theme="#style/Theme.Transparent"
android:windowSoftInputMode="stateAlwaysHidden" >
<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" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</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>
I'm not able to produce such problem. But, once a while, I can see such thing happens in production.
Any idea, in what situation, getIntent().getExtras() will return null for the above case?
This could be a buggy ACTION_SEND implementation that failed to attach any extras. This could be some automated script — or script kiddie — manually invoking your activity without any extras.
Since the activity is exported, I recommend some "defensive programming". Do not assume the existence of an extras Bundle. Instead, "gracefully degrade" as best you can in that case.
<activity android:name=".XActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
android:noHistory="true"
android:launchMode="singleTask" >
<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="x.lv" />
<data android:scheme="http" android:host="www.x.lv" />
<data android:scheme="https" android:host="m.x.lv" />
</intent-filter>
</activity>
AND
public class XActivity extends Activity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent(); [Debugger break-point]
if (intent == null || intent.getData() == null) {
finish();
}
}
}
Well, I do get till the part when my application is start from deep-link if app is running in the background. If I close my app and then click on deep-link, then app opens but I dont hit onCreate method with debugger. Why is so? I thought it should work the same even if app is offline/turned off.
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.