Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@
package com.linkedin.android.shaky.app;

import android.app.Activity;
import android.app.Application;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.CheckBox;
import android.widget.Toast;

import com.linkedin.android.shaky.ActionConstants;

import java.util.Random;

public class ShakyDemo extends Activity {
Expand Down Expand Up @@ -70,5 +71,13 @@ public void onClick(View v) {
((ShakyApplication) getApplication()).getShaky().startFeedbackFlow();
}
});

findViewById(R.id.demo_bug_report_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
((ShakyApplication) getApplication()).getShaky()
.startFeedbackFlow(ActionConstants.ACTION_START_BUG_REPORT);
}
});
}
}
7 changes: 7 additions & 0 deletions shaky-sample/src/main/res/layout/activity_demo.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,11 @@
android:layout_height="wrap_content"
android:text="@string/manual_feedback_trigger"/>

<Button
android:id="@+id/demo_bug_report_button"
style="?attr/borderlessButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/manual_bug_report"/>

</LinearLayout>
1 change: 1 addition & 0 deletions shaky-sample/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<string name="app_name" translatable="false">Shaky</string>
<string name="shake_me" translatable="false">Shake me!</string>
<string name="manual_feedback_trigger" translatable="false">Manually start feedback</string>
<string name="manual_bug_report" translatable="false">Manually start bug report</string>
<string name="show_toast" translatable="false">Show Toast</string>
<string name="toast_text" translatable="false">This is a toast.</string>
<string name="christmas_theme" translatable="false">Use Christmas theme</string>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Copyright (C) 2016 LinkedIn Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.linkedin.android.shaky;

