Search in sources :

Example 1 with DeepLinkEntry

use of com.airbnb.deeplinkdispatch.DeepLinkEntry in project DeepLinkDispatch by airbnb.

the class DeepLinkDelegate method dispatchFrom.

public DeepLinkResult dispatchFrom(Activity activity, Intent sourceIntent) {
    if (activity == null) {
        throw new NullPointerException("activity == null");
    }
    if (sourceIntent == null) {
        throw new NullPointerException("sourceIntent == null");
    }
    Uri uri = sourceIntent.getData();
    if (uri == null) {
        return createResultAndNotify(activity, false, null, "No Uri in given activity's intent.");
    }
    String uriString = uri.toString();
    DeepLinkEntry entry = findEntry(uriString);
    if (entry != null) {
        DeepLinkUri deepLinkUri = DeepLinkUri.parse(uriString);
        Map<String, String> parameterMap = entry.getParameters(uriString);
        for (String queryParameter : deepLinkUri.queryParameterNames()) {
            for (String queryParameterValue : deepLinkUri.queryParameterValues(queryParameter)) {
                if (parameterMap.containsKey(queryParameter)) {
                    Log.w(TAG, "Duplicate parameter name in path and query param: " + queryParameter);
                }
                parameterMap.put(queryParameter, queryParameterValue);
            }
        }
        parameterMap.put(DeepLink.URI, uri.toString());
        Bundle parameters;
        if (sourceIntent.getExtras() != null) {
            parameters = new Bundle(sourceIntent.getExtras());
        } else {
            parameters = new Bundle();
        }
        for (Map.Entry<String, String> parameterEntry : parameterMap.entrySet()) {
            parameters.putString(parameterEntry.getKey(), parameterEntry.getValue());
        }
        try {
            Class<?> c = entry.getActivityClass();
            Intent newIntent;
            TaskStackBuilder taskStackBuilder = null;
            if (entry.getType() == DeepLinkEntry.Type.CLASS) {
                newIntent = new Intent(activity, c);
            } else {
                Method method;
                try {
                    method = c.getMethod(entry.getMethod(), Context.class);
                    if (method.getReturnType().equals(TaskStackBuilder.class)) {
                        taskStackBuilder = (TaskStackBuilder) method.invoke(c, activity);
                        if (taskStackBuilder.getIntentCount() == 0) {
                            return createResultAndNotify(activity, false, uri, "Could not deep link to method: " + entry.getMethod() + " intents length == 0");
                        }
                        newIntent = taskStackBuilder.editIntentAt(taskStackBuilder.getIntentCount() - 1);
                    } else {
                        newIntent = (Intent) method.invoke(c, activity);
                    }
                } catch (NoSuchMethodException exception) {
                    method = c.getMethod(entry.getMethod(), Context.class, Bundle.class);
                    if (method.getReturnType().equals(TaskStackBuilder.class)) {
                        taskStackBuilder = (TaskStackBuilder) method.invoke(c, activity, parameters);
                        if (taskStackBuilder.getIntentCount() == 0) {
                            return createResultAndNotify(activity, false, uri, "Could not deep link to method: " + entry.getMethod() + " intents length == 0");
                        }
                        newIntent = taskStackBuilder.editIntentAt(taskStackBuilder.getIntentCount() - 1);
                    } else {
                        newIntent = (Intent) method.invoke(c, activity, parameters);
                    }
                }
            }
            if (newIntent.getAction() == null) {
                newIntent.setAction(sourceIntent.getAction());
            }
            if (newIntent.getData() == null) {
                newIntent.setData(sourceIntent.getData());
            }
            newIntent.putExtras(parameters);
            newIntent.putExtra(DeepLink.IS_DEEP_LINK, true);
            newIntent.putExtra(DeepLink.REFERRER_URI, uri);
            if (activity.getCallingActivity() != null) {
                newIntent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
            }
            if (taskStackBuilder != null) {
                taskStackBuilder.startActivities();
            } else {
                activity.startActivity(newIntent);
            }
            return createResultAndNotify(activity, true, uri, null);
        } catch (NoSuchMethodException exception) {
            return createResultAndNotify(activity, false, uri, "Deep link to non-existent method: " + entry.getMethod());
        } catch (IllegalAccessException exception) {
            return createResultAndNotify(activity, false, uri, "Could not deep link to method: " + entry.getMethod());
        } catch (InvocationTargetException exception) {
            return createResultAndNotify(activity, false, uri, "Could not deep link to method: " + entry.getMethod());
        }
    } else {
        return createResultAndNotify(activity, false, uri, "No registered entity to handle deep link: " + uri.toString());
    }
}
Also used : Context(android.content.Context) DeepLinkUri(com.airbnb.deeplinkdispatch.DeepLinkUri) Bundle(android.os.Bundle) Intent(android.content.Intent) String(java.lang.String) Method(java.lang.reflect.Method) DeepLinkUri(com.airbnb.deeplinkdispatch.DeepLinkUri) Uri(android.net.Uri) InvocationTargetException(java.lang.reflect.InvocationTargetException) NoSuchMethodException(java.lang.NoSuchMethodException) NullPointerException(java.lang.NullPointerException) DeepLinkEntry(com.airbnb.deeplinkdispatch.DeepLinkEntry) TaskStackBuilder(android.support.v4.app.TaskStackBuilder) Map(java.util.Map)

Aggregations

Context (android.content.Context)1 Intent (android.content.Intent)1 Uri (android.net.Uri)1 Bundle (android.os.Bundle)1 TaskStackBuilder (android.support.v4.app.TaskStackBuilder)1 DeepLinkEntry (com.airbnb.deeplinkdispatch.DeepLinkEntry)1 DeepLinkUri (com.airbnb.deeplinkdispatch.DeepLinkUri)1 NoSuchMethodException (java.lang.NoSuchMethodException)1 NullPointerException (java.lang.NullPointerException)1 String (java.lang.String)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 Method (java.lang.reflect.Method)1 Map (java.util.Map)1