;
35 | }
36 |
37 | # The name of @JsonClass types is used to look up the generated adapter.
38 | -keepnames @com.squareup.moshi.JsonClass class *
39 |
--------------------------------------------------------------------------------
/connect-button/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/connect-button/src/main/java/com/ifttt/connect/analytics/tape/Private.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.analytics.tape;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Indicates that the given field or method has package visibility solely to prevent the creation of
10 | * a synthetic method. In practice, you should treat this field/method as if it were private.
11 | *
12 | * When a private method is called from an inner class, the Java compiler generates a simple package
13 | * private shim method that the class generated from the inner class can call. This results in
14 | * unnecessary bloat and runtime method call overhead. It also gets us closer to the dex method
15 | * count limit.
16 | *
17 | * If you'd like to see warnings for these synthetic methods in IntelliJ, turn on the inspections
18 | * "Private method only used from inner class" and "Private member access between outer and inner
19 | * classes".
20 | */
21 | @Retention(RetentionPolicy.SOURCE)
22 | @Target({ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.TYPE})
23 | @interface Private {
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/connect-button/src/main/java/com/ifttt/connect/ui/AbsActivityLifecycleCallbacks.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.ui;
2 |
3 | import android.app.Activity;
4 | import android.app.Application;
5 | import android.os.Bundle;
6 |
7 | /**
8 | * Convenient abstract class for using {@link Application.ActivityLifecycleCallbacks}.
9 | */
10 | abstract class AbsActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
11 | @Override
12 | public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
13 | }
14 |
15 | @Override
16 | public void onActivityStarted(Activity activity) {
17 | }
18 |
19 | @Override
20 | public void onActivityResumed(Activity activity) {
21 | }
22 |
23 | @Override
24 | public void onActivityPaused(Activity activity) {
25 | }
26 |
27 | @Override
28 | public void onActivityStopped(Activity activity) {
29 | }
30 |
31 | @Override
32 | public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
33 | }
34 |
35 | @Override
36 | public void onActivityDestroyed(Activity activity) {
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/connect-button/src/main/java/com/ifttt/connect/ui/AccountApi.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.ui;
2 |
3 | import retrofit2.Call;
4 | import retrofit2.http.GET;
5 | import retrofit2.http.Query;
6 |
7 | /**
8 | * API used for trying to match an existing IFTTT account with an email.
9 | */
10 | interface AccountApi {
11 | @GET("/v2/account/find")
12 | Call findAccount(@Query("email") String email);
13 | }
14 |
--------------------------------------------------------------------------------
/connect-button/src/main/java/com/ifttt/connect/ui/AnalyticsApiHelper.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.ui;
2 |
3 | import com.ifttt.connect.api.SdkInfoInterceptor;
4 | import okhttp3.OkHttpClient;
5 | import retrofit2.Call;
6 | import retrofit2.Retrofit;
7 | import retrofit2.converter.moshi.MoshiConverterFactory;
8 | import retrofit2.http.Body;
9 | import retrofit2.http.POST;
10 |
11 | final class AnalyticsApiHelper {
12 |
13 | private static AnalyticsApiHelper INSTANCE;
14 |
15 | private final EventsApi eventsApi;
16 |
17 | private AnalyticsApiHelper(String anonymousId) {
18 | OkHttpClient.Builder builder = new OkHttpClient.Builder();
19 | OkHttpClient okHttpClient = builder.addInterceptor(new SdkInfoInterceptor(anonymousId)).build();
20 |
21 | Retrofit retrofit = new Retrofit.Builder().baseUrl("https://connect.ifttt.com")
22 | .addConverterFactory(MoshiConverterFactory.create())
23 | .client(okHttpClient)
24 | .build();
25 |
26 | eventsApi = retrofit.create(EventsApi.class);
27 | }
28 |
29 | static synchronized AnalyticsApiHelper get(String anonymousId) {
30 | if (INSTANCE == null) {
31 | INSTANCE = new AnalyticsApiHelper(anonymousId);
32 | }
33 | return INSTANCE;
34 | }
35 |
36 | Call submitEvents(EventsList events) {
37 | return eventsApi.postEvents(events);
38 | }
39 |
40 | private interface EventsApi {
41 | @POST("/v2/sdk/events")
42 | Call postEvents(@Body EventsList events);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/connect-button/src/main/java/com/ifttt/connect/ui/AnalyticsEventPayload.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.ui;
2 |
3 | import java.util.Map;
4 |
5 | final class AnalyticsEventPayload {
6 |
7 | private final String name;
8 |
9 | private final String timestamp;
10 | private final Map properties;
11 |
12 | AnalyticsEventPayload(String name, String timestamp, Map properties) {
13 | this.name = name;
14 | this.timestamp = timestamp;
15 | this.properties = properties;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/connect-button/src/main/java/com/ifttt/connect/ui/AnalyticsEventUploader.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.ui;
2 |
3 | import android.content.Context;
4 | import androidx.annotation.NonNull;
5 | import androidx.work.Worker;
6 | import androidx.work.WorkerParameters;
7 | import com.ifttt.connect.api.AnonymousId;
8 | import java.io.IOException;
9 | import java.util.List;
10 | import retrofit2.Response;
11 |
12 | /*
13 | * Schedules a one time work request to read from the queue, make an api call to submit events and remove them from queue.
14 | * */
15 | public final class AnalyticsEventUploader extends Worker {
16 |
17 | private final AnalyticsManager analyticsManager;
18 | private final AnalyticsApiHelper apiHelper;
19 |
20 | private static final int MAX_RETRY_COUNT = 3;
21 |
22 | public AnalyticsEventUploader(Context context, WorkerParameters params) {
23 | super(context, params);
24 | analyticsManager = AnalyticsManager.getInstance(context.getApplicationContext());
25 | apiHelper = AnalyticsApiHelper.get(AnonymousId.get(context));
26 | }
27 |
28 | @Override
29 | @NonNull
30 | public Result doWork() {
31 | try {
32 | List list = analyticsManager.performRead();
33 |
34 | if (list != null && !list.isEmpty()) {
35 | Response response = apiHelper
36 | .submitEvents(new EventsList(list))
37 | .execute();
38 |
39 | if (response.isSuccessful()) {
40 | analyticsManager.performRemove(list.size());
41 | return Result.success();
42 | }
43 | } else {
44 | return Result.success();
45 | }
46 | } catch (IOException e) {
47 | }
48 |
49 | if (getRunAttemptCount() < MAX_RETRY_COUNT) {
50 | return Result.retry();
51 | } else {
52 | return Result.failure();
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/connect-button/src/main/java/com/ifttt/connect/ui/AnalyticsLocation.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.ui;
2 |
3 | import android.content.Context;
4 | import androidx.annotation.VisibleForTesting;
5 |
6 | final class AnalyticsLocation {
7 |
8 | final String id;
9 | final String type;
10 |
11 | private static final String TYPE_CONNECT_BUTTON = "connect_button";
12 |
13 | static final AnalyticsLocation WORKS_WITH_IFTTT = new AnalyticsLocation("", TYPE_CONNECT_BUTTON);
14 |
15 | @VisibleForTesting
16 | AnalyticsLocation(String id, String type) {
17 | this.id = id;
18 | this.type = type;
19 | }
20 |
21 | static AnalyticsLocation fromConnectButton(Context context) {
22 | return new AnalyticsLocation(context.getPackageName(),TYPE_CONNECT_BUTTON);
23 | }
24 |
25 | static AnalyticsLocation fromConnectButtonWithId(String connectionId) {
26 | return new AnalyticsLocation(connectionId, TYPE_CONNECT_BUTTON);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/connect-button/src/main/java/com/ifttt/connect/ui/AnalyticsObject.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.ui;
2 |
3 | import androidx.annotation.VisibleForTesting;
4 | import com.ifttt.connect.api.Connection;
5 |
6 | class AnalyticsObject {
7 |
8 | final String id;
9 | final String type;
10 |
11 | private static String TYPE_CONNECTION = "connection";
12 | private static String TYPE_BUTTON = "button";
13 | private static String TYPE_MODAL = "modal";
14 |
15 | private static String ID_WORKS_WITH_IFTTT = "works_with_ifttt";
16 | private static String ID_CONNECT_INFORMATION = "connect_information";
17 | private static String ID_PRIVACY_POLICY = "privacy_policy";
18 | private static String ID_MANAGE = "manage";
19 | private static String ID_CONNECTION_NAME = "connection_name";
20 |
21 | static final AnalyticsObject WORKS_WITH_IFTTT = new AnalyticsObject(ID_WORKS_WITH_IFTTT, TYPE_BUTTON);
22 | static final AnalyticsObject CONNECT_INFORMATION_MODAL = new AnalyticsObject(ID_CONNECT_INFORMATION, TYPE_MODAL);
23 | static final AnalyticsObject PRIVACY_POLICY = new AnalyticsObject(ID_PRIVACY_POLICY, TYPE_BUTTON);
24 | static final AnalyticsObject MANAGE_CONNECTION = new AnalyticsObject(ID_MANAGE, TYPE_BUTTON);
25 | static final AnalyticsObject CONNECTION_NAME = new AnalyticsObject(ID_CONNECTION_NAME, TYPE_BUTTON);
26 |
27 | @VisibleForTesting
28 | AnalyticsObject(String id, String type) {
29 | this.id = id;
30 | this.type = type;
31 | }
32 |
33 | static final class ConnectionAnalyticsObject extends AnalyticsObject {
34 | String status;
35 |
36 | ConnectionAnalyticsObject(String id, String status) {
37 | super(id, TYPE_CONNECTION);
38 | this.status = status;
39 | }
40 |
41 | static ConnectionAnalyticsObject fromConnection(Connection connection) {
42 | return new ConnectionAnalyticsObject(connection.id, connection.status.toString());
43 | }
44 | }
45 |
46 | static AnalyticsObject fromService(String serviceModuleName) {
47 | return new AnalyticsObject(serviceModuleName.concat("_").concat("service_icon"), TYPE_BUTTON);
48 | }
49 |
50 | static AnalyticsObject fromConnectionEmail(String connectionId) {
51 | return new AnalyticsObject(connectionId, "connection_email");
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/connect-button/src/main/java/com/ifttt/connect/ui/AvenirTypefaceSpan.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.ui;
2 |
3 | import android.graphics.Paint;
4 | import android.graphics.Typeface;
5 | import android.text.TextPaint;
6 | import android.text.style.TypefaceSpan;
7 |
8 | final class AvenirTypefaceSpan extends TypefaceSpan {
9 |
10 | private final Typeface newType;
11 |
12 | AvenirTypefaceSpan(Typeface type) {
13 | super("san-serif");
14 | newType = type;
15 | }
16 |
17 | @Override
18 | public void updateDrawState(TextPaint ds) {
19 | applyCustomTypeFace(ds, newType);
20 | }
21 |
22 | @Override
23 | public void updateMeasureState(TextPaint paint) {
24 | applyCustomTypeFace(paint, newType);
25 | }
26 |
27 | private void applyCustomTypeFace(Paint paint, Typeface tf) {
28 | int oldStyle;
29 | Typeface old = paint.getTypeface();
30 | if (old == null) {
31 | oldStyle = 0;
32 | } else {
33 | oldStyle = old.getStyle();
34 | }
35 | int fake = oldStyle & ~tf.getStyle();
36 | if ((fake & Typeface.BOLD) != 0) {
37 | paint.setFakeBoldText(true);
38 | }
39 | if ((fake & Typeface.ITALIC) != 0) {
40 | paint.setTextSkewX(-0.25f);
41 | }
42 | paint.setTypeface(tf);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/connect-button/src/main/java/com/ifttt/connect/ui/ButtonStateChangeListener.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.ui;
2 |
3 | import com.ifttt.connect.api.Connection;
4 | import com.ifttt.connect.api.ErrorResponse;
5 |
6 | /**
7 | * Callback interface for listening to state changes of the {@link BaseConnectButton}.
8 | */
9 | public interface ButtonStateChangeListener {
10 | /**
11 | * Called when there is a state change, either successful or failed, on the IftttConnectButton.
12 | *
13 | * @param currentState Current state of the button.
14 | * @param previousState Previous state of the button.
15 | * @param connection Connection instance.
16 | * If currentState = Enabled, this param will reflect the refreshed Connection instance with updated feature fields.
17 | */
18 | void onStateChanged(ConnectButtonState currentState, ConnectButtonState previousState, Connection connection);
19 |
20 | /**
21 | * Called when the button state change encounters an errorResponse.
22 | *
23 | * @param errorResponse ErrorResponse messages from the button or underlying API calls, or null for a successful state
24 | * change.
25 | */
26 | void onError(ErrorResponse errorResponse);
27 | }
28 |
--------------------------------------------------------------------------------
/connect-button/src/main/java/com/ifttt/connect/ui/ConnectButtonState.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.ui;
2 |
3 | public enum ConnectButtonState {
4 | /**
5 | * A button state for displaying an Connection in its initial state, the user has never authenticated this Connection
6 | * before.
7 | */
8 | Initial,
9 |
10 | /**
11 | * A button state for the create account authentication step. In this step, the user is going to be redirected
12 | * to web to create an account and continue with service connection.
13 | */
14 | CreateAccount,
15 |
16 | /**
17 | * A button state for the login authentication step. In this step, the user is going to be redirected to web
18 | * to login to IFTTT.
19 | */
20 | Login,
21 |
22 | /**
23 | * A button state for displaying a Connection that is enabled.
24 | */
25 | Enabled,
26 |
27 | /**
28 | * A button stat for displaying a Connection that is disabled.
29 | */
30 | Disabled,
31 |
32 | /**
33 | * Default button state.
34 | */
35 | Unknown
36 | }
37 |
--------------------------------------------------------------------------------
/connect-button/src/main/java/com/ifttt/connect/ui/CredentialsProvider.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.ui;
2 |
3 | import androidx.annotation.WorkerThread;
4 | import com.ifttt.connect.api.Connection;
5 | import com.ifttt.connect.api.UserTokenProvider;
6 |
7 | /**
8 | * Interface that defines APIs for providing credentials used during the service authentication process for a
9 | * {@link Connection}.
10 | */
11 | public interface CredentialsProvider extends UserTokenProvider {
12 |
13 | /**
14 | * @return Your users' OAuth code for your service. This is to be used to automatically authenticate the
15 | * user to your service on IFTTT during the connection enable flow.
16 | */
17 | @WorkerThread
18 | String getOAuthCode();
19 | }
20 |
--------------------------------------------------------------------------------
/connect-button/src/main/java/com/ifttt/connect/ui/EmailAppsChecker.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.ui;
2 |
3 | import android.content.pm.PackageManager;
4 | import java.util.ArrayList;
5 | import java.util.Collections;
6 | import java.util.List;
7 | import javax.annotation.CheckReturnValue;
8 |
9 | /**
10 | * Helper class that facilitates the returning user flow: check the installed email apps on the device, which will be
11 | * used by the web view to prompt users to open the email app to check for sign-in email.
12 | */
13 | final class EmailAppsChecker {
14 |
15 | private static final List APP_LIST;
16 |
17 | static {
18 | ArrayList list = new ArrayList<>(4);
19 | list.add("com.google.android.gm");
20 | list.add("com.microsoft.office.outlook");
21 | list.add("com.samsung.android.email.provider");
22 | list.add("com.yahoo.mobile.client.android.mail");
23 | APP_LIST = Collections.unmodifiableList(list);
24 | }
25 |
26 | private final PackageManager packageManager;
27 |
28 | EmailAppsChecker(PackageManager packageManager) {
29 | this.packageManager = packageManager;
30 | }
31 |
32 | @CheckReturnValue
33 | List detectEmailApps() {
34 | ArrayList detected = new ArrayList<>();
35 | for (String app : APP_LIST) {
36 | try {
37 | packageManager.getApplicationInfo(app, 0);
38 | detected.add(app);
39 | } catch (PackageManager.NameNotFoundException e) {
40 | // Could not find email app installed.
41 | }
42 | }
43 |
44 | return detected;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/connect-button/src/main/java/com/ifttt/connect/ui/EventsList.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.ui;
2 |
3 | import java.util.List;
4 |
5 | final class EventsList{
6 | private List events;
7 |
8 | EventsList(List events) {
9 | this.events = events;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/connect-button/src/main/java/com/ifttt/connect/ui/PendingResultLifecycleObserver.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.ui;
2 |
3 | import androidx.lifecycle.Lifecycle;
4 | import androidx.lifecycle.LifecycleObserver;
5 | import androidx.lifecycle.OnLifecycleEvent;
6 | import com.ifttt.connect.api.PendingResult;
7 |
8 | final class PendingResultLifecycleObserver implements LifecycleObserver {
9 |
10 | private final PendingResult pendingResult;
11 |
12 | PendingResultLifecycleObserver(PendingResult pendingResult) {
13 | this.pendingResult = pendingResult;
14 | }
15 |
16 | @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
17 | public void onStop() {
18 | pendingResult.cancel();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/connect-button/src/main/java/com/ifttt/connect/ui/ProgressBackground.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.ui;
2 |
3 | import androidx.annotation.ColorInt;
4 | import androidx.annotation.FloatRange;
5 |
6 | interface ProgressBackground {
7 |
8 | /**
9 | * Set the current progress that should be rendered.
10 | *
11 | * @param progress a progress value ranging from 0 to 1.
12 | */
13 | void setProgress(@FloatRange(from = 0.0f, to = 1.0f) float progress);
14 |
15 | /**
16 | * Set up the drawable as a progress bar.
17 | *
18 | * @param primaryColor Primary color of the drawable.
19 | * @param progressColor Progress bar color of the drawable.
20 | */
21 | void setColor(@ColorInt int primaryColor, @ColorInt int progressColor);
22 | }
23 |
--------------------------------------------------------------------------------
/connect-button/src/main/java/com/ifttt/connect/ui/Revertable.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.ui;
2 |
3 | /**
4 | * Interface that represents an action that can be reverted.
5 | */
6 | interface Revertable {
7 |
8 | void run();
9 |
10 | /**
11 | * Represents an action that reverts the action done by the {@link #run()} function.
12 | */
13 | void revert();
14 | }
15 |
--------------------------------------------------------------------------------
/connect-button/src/main/java/com/ifttt/connect/ui/RevertableHandler.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.ui;
2 |
3 | import android.os.Handler;
4 | import android.os.Looper;
5 | import java.util.ArrayList;
6 | import java.util.List;
7 |
8 | /**
9 | * A {@link Handler} wrapper that works with {@link Revertable} to automatically schedule a revert action for any
10 | * running Revertable.
11 | */
12 | final class RevertableHandler {
13 |
14 | private final List revertables = new ArrayList<>();
15 | private final Handler handler = new Handler(Looper.getMainLooper());
16 |
17 | /**
18 | * Run a {@link Revertable}, and automatically schedule a Runnable to call {@link Revertable#revert()} after a
19 | * delay.
20 | *
21 | * @param revertable Revertable object to run.
22 | * @param delay Delay in milliseconds that the revert function will be called.
23 | */
24 | void run(Revertable revertable, long delay) {
25 | Runnable toRevert = new Runnable() {
26 | @Override
27 | public void run() {
28 | revertables.remove(this);
29 | revertable.revert();
30 | }
31 | };
32 | revertables.add(toRevert);
33 |
34 | revertable.run();
35 | handler.postDelayed(toRevert, delay);
36 | }
37 |
38 | /**
39 | * Revert all of the scheduled revert actions.
40 | */
41 | void revertAll() {
42 | for (Runnable revertable : revertables) {
43 | handler.removeCallbacks(revertable);
44 | revertable.run();
45 | }
46 |
47 | revertables.clear();
48 | }
49 |
50 | /**
51 | * Remove all of the scheduled revert actions.
52 | */
53 | void clear() {
54 | for (Runnable revertable : revertables) {
55 | handler.removeCallbacks(revertable);
56 | }
57 |
58 | revertables.clear();
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/connect-button/src/main/java/com/ifttt/connect/ui/package-info.java:
--------------------------------------------------------------------------------
1 | @ParametersAreNonnullByDefault
2 | package com.ifttt.connect.ui;
3 |
4 | import javax.annotation.ParametersAreNonnullByDefault;
5 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/anim/ifttt_helper_text_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/anim/ifttt_helper_text_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/drawable-v21/ifttt_about_button_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/drawable/background_button.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/drawable/button_background_default.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/drawable/ic_close_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/drawable/ic_ifttt_about_1.xml:
--------------------------------------------------------------------------------
1 |
7 |
13 |
19 |
20 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/drawable/ic_ifttt_about_2.xml:
--------------------------------------------------------------------------------
1 |
7 |
13 |
19 |
20 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/drawable/ic_ifttt_about_3.xml:
--------------------------------------------------------------------------------
1 |
7 |
15 |
22 |
29 |
30 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/drawable/ic_ifttt_about_4.xml:
--------------------------------------------------------------------------------
1 |
7 |
15 |
21 |
27 |
35 |
36 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/drawable/ic_ifttt_about_arrow.xml:
--------------------------------------------------------------------------------
1 |
6 |
12 |
20 |
21 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/drawable/ic_ifttt_logo_black.xml:
--------------------------------------------------------------------------------
1 |
6 |
12 |
18 |
24 |
30 |
36 |
42 |
48 |
54 |
60 |
66 |
67 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/drawable/ic_ifttt_logo_white.xml:
--------------------------------------------------------------------------------
1 |
6 |
12 |
18 |
24 |
30 |
36 |
42 |
48 |
54 |
60 |
66 |
67 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/drawable/ic_start_arrow.xml:
--------------------------------------------------------------------------------
1 |
6 |
12 |
13 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/drawable/ifttt_about_button_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/drawable/ifttt_about_button_background_default.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/drawable/ifttt_about_button_background_pressed.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/drawable/ifttt_button_border.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/font/avenir_next_ltpro_bold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IFTTT/ConnectSDK-Android/30286987c6688f174d9b7eceaa23cb6bd273e869/connect-button/src/main/res/font/avenir_next_ltpro_bold.otf
--------------------------------------------------------------------------------
/connect-button/src/main/res/font/avenir_next_ltpro_demi.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IFTTT/ConnectSDK-Android/30286987c6688f174d9b7eceaa23cb6bd273e869/connect-button/src/main/res/font/avenir_next_ltpro_demi.otf
--------------------------------------------------------------------------------
/connect-button/src/main/res/layout/view_ifttt_progress.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
13 |
14 |
24 |
25 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/layout/view_ifttt_simple_connect_button.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
10 |
11 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values-cs/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Chraňte a monitorujte své údaje
4 | Odpojování...
5 | Ikona zahájení
6 | Zkontrolujte, že má váš telefon přístup k internetu
7 | Odpojeno
8 | Zadejte platný e-mail
9 | Můžete kdykoli odpojit
10 | Nový účet IFTTT pro %1$s
11 | Další informace
12 | Zkusit znovu
13 | Připojit
14 | Přechod na %1$s...
15 | Ikona služby %1$s
16 | cs
17 | FUNGUJE S IFTTT
18 | Odpojit
19 | Načítání…
20 | Vytváření účtu...
21 | Spravovat
22 | Připojeno
23 | Využíváním tohoto propojení vyjadřujete souhlas Ochrana soukromí a smluvní podmínky
24 | Ochrana soukromí a smluvní podmínky
25 | IFTTT propojuje %1$s s %2$s
26 | E-mail
27 | Připojování
28 | Připojit %1$s
29 | Ovládejte, které služby mají přístup k vašim údajům a jak je využívají
30 | Zabezpečeno pomocí IFTTT. Další informace
31 | Získejte nové funkce, kdy budou vaše oblíbené věci spolupracovat
32 |
33 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values-da/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Beskyt og overvåg dine data
4 | Afbryder forbindelsen...
5 | Start-ikon
6 | Sørg for, at din telefon har internetforbindelse
7 | Forbindelsen er afbrudt.
8 | Indtast gyldig e-mail
9 | Du kan afbryde forbindelsen når som helst
10 | Ny IFTTT-konto til %1$s
11 | Få flere oplysninger
12 | Nyt forsøg
13 | Opret forbindelse
14 | Går til %1$s...
15 | Ikon for %1$s-tjenesten
16 | da
17 | VIRKER MED IFTTT
18 | Afbryd forbindelse
19 | Indlæser...
20 | Opretter konto...
21 | Administrer
22 | Tilsluttede
23 | Ved at bruge denne forbindelse accepterer du vores Fortrolighedspolitik og vilkår.
24 | Fortrolighedspolitik og vilkår
25 | IFTTT opretter forbindelse mellem %1$s og %2$s
26 | E-mail
27 | Tilslutning
28 | Opret forbindelse til %1$s
29 | Styr, hvilke tjenester der har adgang til dine data, og hvordan de bruger dem
30 | Sikret med IFTTT. Få flere oplysninger
31 | Lås op for nye funktioner, når dine foretrukne ting fungerer sammen
32 |
33 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values-de/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Schützen und überwachen Sie Ihre Daten.
4 | Wird getrennt ...
5 | Startsymbol
6 | Stellen Sie sicher, dass Ihr Telefon über eine Internetverbindung verfügt.
7 | Verbindung getrennt
8 | Geben Sie eine gültige E-Mail-Adresse ein.
9 | Trennen jederzeit möglich
10 | Neues IFTTT-Konto für %1$s
11 | Weitere Informationen
12 | Wiederholen
13 | Verbinden
14 | Navigieren zu %1$s ...
15 | %1$s-Service-Symbol
16 | de
17 | FUNKTIONIERT MIT IFTTT
18 | Verbindung trennen
19 | Laden…
20 | Konto wird erstellt ...
21 | Verwalten
22 | verbunden
23 | Durch die Nutzung dieser Verbindung stimmen Sie unseren Datenschutzbestimmungen zu.
24 | Datenschutzbestimmungen
25 | IFTTT verbindet %1$s mit %2$s.
26 | E-Mail
27 | Wird verbunden
28 | Verbinden %1$s
29 | Steuern Sie, welche Dienste auf Ihre Daten zugreifen und wie sie diese verwenden.
30 | Mit IFTTT gesichert Weitere Informationen
31 | Schalten Sie neue Funktion frei, indem Sie Ihre Lieblingsapps zusammenarbeiten lassen.
32 |
33 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values-en-rGB/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Protect and monitor your data
4 | Disconnecting...
5 | Start icon
6 | Make sure your phone has internet connection
7 | Disconnected
8 | Enter valid email
9 | Unplug any time
10 | New IFTTT account for %1$s
11 | Learn more
12 | Retry
13 | Connect
14 | Going to %1$s...
15 | %1$s service icon
16 | en-GB
17 | WORKS WITH IFTTT
18 | Disconnect
19 | Loading...
20 | Creating account...
21 | Manage
22 | Connected
23 | By using this connection, you agree to our Privacy & Terms
24 | Privacy & Terms
25 | IFTTT connects %1$s to %2$s
26 | Email
27 | Connecting...
28 | Connect %1$s
29 | Control which services access your data and how they use it
30 | Secured with IFTTT. Learn More
31 | Unlock new features when your favourite things work together
32 |
33 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values-es-rUS/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Proteja y monitoree sus datos
4 | Desconectando...
5 | Icono de inicio
6 | Asegúrese de que su teléfono tenga conexión a internet
7 | Desconectado
8 | Ingrese un correo electrónico válido
9 | Desconéctese en cualquier momento
10 | Nueva cuenta IFTTT para %1$s
11 | Más información
12 | Intentar nuevamente
13 | Conectarse
14 | Yendo a %1$s...
15 | Icono de servicio de %1$s
16 | es-419
17 | FUNCIONA CON IFTTT
18 | Desconectar
19 | Cargando...
20 | Creando cuenta...
21 | Administrar
22 | Se conectó con
23 | Al usar esta conexión, acepta nuestros Términos y privacidad
24 | Términos y privacidad
25 | IFTTT conecta %1$s con %2$s
26 | Correo electrónico
27 | Conectando
28 | Conectar %1$s
29 | Controle qué servicios acceden a sus datos y cómo los usan
30 | Protegido con IFTTT. Más información
31 | Desbloquee nuevas funciones cuando sus cosas favoritas funcionan juntas
32 |
33 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values-es/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Protege y supervisa tus datos
4 | Desconectando...
5 | Icono de inicio
6 | Asegúrate de que tu teléfono tenga conexión a Internet
7 | Desconectado
8 | Introduce un correo electrónico válido
9 | Desconecta en cualquier momento
10 | Nueva cuenta IFTTT para %1$s
11 | Más información
12 | Reintentar
13 | Conectar
14 | Yendo a %1$s ...
15 | Icono de servicio de %1$s
16 | es
17 | FUNCIONA CON IFTTT
18 | Desconectar
19 | Cargando...
20 | Creando cuenta...
21 | Gestionar
22 | Conectado
23 | Al usar esta conexión, aceptas nuestros Privacidad y términos
24 | Privacidad y términos
25 | IFTTT conecta %1$s con %2$s
26 | Correo electrónico
27 | Conectando
28 | Conectar %1$s
29 | Controla qué servicios acceden a tus datos y cómo los usan
30 | Asegurado con IFTTT. Más información
31 | Desbloquea nuevas funciones cuando tus dispositivos favoritos trabajen juntos
32 |
33 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values-fi/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Suojaa ja tarkastele tietojasi
4 | Yhteys katkaistaan...
5 | Käynnistyskuvake
6 | Varmista, että puhelimesi on yhteydessä internetiin
7 | Yhteys katkaistu
8 | Anna kelvollinen sähköpostiosoite
9 | Poista käytöstä koska tahansa
10 | Uusi IFTTT-tili käyttäjälle %1$s
11 | Lisätietoja
12 | Yritä uudelleen
13 | Yhdistä
14 | Siirrytään kohteeseen %1$s...
15 | palvelukuvake %1$s
16 | fi
17 | TOIMII IFTTT:n kanssa
18 | Katkaise yhteys
19 | Ladataan...
20 | Tiliä luodaan...
21 | Hallinnoi
22 | Yhdistetty:
23 | Käyttämällä tätä yhteyttä hyväksyt Yksityisyys ja ehdot
24 | Yksityisyys ja ehdot
25 | IFTTT yhdistää kohteen %1$s kohteeseen %2$s
26 | Sähköposti
27 | Yhdistetään
28 | Yhdistä %1$s
29 | Määritä, mitkä palvelut voivat käyttää tietojasi ja miten
30 | IFTTT-suojattu. Lisätietoja
31 | Kun lempiasiasi toimivat yhdessä, voit hyödyntää uusia ominaisuuksia
32 |
33 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values-fr-rCA/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Protégez et surveillez vos données
4 | Déconnexion...
5 | Icône de démarrage
6 | Assurez-vous que votre téléphone dispose d\'une connexion Internet
7 | Déconnecté
8 | Saisir une adresse courriel valide
9 | Débranchez à tout moment
10 | Nouveau compte IFTTT pour %1$s
11 | En savoir plus
12 | Réessayer
13 | Connecter
14 | Aller à %1$s...
15 | icône de service %1$s
16 | fr-CA
17 | FONCTIONNE AVEC IFTTT
18 | Se déconnecter
19 | Chargement...
20 | Création du compte...
21 | Gérer
22 | Connecté
23 | En utilisant cette connexion, vous acceptez nos Confidentialité et modalités
24 | Confidentialité et modalités
25 | IFTTT connecte %1$s à %2$s
26 | Courriel
27 | Connexion
28 | Connecter %1$s
29 | Contrôlez quels services accèdent à vos données et comment ils les utilisent
30 | Sécurisé avec IFTTT. En savoir plus
31 | Déverrouillez de nouvelles fonctionnalités lorsque vos choses préférées fonctionnent ensemble
32 |
33 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values-fr/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Protégez et surveillez vos données
4 | Déconnexion...
5 | Icône de démarrage
6 | Assurez-vous que votre téléphone dispose d\'une connexion Internet
7 | Déconnecté
8 | Entrez une adresse e-mail valide
9 | Débranchez à tout moment
10 | Nouveau compte IFTTT pour %1$s
11 | En savoir plus
12 | Réessayer
13 | Connecter
14 | Déplacement vers %1$s...
15 | Icône de service %1$s
16 | fr
17 | FONCTIONNE AVEC IFTTT
18 | Déconnexion
19 | Chargement...
20 | Création du compte...
21 | Gérer
22 | Connecté
23 | En utilisant cette connexion, vous acceptez nos Confidentialité et conditions
24 | Confidentialité et conditions
25 | IFTTT connecte %1$s à %2$s
26 | Adresse e-mail
27 | Connexion
28 | Connecter %1$s
29 | Contrôlez quels services accèdent à vos données et comment ils les utilisent
30 | Sécurisé avec IFTTT. En savoir plus
31 | Déverrouillez de nouvelles fonctionnalités lorsque vos objets préférés fonctionnent ensemble
32 |
33 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values-it/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Proteggi e monitora i tuoi dati
4 | Scollegamento in corso...
5 | Icona di avvio
6 | Assicurati che il tuo telefono sia collegato a Internet
7 | Scollegato
8 | Inserisci un indirizzo e-mail valido
9 | Scollegati quando vuoi
10 | Nuovo account IFTTT per %1$s
11 | Per saperne di più
12 | Riprova
13 | Collega
14 | Spostamento verso %1$s...
15 | icona del servizio %1$s
16 | it
17 | FUNZIONA CON IFTTT
18 | Disconnetti
19 | Caricamento...
20 | Creazione dell\'account...
21 | Gestisci
22 | Collegato a
23 | Utilizzando questo collegamento, l\'utente accetta la nostra Informativa sulla privacy e termini
24 | Informativa sulla privacy e termini
25 | IFTTT si collega a %1$s per %2$s
26 | E-mail
27 | Connessione
28 | Collega %1$s
29 | Controlla quali servizi accedono ai tuoi dati e come li utilizzano
30 | Protetto con IFTTT. Per saperne di più
31 | Sblocca nuove funzioni quando i tuoi elementi preferiti funzionano assieme
32 |
33 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values-ja/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | データを保護し、監視します
4 | 接続解除中...
5 | スタートアイコン
6 | スマートフォンがインターネットに接続されていることを確認してください
7 | 切断済み
8 | 有効な電子メールの入力
9 | いつでも停止可能
10 | %1$sの新規アカウント
11 | 詳細を確認する
12 | 再試行
13 | 接続
14 | %1$sに移動中...
15 | %1$sサービスアイコン
16 | ja
17 | IFTTTと連携
18 | 切断
19 | 読み込み中…
20 | アカウントを作成中...
21 | 管理
22 | 接続済み
23 | この接続を使用すると、プライバシーと利用規約に同意したことになります
24 | プライバシーと利用規約
25 | IFTTTは%1$sを%2$sに接続します
26 | メール
27 | 接続中
28 | %1$sに接続
29 | データにアクセスするサービスとその使用方法を制御します
30 | IFTTTで保護 詳細を確認する
31 | お気に入りのものを連携すると、新しい機能を利用できます
32 |
33 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values-ko/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 데이터 보호 및 모니터링
4 | 연결을 해제하는 중...
5 | 시작 아이콘
6 | 전화가 인터넷에 연결되었는지 확인
7 | 연결 해제됨
8 | 올바른 이메일 입력
9 | 언제든지 플러그 분리
10 | %1$s을(를) 위한 새 IFTTT 계정
11 | 자세히 알아보기
12 | 재시도
13 | 연결
14 | %1$s(으)로 이동하는 중...
15 | %1$s 서비스 아이콘
16 | ko
17 | IFTTT와 함께 사용 가능
18 | 연결 해제
19 | 로드 중...
20 | 계정을 만드는 중...
21 | 관리
22 | 연결된
23 | 이 연결 사용 시 당사의 개인정보 개인정보 및 약관
24 | 개인정보 및 약관
25 | IFTTT는 %1$s을(를) %2$s에 연결합니다.
26 | 이메일
27 | 연결 중
28 | %1$s에 연결
29 | 데이터에 액세스하는 서비스와 사용하는 방법 제어
30 | IFTTT로 보안 처리되었습니다. 자세히 알아보기
31 | 즐겨 사용하는 장치를 함께 사용할 때 새 기능 잠금 해제
32 |
33 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values-nb/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Beskytt og overvåk dataene dine
4 | Kobler fra ...
5 | Start-ikon
6 | Kontroller at telefonen har tilkobling til Internett
7 | Frakoblet
8 | Angi en gyldig e-postadresse
9 | Koble ut når som helst
10 | Ny IFTTT-konto for %1$s
11 | Finn ut mer
12 | Prøv igjen
13 | Koble til
14 | Går til %1$s ...
15 | %1$s-tjenesteikon
16 | nb
17 | FUNGERER MED IFTTT
18 | Koble fra
19 | Laster inn ...
20 | Oppretter konto ...
21 | Administrer
22 | Tilkoblet
23 | Ved å bruke denne koblingen, godtar du våre retningslinjer for Personvern og vilkår
24 | Personvern og vilkår
25 | IFTTT kobler %1$s til %2$s
26 | E-post
27 | Kobler til
28 | Koble til %1$s
29 | Kontroller hvilke tjenester som har tilgang til dataene dine og hvordan de bruker dem
30 | Sikret med IFTTT. Finn ut mer
31 | Lås opp nye funksjoner når favorittingene dine samarbeider
32 |
33 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values-nl/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Uw gegevens beschermen en controleren
4 | Verbinding verbreken...
5 | Startpictogram
6 | Zorg dat uw telefoon een internetverbinding heeft
7 | Verbinding verbroken
8 | Vul een geldig e-mailadres in
9 | Op elk gewenst moment loskoppelen
10 | Nieuw IFTTT-account voor %1$s
11 | Meer informatie
12 | Opnieuw proberen
13 | Verbinden
14 | Gaat %1$s naar...
15 | %1$s-servicepictogram
16 | nl
17 | WERKT MET IFTTT
18 | Verbinding verbreken
19 | Bezig met laden...
20 | Account maken...
21 | Beheren
22 | Verbonden
23 | Door deze verbinding te gebruiken, gaat u akkoord met onze Privacy en voorwaarden
24 | Privacy en voorwaarden
25 | IFTTT verbindt %1$s met %2$s
26 | E-mail
27 | Verbinding maken
28 | Verbinden met %1$s
29 | Bepaal welke services toegang hebben tot uw gegevens en hoe ze deze gebruiken
30 | Beveiligd met IFTTT. Meer informatie
31 | Ontgrendel nieuwe functies wanneer uw favoriete dingen samenwerken
32 |
33 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values-pl/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Monitoruj i chroń swoje dane
4 | Rozłączanie...
5 | Ikona Start
6 | Upewnij się, że Twój telefon ma połączenie z Internetem
7 | Rozłączono
8 | Wprowadź prawidłowy e-mail
9 | Możesz odłączyć w dowolnym momencie
10 | Nowe konto IFTTT dla %1$s
11 | Dowiedz się więcej
12 | Spróbuj ponownie
13 | Połącz
14 | Przechodzenie do %1$s...
15 | Ikona usługi %1$s
16 | pl
17 | DZIAŁA Z IFTTT
18 | Rozłącz
19 | Wczytywanie...
20 | Tworzenie konta...
21 | Zarządzaj
22 | Połączony
23 | Korzystanie z tego połączenia jest równoznaczne z wyrażeniem zgody na Warunki i Polityka prywatności
24 | Warunki i Polityka prywatności
25 | IFTTT łączy %1$s z %2$s
26 | E-mail
27 | Łączenie
28 | Połącz %1$s
29 | Kontroluj, które usługi mogą mieć dostęp do Twoich danych, i jak mogą je wykorzystywać
30 | Zabezpieczone za pomocą IFTTT. Dowiedz się więcej
31 | Odkrywaj nowe funkcje, gdy ulubione elementy współpracują ze sobą
32 |
33 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Proteja e monitore seus dados
4 | Desconectando...
5 | Ícone de início
6 | Verifique se o telefone tem conexão com a Internet
7 | Desconectado
8 | Insira um e-mail válido
9 | Desconecte a qualquer momento
10 | Nova conta do IFTTT para %1$s
11 | Saiba mais
12 | Tentar novamente
13 | Conectar-se
14 | Indo para %1$s...
15 | Ícone de serviço do %1$s
16 | pt-BR
17 | TAREFAS COM O IFTTT
18 | Desconectar
19 | Carregando...
20 | Criando conta...
21 | Gerenciar
22 | Conectado
23 | Ao usar esta conexão, você concorda com nossa Privacidade e nossos Termos
24 | Privacidade e nossos Termos
25 | O IFTTT conecta %1$s a %2$s
26 | E-mail
27 | Conectando
28 | Conectar %1$s
29 | Controle quais serviços acessam seus dados e como eles os usam
30 | Seguro com o IFTTT. Saiba mais
31 | Libere novos recursos quando seus produtos favoritos funcionam em conjunto
32 |
33 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values-pt-rPT/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Proteja e monitorize os seus dados
4 | A desligar...
5 | Ícone de iniciar
6 | Certifique-se de que o seu telefone tem ligação à Internet
7 | Desligado
8 | Introduza um e-mail válido
9 | Desligue em qualquer altura
10 | Nova conta IFTTT para %1$s
11 | Mais informações
12 | Repetir
13 | Estabelecer ligação
14 | A ir para %1$s...
15 | Ícone de serviço %1$s
16 | pt-PT
17 | FUNCIONA COM IFTTT
18 | Desligar
19 | A carregar
20 | A criar conta...
21 | Gerir
22 | ligado
23 | A utilizar esta ligação, concorda com os nossos Termos e Privacidade
24 | Termos e Privacidade
25 | IFTTT liga %1$s para %2$s
26 | E-mail
27 | A ligar
28 | Estabelecer ligação a %1$s
29 | Controle que serviços acedem aos seus dados e como utilizá-los
30 | Protegido com IFTTT. Mais informações
31 | Desbloqueie novas funcionalidades quando os seus equipamentos favoritos trabalham em conjunto
32 |
33 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values-ru/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Защищайте и отслеживайте свои данные
4 | Отключение...
5 | Значок запуска
6 | Убедитесь, что телефон подключен к Интернету
7 | Отключено
8 | Введите действительный адрес
9 | Вы можете отключиться в любой момент!
10 | Новая учетная запись IFTTT для %1$s
11 | Узнайте больше
12 | Повторить попытку
13 | Подключиться
14 | Переход к %1$s...
15 | Значок службы %1$s
16 | ru
17 | РАБОТАЕТ С IFTTT
18 | Отключиться
19 | Загрузка...
20 | Создание учетной записи...
21 | Управление
22 | Подключено:
23 | Используя это подключение, вы принимаете наши Политику конфиденциальности и Условия
24 | конфиденциальности и Условия
25 | IFTTT подключает %1$s к %2$s
26 | Адрес электронной почты
27 | Подключение
28 | Подключить %1$s
29 | Контролируйте доступ различных служб к вашим данным и их использование
30 | Под защитой IFTTT. Узнайте больше
31 | Откройте новые возможности благодаря взаимодействию ваших любимых вещей
32 |
33 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values-sv/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Skydda och övervaka dina uppgifter
4 | Kopplar från…
5 | Startsymbol
6 | Kontrollera att din telefon har en Internetanslutning
7 | Frånkopplad
8 | Ange en giltig e-postadress
9 | Koppla ur när som helst
10 | Nytt IFTTT-konto för %1$s
11 | Läs mer
12 | Försök igen
13 | Anslut
14 | Går till %1$s…
15 | Servicesymbol för %1$s
16 | sv
17 | FUNGERAR MED IFTTT
18 | Koppla från
19 | Läser in ...
20 | Skapar konto…
21 | Hantera
22 | Ansluten till
23 | Genom att använda den här anslutningen accepterar du vår Sekretesspolicy och våra villkor
24 | Sekretesspolicy och våra villkor
25 | IFTTT ansluter %1$s till %2$s
26 | E-post
27 | Ansluter
28 | Anslut %1$s
29 | Styr vilka tjänster som kommer åt dina uppgifter och hur de använder dem
30 | Skyddad med IFTTT. Läs mer
31 | Upptäck nya funktioner när dina favoritsaker arbetar tillsammans
32 |
33 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values-v21/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #666666
4 |
5 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values-zh-rCN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 保护和监控您的数据
4 | 正在断开连接...
5 | 开始图标
6 | 确保您的手机已连接互联网
7 | 已断开连接
8 | 输入有效的邮箱
9 | 可随时断电
10 | 为 %1$s 新建 IFTTT 帐户
11 | 了解更多
12 | 重试
13 | 连接
14 | 正在转到 %1$s...
15 | %1$s 服务图标
16 | zh-Hans
17 | 使用 IFTTT
18 | 断开连接
19 | 正在加载...
20 | 正在创建帐户...
21 | 管理
22 | 已连接
23 | 使用此连接,即表示您同意我们的隐私条款
24 | 隐私条款
25 | IFTTT 将 %1$s 连接至 %2$s
26 | 电子邮箱
27 | 正在连接
28 | 连接 %1$s
29 | 控制可访问您数据的服务,并管理其使用方式
30 | IFTTT 提供保护。了解更多
31 | 常用工具齐登场,助力解锁新功能。
32 |
33 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values-zh-rTW/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 保護並監控您的資料
4 | 正在中斷連線...
5 | 開始圖示
6 | 請確定您的手機有網際網路連線
7 | 已中斷連線
8 | 輸入有效的電子郵件
9 | 隨時斷開
10 | %1$s 的 IFTTT 新帳戶
11 | 了解更多
12 | 重試
13 | 連線
14 | 正在前往 %1$s...
15 | %1$s 服務圖示
16 | zh-Hant
17 | 搭配使用 IFTTT
18 | 中斷連線
19 | 正在載入...
20 | 正在建立帳戶...
21 | 管理
22 | 已連線
23 | 使用此連線,即表示您同意我們的隱私權與條款
24 | 隱私權與條款
25 | IFTTT 會將 %1$s 連線至 %2$s
26 | 電子郵件
27 | 正在連線
28 | 連線 %1$s
29 | 控制哪些服務可存取您的資料,以及使用資料的方式
30 | 透過 IFTTT 保護。了解更多
31 | 讓您喜愛的事物彼此合作,就能發掘出新功能
32 |
33 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #EEEEEE
4 | #CBCBCB
5 | #222222
6 | #444444
7 | #41FFFFFF
8 | #222222
9 | #666666
10 | #FFFFFF
11 | #FF2121
12 | #4DFFFFFF
13 | #4D000000
14 | #4CFFFFFF
15 |
16 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values/public.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Connect %1$s
4 | Connect
5 | Email
6 | IFTTT connects %1$s to %2$s
7 | Learn more
8 | WORKS WITH IFTTT
9 | Unlock new features when your favorite things work together
10 | Control which services access your data and how they use it
11 | Protect and monitor your data
12 | Unplug any time
13 | Creating account…
14 | Going to %1$s…
15 | Connected
16 | Connecting…
17 | Disconnecting…
18 | Disconnect
19 | Please enter a valid email address
20 | By using this connection you agree to our Privacy & Terms
21 | Privacy & Terms
22 | Secured with IFTTT Learn more
23 | Manage
24 | Loading…
25 | Make sure your phone has internet connection
26 | New IFTTT account for %1$s
27 | Retry
28 |
29 |
30 |
31 | %1$s service icon
32 | Start icon
33 | Disconnected
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/connect-button/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
9 |
10 |
13 |
14 |
--------------------------------------------------------------------------------
/connect-button/src/test/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/connect-button/src/test/java/com/ifttt/connect/api/TestUtils.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.api;
2 |
3 | import android.content.Context;
4 | import com.squareup.moshi.JsonAdapter;
5 | import com.squareup.moshi.JsonReader;
6 | import com.squareup.moshi.Moshi;
7 | import com.squareup.moshi.adapters.Rfc3339DateJsonAdapter;
8 | import java.io.IOException;
9 | import java.io.InputStream;
10 | import java.util.Date;
11 | import okhttp3.mockwebserver.MockWebServer;
12 | import okio.Okio;
13 |
14 | public final class TestUtils {
15 |
16 | private static final Moshi MOSHI = new Moshi.Builder().add(Date.class, new Rfc3339DateJsonAdapter().nullSafe()).add(
17 | new HexColorJsonAdapter()).add(new ConnectionJsonAdapter()).build();
18 |
19 | private static final JsonAdapter CONNECTION_ADAPTER = MOSHI.adapter(Connection.class);
20 |
21 | public static Connection loadConnection(ClassLoader classLoader) throws IOException {
22 | InputStream inputStream = classLoader.getResourceAsStream("connection.json");
23 | JsonReader jsonReader = JsonReader.of(Okio.buffer(Okio.source(inputStream)));
24 | return CONNECTION_ADAPTER.fromJson(jsonReader);
25 | }
26 |
27 | public static ConnectionApiClient getMockConnectionApiClient(
28 | Context context, MockWebServer server, UserTokenProvider provider
29 | ) {
30 | return new ConnectionApiClient.Builder(context, provider).buildWithBaseUrl(server.url("").toString());
31 | }
32 |
33 | private TestUtils() {
34 | throw new AssertionError();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/connect-button/src/test/java/com/ifttt/connect/ui/ConnectResultTest.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.ui;
2 |
3 | import android.content.Intent;
4 | import android.net.Uri;
5 | import org.junit.Test;
6 | import org.junit.runner.RunWith;
7 | import org.robolectric.RobolectricTestRunner;
8 |
9 | import static com.google.common.truth.Truth.assertThat;
10 |
11 | @RunWith(RobolectricTestRunner.class)
12 | public final class ConnectResultTest {
13 |
14 | @Test
15 | public void fromInvalidServiceConnection() {
16 | Intent intent = new Intent().setData(Uri.parse("test://url?next_step=service_connection"));
17 | ConnectResult result = ConnectResult.fromIntent(intent);
18 |
19 | assertThat(result.nextStep).isEqualTo(ConnectResult.NextStep.Unknown);
20 | assertThat(result.errorType).isNull();
21 | }
22 |
23 | @Test
24 | public void fromComplete() {
25 | Intent intent = new Intent().setData(Uri.parse("test://url?next_step=complete"));
26 | ConnectResult result = ConnectResult.fromIntent(intent);
27 |
28 | assertThat(result.nextStep).isEqualTo(ConnectResult.NextStep.Complete);
29 | assertThat(result.errorType).isNull();
30 | }
31 |
32 | @Test
33 | public void fromUnknownState() {
34 | Intent intent = new Intent().setData(Uri.parse("test://url?"));
35 | ConnectResult result = ConnectResult.fromIntent(intent);
36 |
37 | assertThat(result.nextStep).isEqualTo(ConnectResult.NextStep.Unknown);
38 | assertThat(result.errorType).isNull();
39 | }
40 |
41 | @Test
42 | public void fromError() {
43 | Intent intent = new Intent().setData(Uri.parse("test://url?next_step=error&error_type=account_creation"));
44 | ConnectResult result = ConnectResult.fromIntent(intent);
45 |
46 | assertThat(result.nextStep).isEqualTo(ConnectResult.NextStep.Error);
47 | assertThat(result.errorType).isEqualTo("account_creation");
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/connect-button/src/test/java/com/ifttt/connect/ui/DisableTrackingTest.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.ui;
2 |
3 | import static com.google.common.truth.Truth.assertThat;
4 |
5 | import android.content.Context;
6 |
7 | import androidx.test.core.app.ApplicationProvider;
8 | import androidx.test.ext.junit.runners.AndroidJUnit4;
9 | import androidx.work.Configuration;
10 | import androidx.work.testing.SynchronousExecutor;
11 | import androidx.work.testing.WorkManagerTestInitHelper;
12 |
13 | import org.junit.Before;
14 | import org.junit.Test;
15 | import org.junit.runner.RunWith;
16 | import org.robolectric.annotation.LooperMode;
17 |
18 | @RunWith(AndroidJUnit4.class)
19 | @LooperMode(LooperMode.Mode.PAUSED)
20 | public final class DisableTrackingTest {
21 |
22 | private AnalyticsManager analyticsManager;
23 |
24 | @Before
25 | public void setup() {
26 | Context context = ApplicationProvider.getApplicationContext();
27 | Configuration config = new Configuration.Builder()
28 | .setExecutor(new SynchronousExecutor())
29 | .build();
30 | WorkManagerTestInitHelper.initializeTestWorkManager(context, config);
31 |
32 | analyticsManager = AnalyticsManager.getInstance(context);
33 | }
34 |
35 | @Test
36 | public void testAnalyticsDisabled() {
37 | analyticsManager.clearQueue();
38 | assertThat(analyticsManager.performRead().size()).isEqualTo(0);
39 |
40 | analyticsManager.disableTracking();
41 | analyticsManager.trackUiClick(new AnalyticsObject("obj_id", "obj_type"), new AnalyticsLocation("loc_id", "loc_type"));
42 |
43 | assertThat(analyticsManager.performRead().size()).isEqualTo(0);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/connect-button/src/test/java/com/ifttt/connect/ui/QueueOperationsTest.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.ui;
2 |
3 | import static com.google.common.truth.Truth.assertThat;
4 |
5 | import androidx.test.ext.junit.runners.AndroidJUnit4;
6 |
7 | import com.ifttt.connect.R;
8 |
9 | import org.junit.Before;
10 | import org.junit.Test;
11 | import org.junit.runner.RunWith;
12 | import org.robolectric.Robolectric;
13 | import org.robolectric.android.controller.ActivityController;
14 | import org.robolectric.annotation.Config;
15 |
16 | import java.util.HashMap;
17 |
18 | @RunWith(AndroidJUnit4.class)
19 | @Config(sdk = 28)
20 | public final class QueueOperationsTest {
21 | private AnalyticsManager analyticsManager;
22 |
23 | @Before
24 | public void setup() {
25 | ActivityController controller = Robolectric.buildActivity(TestActivity.class);
26 | controller.get().setTheme(R.style.Base_Theme_AppCompat);
27 | controller.create().start();
28 |
29 | analyticsManager = AnalyticsManager.getInstance(controller.get());
30 | analyticsManager.clearQueue();
31 | }
32 |
33 | @Test
34 | public void testEnqueueAndRead() {
35 | assertThat(analyticsManager.performRead().size()).isEqualTo(0);
36 |
37 | analyticsManager.performAdd(new AnalyticsEventPayload("event1", "", new HashMap<>()));
38 | analyticsManager.performAdd(new AnalyticsEventPayload("event2", "", new HashMap<>()));
39 | analyticsManager.performAdd(new AnalyticsEventPayload("event3", "", new HashMap<>()));
40 |
41 | assertThat(analyticsManager.performRead().size()).isEqualTo(3);
42 | }
43 |
44 | @Test
45 | public void testRemove() {
46 | assertThat(analyticsManager.performRead().size()).isEqualTo(0);
47 |
48 | analyticsManager.performAdd(new AnalyticsEventPayload("event1", "", new HashMap<>()));
49 | analyticsManager.performAdd(new AnalyticsEventPayload("event2", "", new HashMap<>()));
50 | analyticsManager.performAdd(new AnalyticsEventPayload("event3", "", new HashMap<>()));
51 |
52 | analyticsManager.performRemove(3);
53 | assertThat(analyticsManager.performRead().size()).isEqualTo(0);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/connect-button/src/test/java/com/ifttt/connect/ui/StartIconDrawableTest.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.ui;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.robolectric.RobolectricTestRunner;
6 |
7 | import static android.graphics.Color.parseColor;
8 | import static com.google.common.truth.Truth.assertThat;
9 | import static com.ifttt.connect.ui.StartIconDrawable.isDarkColor;
10 |
11 | @RunWith(RobolectricTestRunner.class)
12 | public final class StartIconDrawableTest {
13 |
14 | @Test
15 | public void testIsDarkColor() {
16 | String[] colors = new String[] {
17 | "#333333", "#3B579D", "#E4405F", "#0099FF", "#4D4E4D", "#1ED760", "#000000", "#1E2023", "#FFFFFF"
18 | };
19 |
20 | assertThat(isDarkColor(parseColor(colors[0]))).isTrue();
21 | assertThat(isDarkColor(parseColor(colors[1]))).isFalse();
22 | assertThat(isDarkColor(parseColor(colors[2]))).isFalse();
23 | assertThat(isDarkColor(parseColor(colors[3]))).isFalse();
24 | assertThat(isDarkColor(parseColor(colors[4]))).isFalse();
25 | assertThat(isDarkColor(parseColor(colors[5]))).isFalse();
26 | assertThat(isDarkColor(parseColor(colors[6]))).isTrue();
27 | assertThat(isDarkColor(parseColor(colors[7]))).isTrue();
28 | assertThat(isDarkColor(parseColor(colors[8]))).isFalse();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/connect-button/src/test/java/com/ifttt/connect/ui/TestActivity.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.connect.ui;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.widget.FrameLayout;
6 | import androidx.annotation.Nullable;
7 | import androidx.work.Configuration;
8 | import androidx.work.testing.SynchronousExecutor;
9 | import androidx.work.testing.WorkManagerTestInitHelper;
10 | import com.ifttt.connect.R;
11 |
12 | import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
13 | import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
14 |
15 | public final class TestActivity extends Activity {
16 |
17 | @Override
18 | protected void onCreate(@Nullable Bundle savedInstanceState) {
19 | super.onCreate(savedInstanceState);
20 |
21 | final Configuration config = new Configuration.Builder()
22 | .setExecutor(new SynchronousExecutor())
23 | .build();
24 | WorkManagerTestInitHelper.initializeTestWorkManager(
25 | this, config);
26 |
27 | BaseConnectButton button = new BaseConnectButton(this);
28 | button.setId(R.id.ifttt_connect_button_test);
29 | button.setLayoutParams(new FrameLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
30 |
31 | setContentView(button);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/connect-location/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/connect-location/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion rootProject.compileSdkVersion
5 |
6 | defaultConfig {
7 | minSdkVersion rootProject.minSdkVersion
8 |
9 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
10 | }
11 |
12 | buildTypes {
13 | release {
14 | minifyEnabled false
15 | }
16 | }
17 |
18 | compileOptions {
19 | sourceCompatibility JavaVersion.VERSION_1_8
20 | targetCompatibility JavaVersion.VERSION_1_8
21 | }
22 |
23 | testOptions.unitTests.includeAndroidResources = true
24 | namespace 'com.ifttt.location'
25 | }
26 |
27 | dependencies {
28 | debugImplementation project(':connect-button')
29 | releaseImplementation "com.ifttt:connect-button:$libVersion"
30 | releaseImplementation "com.ifttt:connect-api:$libVersion"
31 |
32 | implementation "com.google.android.gms:play-services-awareness:$awarenessVersion"
33 | implementation "androidx.work:work-runtime:$workManagerVersion"
34 |
35 | testImplementation "junit:junit:$junitVersion"
36 | testImplementation "org.robolectric:robolectric:$robolectricVersion"
37 | testImplementation "androidx.test:runner:$androidXTestVersion"
38 | testImplementation "androidx.test:core:$androidXTestVersion"
39 | testImplementation "androidx.test.ext:truth:$androidXTestVersion"
40 | testImplementation "androidx.test.ext:junit:$androidXJunitVersion"
41 | testImplementation "com.squareup.retrofit2:retrofit-mock:$retrofitVersion"
42 | testImplementation "androidx.work:work-testing:$workManagerVersion"
43 | }
44 |
45 | apply from: 'publish.gradle'
46 |
--------------------------------------------------------------------------------
/connect-location/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/connect-location/src/main/java/com/ifttt/location/AwarenessEnterReceiver.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.location;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import com.google.android.gms.awareness.fence.FenceState;
7 |
8 | import static com.ifttt.location.LocationEventAttributes.LocationDataSource.Awareness;
9 | import static com.ifttt.location.LocationEventUploader.EventType.Entry;
10 |
11 | /**
12 | * BroadcastReceiver that listens to all "enter" geo-fence events.
13 | */
14 | public final class AwarenessEnterReceiver extends BroadcastReceiver {
15 |
16 | @Override
17 | public void onReceive(Context context, Intent intent) {
18 | FenceState fenceState = FenceState.extract(intent);
19 | if (fenceState.getCurrentState() != FenceState.TRUE) {
20 | Logger.error("Geo-fence enter event, fence state: " + fenceState.getCurrentState());
21 | return;
22 | }
23 |
24 | BackupGeofenceMonitor monitor = BackupGeofenceMonitor.get(context);
25 | if (BackupGeofenceMonitor.MonitoredGeofence.GeofenceState.Entered
26 | == monitor.getState(fenceState.getFenceKey())) {
27 | return;
28 | }
29 |
30 | Logger.log("Geo-fence enter event");
31 | LocationEventHelper.logEventReported(ConnectLocation.getInstance(), Entry, Awareness);
32 |
33 | String stepId = LocationEventUploadHelper.extractStepId(fenceState.getFenceKey());
34 | LocationEventUploader.schedule(context, Entry, Awareness, stepId);
35 | monitor.setState(fenceState.getFenceKey(), BackupGeofenceMonitor.MonitoredGeofence.GeofenceState.Entered);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/connect-location/src/main/java/com/ifttt/location/AwarenessExitReceiver.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.location;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import com.google.android.gms.awareness.fence.FenceState;
7 |
8 | import static com.ifttt.location.LocationEventAttributes.LocationDataSource.Awareness;
9 | import static com.ifttt.location.LocationEventUploader.EventType.Exit;
10 |
11 | /**
12 | * BroadcastReceiver that listens to all "exit" geo-fence events.
13 | */
14 | public final class AwarenessExitReceiver extends BroadcastReceiver {
15 |
16 | @Override
17 | public void onReceive(Context context, Intent intent) {
18 | FenceState fenceState = FenceState.extract(intent);
19 | if (fenceState.getCurrentState() != FenceState.TRUE) {
20 | Logger.error("Geo-fence exit event, fence state: " + fenceState.getCurrentState());
21 | return;
22 | }
23 |
24 | BackupGeofenceMonitor monitor = BackupGeofenceMonitor.get(context);
25 | if (BackupGeofenceMonitor.MonitoredGeofence.GeofenceState.Exited
26 | == monitor.getState(fenceState.getFenceKey())) {
27 | return;
28 | }
29 |
30 | Logger.log("Geo-fence exit event");
31 | LocationEventHelper.logEventReported(ConnectLocation.getInstance(), Exit, Awareness);
32 |
33 | String stepId = LocationEventUploadHelper.extractStepId(fenceState.getFenceKey());
34 | LocationEventUploader.schedule(context, Exit, Awareness, stepId);
35 | monitor.setState(fenceState.getFenceKey(), BackupGeofenceMonitor.MonitoredGeofence.GeofenceState.Exited);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/connect-location/src/main/java/com/ifttt/location/Cache.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.location;
2 |
3 | /**
4 | * Interface representing cached data within ConnectLocation module.
5 | *
6 | * @see SharedPreferencesGeofenceCache
7 | * @see SharedPreferenceUserTokenCache
8 | */
9 | interface Cache {
10 | void write(T t);
11 |
12 | T read();
13 |
14 | void clear();
15 | }
16 |
--------------------------------------------------------------------------------
/connect-location/src/main/java/com/ifttt/location/CacheUserTokenProvider.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.location;
2 |
3 | import androidx.annotation.Nullable;
4 | import com.ifttt.connect.api.UserTokenProvider;
5 |
6 | class CacheUserTokenProvider implements UserTokenProvider {
7 |
8 | private final Cache cache;
9 | @Nullable private final UserTokenProvider delegate;
10 |
11 | CacheUserTokenProvider(Cache cache, @Nullable UserTokenProvider delegate) {
12 | this.cache = cache;
13 | this.delegate = delegate;
14 | }
15 |
16 | @Nullable
17 | @Override
18 | public String getUserToken() {
19 | String token;
20 | if (delegate != null) {
21 | token = delegate.getUserToken();
22 | if (token != null && token.length() > 0) {
23 | cache.write(token);
24 | }
25 | } else {
26 | token = cache.read();
27 | }
28 |
29 | return token;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/connect-location/src/main/java/com/ifttt/location/GeofenceProvider.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.location;
2 |
3 | import android.Manifest;
4 | import androidx.annotation.Nullable;
5 | import androidx.annotation.RequiresPermission;
6 | import com.ifttt.connect.api.Connection;
7 | import com.ifttt.location.ConnectLocation.LocationStatusCallback;
8 | import java.util.Arrays;
9 | import java.util.HashSet;
10 | import java.util.Set;
11 |
12 | /**
13 | * Abstract type for a geofence functionality provider. The type is responsbile for setting up geofences given a
14 | * {@link Connection}.
15 | */
16 | interface GeofenceProvider {
17 |
18 | String FIELD_TYPE_LOCATION_ENTER = "LOCATION_ENTER";
19 | String FIELD_TYPE_LOCATION_EXIT = "LOCATION_EXIT";
20 | String FIELD_TYPE_LOCATION_ENTER_EXIT = "LOCATION_ENTER_OR_EXIT";
21 |
22 | Set LOCATION_FIELD_TYPES_LIST = new HashSet<>(Arrays.asList(FIELD_TYPE_LOCATION_ENTER,
23 | FIELD_TYPE_LOCATION_EXIT,
24 | FIELD_TYPE_LOCATION_ENTER_EXIT
25 | ));
26 |
27 | @RequiresPermission(Manifest.permission.ACCESS_FINE_LOCATION)
28 | void updateGeofences(final Connection connection, @Nullable LocationStatusCallback locationStatusCallback);
29 |
30 | void removeGeofences(@Nullable LocationStatusCallback locationStatusCallback);
31 | }
32 |
--------------------------------------------------------------------------------
/connect-location/src/main/java/com/ifttt/location/LocationEventAttributes.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.location;
2 |
3 | /**
4 | * Attributes and meta-data for background location events reported by {@link LocationEventListener}.
5 | */
6 | public final class LocationEventAttributes {
7 |
8 | /**
9 | * Location change event types, represented by {@link LocationEventUploader.EventType}.
10 | */
11 | public static final String LOCATION_EVENT_EVENT_TYPE = "eventType";
12 |
13 | /**
14 | * Unique location event upload job ID.
15 | */
16 | public static final String LOCATION_EVENT_JOB_ID = "jobId";
17 |
18 | /**
19 | * Error types encountered during location event upload, represented by {@link ErrorType}.
20 | */
21 | public static final String LOCATION_EVENT_ERROR_TYPE = "error";
22 |
23 | /**
24 | * Free-form text from the errors as additional data.
25 | */
26 | public static final String LOCATION_EVENT_ERROR_MESSAGE = "errorMessage";
27 |
28 | /**
29 | * Timestamp representing the lapsed time between a location event is reported and it is to be uploaded.
30 | */
31 | public static final String LOCATION_EVENT_DELAY_TO_UPLOAD = "delayToUpload";
32 |
33 | /**
34 | * Timestamp representing the time it takes to upload a location event.
35 | */
36 | public static final String LOCATION_EVENT_DELAY_TO_COMPLETE = "delayToComplete";
37 |
38 | /**
39 | * Location change events' source types, represented by {@link LocationDataSource}.
40 | */
41 | public static final String LOCATION_EVENT_SOURCE = "source";
42 |
43 | public enum ErrorType {
44 | Network,
45 | Sdk
46 | }
47 |
48 | public enum LocationDataSource {
49 | LocationReport, Awareness
50 | }
51 |
52 | private LocationEventAttributes() {
53 | throw new AssertionError();
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/connect-location/src/main/java/com/ifttt/location/LocationEventListener.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.location;
2 |
3 | import java.util.Map;
4 |
5 | /**
6 | * Listener interface that reports background location events and their attributes
7 | * whenever a location change happens on any of the registered geofences.
8 | */
9 | public interface LocationEventListener {
10 |
11 | void onLocationEventReported(LocationEventType type, Map data);
12 | }
13 |
--------------------------------------------------------------------------------
/connect-location/src/main/java/com/ifttt/location/LocationEventType.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.location;
2 |
3 | /**
4 | * Representations of the background location events that {@link LocationEventListener} listens to.
5 | */
6 | public enum LocationEventType {
7 | /**
8 | * A location change event (entering or exiting a geofence) is reported to the SDK.
9 | */
10 | EventReported,
11 |
12 | /**
13 | * A location change event is scheduled to be uploaded to IFTTT.
14 | */
15 | EventUploadAttempted,
16 |
17 | /**
18 | * A location change event is uploaded successfully to IFTTT.
19 | */
20 | EventUploadSuccessful,
21 |
22 | /**
23 | * A location change event could not be uploaded to IFTTT.
24 | */
25 | EventUploadFailed
26 | }
27 |
--------------------------------------------------------------------------------
/connect-location/src/main/java/com/ifttt/location/LocationInfo.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.location;
2 |
3 | import com.squareup.moshi.Json;
4 | import java.text.DateFormat;
5 | import java.text.SimpleDateFormat;
6 | import java.util.Locale;
7 | import java.util.UUID;
8 |
9 | final class LocationInfo {
10 |
11 | private static final DateFormat LOCATION_EVENT_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX",
12 | Locale.US
13 | );
14 |
15 | @Json(name = "channel_id") final String channelId = "941030000";
16 | @Json(name = "trigger_subscription_id") final String triggerSubscriptionId;
17 | @Json(name = "record_id") final String recordId = UUID.randomUUID().toString();
18 | @Json(name = "occurred_at") final String occurredAt;
19 | @Json(name = "event_type") final String eventType;
20 | @Json(name = "region_type") final String regionType = "geo";
21 | @Json(name = "installation_id") final String installationId;
22 |
23 | private LocationInfo(
24 | String triggerSubscriptionId, String occurredAt, String eventType, String installationId
25 | ) {
26 | this.triggerSubscriptionId = triggerSubscriptionId;
27 | this.occurredAt = occurredAt;
28 | this.eventType = eventType;
29 | this.installationId = installationId;
30 | }
31 |
32 | static LocationInfo entry(String triggerSubscriptionId, String installationId) {
33 | return new LocationInfo(triggerSubscriptionId,
34 | LOCATION_EVENT_DATE_FORMAT.format(System.currentTimeMillis()),
35 | "entry",
36 | installationId
37 | );
38 | }
39 |
40 | static LocationInfo exit(String triggerSubscriptionId, String installationId) {
41 | return new LocationInfo(triggerSubscriptionId,
42 | LOCATION_EVENT_DATE_FORMAT.format(System.currentTimeMillis()),
43 | "exit",
44 | installationId
45 | );
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/connect-location/src/main/java/com/ifttt/location/Logger.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.location;
2 |
3 | import android.util.Log;
4 |
5 | final class Logger {
6 |
7 | private static final String TAG = "ConnectLocation";
8 | private static Boolean canLogEvent = false;
9 |
10 | static void setLoggingEnabled(Boolean enabled) {
11 | canLogEvent = enabled;
12 | }
13 |
14 | static void log(String message) {
15 | if (canLogEvent) {
16 | Log.d(TAG, message);
17 | }
18 | }
19 | static void warning(String message) {
20 | if (canLogEvent) {
21 | Log.w(TAG, message);
22 | }
23 | }
24 | static void error(String message) {
25 | if (canLogEvent) {
26 | Log.e(TAG, message);
27 | }
28 | }
29 |
30 | private Logger() {
31 | throw new AssertionError();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/connect-location/src/main/java/com/ifttt/location/OnEventUploadListener.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.location;
2 |
3 | import android.content.Context;
4 |
5 | /**
6 | * A listener interface for geo-fence uploads from {@link ConnectLocation#reportEvent(Context, double, double, OnEventUploadListener)}
7 | * that status of any given method call. You can use this interface to listen to whether a reported event was uploaded
8 | * or skipped.
9 | */
10 | public interface OnEventUploadListener {
11 |
12 | void onUploadEvent(String fenceKey, LocationEventUploader.EventType eventType);
13 |
14 | void onUploadSkipped(String fenceKey, String reason);
15 | }
16 |
--------------------------------------------------------------------------------
/connect-location/src/main/java/com/ifttt/location/RebootBroadcastReceiver.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.location;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.Context;
5 | import android.content.Intent;
6 |
7 | /**
8 | * A {@link BroadcastReceiver} that listens to system's {@link Intent#ACTION_BOOT_COMPLETED} broadcast, and make an
9 | * attempt to re-register geo-fences.
10 | */
11 | public final class RebootBroadcastReceiver extends BroadcastReceiver {
12 |
13 | @Override
14 | public void onReceive(Context context, Intent intent) {
15 | if (!intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
16 | return;
17 | }
18 |
19 | ConnectionRefresher.executeIfExists(context);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/connect-location/src/main/java/com/ifttt/location/RetrofitLocationApi.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.location;
2 |
3 | import java.util.List;
4 | import okhttp3.Interceptor;
5 | import okhttp3.OkHttpClient;
6 | import retrofit2.Call;
7 | import retrofit2.Retrofit;
8 | import retrofit2.converter.moshi.MoshiConverterFactory;
9 | import retrofit2.http.Body;
10 | import retrofit2.http.POST;
11 |
12 | interface RetrofitLocationApi {
13 | @POST("/v1/location_events")
14 | Call upload(@Body List locationInfoList);
15 |
16 | final class Client {
17 |
18 | final RetrofitLocationApi api;
19 |
20 | Client(Interceptor tokenInterceptor) {
21 | OkHttpClient client = new OkHttpClient.Builder().addInterceptor(tokenInterceptor).build();
22 | Retrofit retrofit = new Retrofit.Builder().client(client)
23 | .baseUrl("https://connectapi.ifttt.com")
24 | .addConverterFactory(MoshiConverterFactory.create())
25 | .build();
26 | api = retrofit.create(RetrofitLocationApi.class);
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/connect-location/src/main/java/com/ifttt/location/SharedPreferenceUserTokenCache.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.location;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import androidx.annotation.Nullable;
6 |
7 | final class SharedPreferenceUserTokenCache implements Cache {
8 |
9 | private static final String SHARED_PREF_NAME = "ifttt_user_token_store";
10 | private static final String PREF_KEY_USER_TOKEN = "ifttt_key_user_token";
11 |
12 | private final SharedPreferences sharedPreferences;
13 |
14 | SharedPreferenceUserTokenCache(Context context) {
15 | sharedPreferences = context.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
16 | }
17 |
18 | @Override
19 | public void write(String userToken) {
20 | sharedPreferences.edit().putString(PREF_KEY_USER_TOKEN, userToken).apply();
21 | }
22 |
23 | @Override
24 | @Nullable
25 | public String read() {
26 | return sharedPreferences.getString(PREF_KEY_USER_TOKEN, null);
27 | }
28 |
29 | @Override
30 | public void clear() {
31 | sharedPreferences.edit().remove(PREF_KEY_USER_TOKEN).apply();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/connect-location/src/main/java/com/ifttt/location/SharedPreferencesGeofenceCache.java:
--------------------------------------------------------------------------------
1 | package com.ifttt.location;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import com.ifttt.location.BackupGeofenceMonitor.MonitoredGeofence;
6 | import com.squareup.moshi.JsonAdapter;
7 | import com.squareup.moshi.Moshi;
8 | import com.squareup.moshi.Types;
9 | import java.io.IOException;
10 | import java.util.Collections;
11 | import java.util.Map;
12 |
13 | final class SharedPreferencesGeofenceCache implements Cache