/**
* Class to hold actions that can be performed on shaky.
*/
public class ActionConstants {

public static final String ACTION_START_FEEDBACK_FLOW = "StartFeedbackFlow";
public static final String ACTION_START_BUG_REPORT = "StartBugReport";
public static final String ACTION_DIALOG_DISMISSED_BY_USER = "DialogDismissedByUser";
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public class FeedbackActivity extends AppCompatActivity {
static final String RES_MENU = "resMenu";
static final String SUBCATEGORY = "subcategory";
static final String THEME = "theme";
private static final String ACTION = "ACTION_THAT_STARTED_THE_ACTIVITY";
static final int MISSING_RESOURCE = 0;

private Uri imageUri;
Expand All @@ -59,11 +60,13 @@ public static Intent newIntent(@NonNull Context context,
@Nullable Uri screenshotUri,
@Nullable Bundle userData,
@MenuRes int resMenu,
@Nullable String actionThatStartedTheActivity,
@StyleRes int theme) {
Intent intent = new Intent(context, FeedbackActivity.class);
intent.putExtra(SCREENSHOT_URI, screenshotUri);
intent.putExtra(USER_DATA, userData);
intent.putExtra(RES_MENU, resMenu);
intent.putExtra(ACTION, actionThatStartedTheActivity);
intent.putExtra(THEME, theme);
return intent;
}
Expand All @@ -80,12 +83,20 @@ public void onCreate(Bundle savedInstanceState) {
imageUri = getIntent().getParcelableExtra(SCREENSHOT_URI);
userData = getIntent().getBundleExtra(USER_DATA);
resMenu = getIntent().getIntExtra(RES_MENU, FormFragment.DEFAULT_MENU);
String action = getIntent().getStringExtra(ACTION);

if (savedInstanceState == null) {
getSupportFragmentManager()
if (savedInstanceState == null && action != null) {
if (action.equals(ActionConstants.ACTION_START_FEEDBACK_FLOW)) {
getSupportFragmentManager()
.beginTransaction()
.add(R.id.shaky_fragment_container, SelectFragment.newInstance(customTheme))
.commit();
} else if (action.equals(ActionConstants.ACTION_START_BUG_REPORT)) {
startFormFragment(FeedbackItem.BUG, false);
if (imageUri != null) {
startDrawFragment();
}
}
}
}

Expand Down Expand Up @@ -120,38 +131,51 @@ public void onBackPressed() {
* Attaches this intent's extras to the fragment and transitions to the next fragment.
*
* @param fragment Fragment the fragment to swap to
* @param shouldAddToBackStack if the fragment should be added to backstack or not
*/
private void changeToFragment(@NonNull Fragment fragment) {
getSupportFragmentManager().beginTransaction()
private void changeToFragment(@NonNull Fragment fragment, boolean shouldAddToBackStack) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager()
.beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.replace(R.id.shaky_fragment_container, fragment)
.addToBackStack(null)
.commit();
.replace(R.id.shaky_fragment_container, fragment);

if (shouldAddToBackStack) {
fragmentTransaction.addToBackStack(null);
}

fragmentTransaction.commit();
}

/**
* Swap the view container for a form fragment, restores the previous fragment if one exists.
*
* @param feedbackType the FeedbackType for which to start the fragment
* @param shouldAddToBackStack if the fragment should be added to backstack or not
*/
private void startFormFragment(@FeedbackItem.FeedbackType int feedbackType) {
private void startFormFragment(
@FeedbackItem.FeedbackType int feedbackType,
boolean shouldAddToBackStack
) {
String title = getString(getTitleResId(feedbackType));
String hint = getString(getHintResId(feedbackType));
String[] subtypes = null;
if (feedbackType == FeedbackItem.BUG) {
subtypes = new String[]{Subcategories.Bug.CRASH, Subcategories.Bug.NON_FATAL};
}
changeToFragment(new FormFragment.Builder(title, hint)
.setScreenshotUri(imageUri)
.setMenu(resMenu)
.setSubtypes(subtypes != null ? R.array.shaky_bug_subcategories : null, subtypes)
.setTheme(customTheme)
.build());
.setScreenshotUri(imageUri)
.setMenu(resMenu)
.setSubtypes(subtypes != null ? R.array.shaky_bug_subcategories : null, subtypes)
.setTheme(customTheme)
.build(),
shouldAddToBackStack);
}

/**
* Swap the view container for a draw fragment, restores the previous fragment if one exists.
*/
private void startDrawFragment() {
changeToFragment(DrawFragment.newInstance(imageUri, customTheme));
changeToFragment(DrawFragment.newInstance(imageUri, customTheme), true);
}

private void setFeedbackType(@FeedbackItem.FeedbackType int feedbackType) {
Expand All @@ -167,7 +191,7 @@ public void onReceive(Context context, Intent intent) {

setFeedbackType(feedbackType);

startFormFragment(feedbackType);
startFormFragment(feedbackType, true);
if (imageUri != null && feedbackType == FeedbackItem.BUG) {
startDrawFragment();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@
*/
public class SendFeedbackDialog extends DialogFragment {

public static final String ACTION_START_FEEDBACK_FLOW = "StartFeedbackFlow";
public static final String ACTION_DIALOG_DISMISSED_BY_USER = "DialogDismissedByUser";
public static final String SHOULD_DISPLAY_SETTING_UI = "ShouldDisplaySettingUI";
public static final String CUSTOM_TITLE = "CustomTitle";
public static final String CUSTOM_MESSAGE = "CustomMessage";
Expand Down Expand Up @@ -89,14 +87,14 @@ public Dialog onCreateDialog(Bundle savedInstanceState) {
builder.setPositiveButton(R.string.shaky_dialog_positive, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(ACTION_START_FEEDBACK_FLOW);
Intent intent = new Intent(getActionToPerformOnPositiveClick());
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent);
}
});
builder.setNegativeButton(R.string.shaky_dialog_negative, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(ACTION_DIALOG_DISMISSED_BY_USER);
Intent intent = new Intent(ActionConstants.ACTION_DIALOG_DISMISSED_BY_USER);
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent);
}
});
Expand Down Expand Up @@ -142,4 +140,12 @@ public void onDismiss(DialogInterface dialog) {
handler.removeCallbacks(runnable);
}
}

/**
* Consumer can override this method to perform a custom action on dialog positive button click,
* by default it starts the feedback flow.
*/
public String getActionToPerformOnPositiveClick() {
return ActionConstants.ACTION_START_FEEDBACK_FLOW;
}
}
56 changes: 48 additions & 8 deletions shaky/src/main/java/com/linkedin/android/shaky/Shaky.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import android.app.Activity;
import android.app.Application;
import android.app.DialogFragment;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
Expand Down Expand Up @@ -63,6 +64,7 @@ public class Shaky implements ShakeDetector.Listener {
private Context appContext;
private long lastShakeTime;
private CollectDataTask collectDataTask;
private String actionThatStartedTheActivity;

Shaky(@NonNull Context context, @NonNull ShakeDelegate delegate, @Nullable ShakyFlowCallback callback) {
appContext = context.getApplicationContext();
Expand All @@ -73,8 +75,9 @@ public class Shaky implements ShakeDetector.Listener {
shakeDetector.setSensitivity(getDetectorSensitivityLevel());

IntentFilter filter = new IntentFilter();
filter.addAction(SendFeedbackDialog.ACTION_START_FEEDBACK_FLOW);
filter.addAction(SendFeedbackDialog.ACTION_DIALOG_DISMISSED_BY_USER);
filter.addAction(ActionConstants.ACTION_START_FEEDBACK_FLOW);
filter.addAction(ActionConstants.ACTION_START_BUG_REPORT);
filter.addAction(ActionConstants.ACTION_DIALOG_DISMISSED_BY_USER);
filter.addAction(FeedbackActivity.ACTION_END_FEEDBACK_FLOW);
filter.addAction(FeedbackActivity.ACTION_ACTIVITY_CLOSED_BY_USER);
filter.addAction(ShakySettingDialog.UPDATE_SHAKY_SENSITIVITY);
Expand Down Expand Up @@ -106,14 +109,33 @@ public static Shaky with(@NonNull Application application,
return shaky;
}

/**
* Start the shaky feedback flow manually.
*/
public void startFeedbackFlow() {
startFeedbackFlow(null);
}

/**
* Start shaky manually for a custom flow.
*
* @param action the flow to start. If null, starts the feedback flow by default. Otherwise
* starts the custom flow (if valid).
*/
public void startFeedbackFlow(@Nullable String action) {
if (shakyFlowCallback != null) {
shakyFlowCallback.onShakyStarted(ShakyFlowCallback.SHAKY_STARTED_MANUALLY);
}
if (!canStartFeedbackFlow()) {
return;
}

if (action != null) {
if (isValidStartAction(action)) {
actionThatStartedTheActivity = action;
}
} else {
actionThatStartedTheActivity = ActionConstants.ACTION_START_FEEDBACK_FLOW;
}
doStartFeedbackFlow();
}

Expand Down Expand Up @@ -163,6 +185,17 @@ private void stop() {
shakeDetector.stop();
}

/**
* Checks If the flow to start is a valid flow or not.
* @param action the provided flow to start
*
* @return true if the flow is a valid flow.
*/
private boolean isValidStartAction(String action) {
return action.equals(ActionConstants.ACTION_START_FEEDBACK_FLOW)
|| action.equals(ActionConstants.ACTION_START_BUG_REPORT);
}

@Override
public void hearShake() {
if (shakyFlowCallback != null) {
Expand All @@ -184,11 +217,15 @@ public void hearShake() {
}
arguments.putBoolean(SendFeedbackDialog.SHOULD_DISPLAY_SETTING_UI, delegate.shouldShowSettingsUI());
arguments.putInt(ShakySettingDialog.SHAKY_CURRENT_SENSITIVITY, delegate.getSensitivityLevel());
SendFeedbackDialog sendFeedbackDialog = new SendFeedbackDialog();
sendFeedbackDialog.setArguments(arguments);
if (delegate.getCustomDialog() != null) {
delegate.getCustomDialog().show(activity.getFragmentManager(), CUSTOM_DIALOG_TAG);
DialogFragment customDialog = delegate.getCustomDialog();
if (delegate.getCustomDialog() instanceof SendFeedbackDialog) {
customDialog.setArguments(arguments);
}
customDialog.show(activity.getFragmentManager(), CUSTOM_DIALOG_TAG);
} else {
SendFeedbackDialog sendFeedbackDialog = new SendFeedbackDialog();
sendFeedbackDialog.setArguments(arguments);
sendFeedbackDialog.show(activity.getFragmentManager(), SEND_FEEDBACK_TAG);
}
if (shakyFlowCallback != null) {
Expand Down Expand Up @@ -268,11 +305,13 @@ private BroadcastReceiver createReceiver() {
return new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (SendFeedbackDialog.ACTION_START_FEEDBACK_FLOW.equals(intent.getAction())) {
if (ActionConstants.ACTION_START_FEEDBACK_FLOW.equals(intent.getAction())
|| ActionConstants.ACTION_START_BUG_REPORT.equals(intent.getAction())) {
if (activity != null) {
actionThatStartedTheActivity = intent.getAction();
doStartFeedbackFlow();
}
} else if (SendFeedbackDialog.ACTION_DIALOG_DISMISSED_BY_USER.equals(intent.getAction())
} else if (ActionConstants.ACTION_DIALOG_DISMISSED_BY_USER.equals(intent.getAction())
|| FeedbackActivity.ACTION_ACTIVITY_CLOSED_BY_USER.equals(intent.getAction())) {
if (shakyFlowCallback != null) {
shakyFlowCallback.onShakyFinished(ShakyFlowCallback.SHAKY_FINISHED_BY_USER);
Expand Down Expand Up @@ -326,6 +365,7 @@ private void startFeedbackActivity(@NonNull Result result) {
result.getScreenshotUri(),
result.getData(),
delegate.resMenu,
actionThatStartedTheActivity,
delegate.getTheme() != null ? delegate.getTheme() : FeedbackActivity.MISSING_RESOURCE);
activity.startActivity(intent);

Expand Down
Loading