Search in sources :

Example 1 with DeepLinkUri

use of com.airbnb.deeplinkdispatch.DeepLinkUri 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)

Example 2 with DeepLinkUri

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

the class TypeConversionErrorHandlerCustomTypeDeepLinkActivity method onCreate.

@Override
protected void onCreate(Bundle savedInstanceState) {
    typeConverters = new TypeConverters();
    typeConverters.put(ComparableColorDrawable.class, value -> {
        switch(value.toLowerCase()) {
            case "red":
                return new ComparableColorDrawable(0xff0000ff);
            case "green":
                return new ComparableColorDrawable(0x00ff00ff);
            case "blue":
                return new ComparableColorDrawable(0x000ffff);
            default:
                return new ComparableColorDrawable(0xffffffff);
        }
    });
    try {
        // Not very elegant reflection way to get the right type to add to the mapper.
        typeConverters.put(TypeConversionErrorHandlerCustomTypeDeepLinkActivity.class.getDeclaredField("stringList").getGenericType(), value -> Arrays.asList(value.split(",")));
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    }
    Function3<DeepLinkUri, Type, ? super String, Integer> typeConversionErrorNullable = (Function3<DeepLinkUri, Type, String, Integer>) (uriTemplate, type, s) -> {
        Log.e(TAG, "Unable to convert " + s + " used in urlTemplate " + uriTemplate + " to a " + type + ". Returning null.");
        throw new NumberFormatException("For input string: \"" + s + "\"");
    };
    Function3<DeepLinkUri, Type, ? super String, Integer> typeConversionErrorNonNullable = (Function3<DeepLinkUri, Type, String, Integer>) (uriTemplate, type, s) -> {
        Log.e(TAG, "Unable to convert " + s + " used in urlTemplate " + uriTemplate + " to a " + type + ". Returning 0.");
        throw new NumberFormatException("For input string: \"" + s + "\"");
    };
    Function0<TypeConverters> typeConvertersLambda = () -> typeConverters;
    super.onCreate(savedInstanceState);
    Map configurablePlaceholdersMap = new HashMap();
    configurablePlaceholdersMap.put("configPathOne", "somePathThree");
    configurablePlaceholdersMap.put("configurable-path-segment-one", "");
    configurablePlaceholdersMap.put("configurable-path-segment", "");
    configurablePlaceholdersMap.put("configurable-path-segment-two", "");
    configurablePlaceholdersMap.put("configPathOne", "somePathOne");
    DeepLinkDelegate deepLinkDelegate = new DeepLinkDelegate(new SampleModuleRegistry(), new LibraryDeepLinkModuleRegistry(), new BenchmarkDeepLinkModuleRegistry(), new KaptLibraryDeepLinkModuleRegistry(), configurablePlaceholdersMap, typeConvertersLambda, typeConversionErrorNullable, typeConversionErrorNonNullable);
    deepLinkDelegate.dispatchFrom(this);
    finish();
}
Also used : SampleModuleRegistry(com.airbnb.deeplinkdispatch.sample.SampleModuleRegistry) DeepLinkUri(com.airbnb.deeplinkdispatch.DeepLinkUri) HashMap(java.util.HashMap) Function3(kotlin.jvm.functions.Function3) BenchmarkDeepLinkModuleRegistry(com.airbnb.deeplinkdispatch.sample.benchmarkable.BenchmarkDeepLinkModuleRegistry) TypeConverters(com.airbnb.deeplinkdispatch.handler.TypeConverters) Type(java.lang.reflect.Type) KaptLibraryDeepLinkModuleRegistry(com.airbnb.deeplinkdispatch.sample.kaptlibrary.KaptLibraryDeepLinkModuleRegistry) KaptLibraryDeepLinkModuleRegistry(com.airbnb.deeplinkdispatch.sample.kaptlibrary.KaptLibraryDeepLinkModuleRegistry) LibraryDeepLinkModuleRegistry(com.airbnb.deeplinkdispatch.sample.library.LibraryDeepLinkModuleRegistry) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

DeepLinkUri (com.airbnb.deeplinkdispatch.DeepLinkUri)2 Map (java.util.Map)2 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 TypeConverters (com.airbnb.deeplinkdispatch.handler.TypeConverters)1 SampleModuleRegistry (com.airbnb.deeplinkdispatch.sample.SampleModuleRegistry)1 BenchmarkDeepLinkModuleRegistry (com.airbnb.deeplinkdispatch.sample.benchmarkable.BenchmarkDeepLinkModuleRegistry)1 KaptLibraryDeepLinkModuleRegistry (com.airbnb.deeplinkdispatch.sample.kaptlibrary.KaptLibraryDeepLinkModuleRegistry)1 LibraryDeepLinkModuleRegistry (com.airbnb.deeplinkdispatch.sample.library.LibraryDeepLinkModuleRegistry)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 Type (java.lang.reflect.Type)1 HashMap (java.util.HashMap)1