diff --git a/android-app-core/src/main/java/org/solovyev/android/calculator/AndroidCalculatorDisplayView.java b/android-app-core/src/main/java/org/solovyev/android/calculator/AndroidCalculatorDisplayView.java index d35fdd4b..2e1e6954 100644 --- a/android-app-core/src/main/java/org/solovyev/android/calculator/AndroidCalculatorDisplayView.java +++ b/android-app-core/src/main/java/org/solovyev/android/calculator/AndroidCalculatorDisplayView.java @@ -10,6 +10,7 @@ import android.content.SharedPreferences; import android.graphics.Color; import android.os.Handler; import android.preference.PreferenceManager; +import android.support.v4.app.FragmentActivity; import android.text.Html; import android.util.AttributeSet; import android.util.TypedValue; @@ -183,7 +184,11 @@ public class AndroidCalculatorDisplayView extends AutoResizeTextView implements setTextSize(TypedValue.COMPLEX_UNIT_SP, getResources().getDimension(R.dimen.cpp_display_text_size_mobile)); } - this.setOnClickListener(new CalculatorDisplayOnClickListener(context)); + if (context instanceof FragmentActivity) { + this.setOnClickListener(new CalculatorDisplayOnClickListener((FragmentActivity) context)); + } else { + throw new IllegalArgumentException("Must be fragment activity, got " + context.getClass()); + } } this.initialized = true; diff --git a/android-app-core/src/main/java/org/solovyev/android/calculator/CalculatorButtons.java b/android-app-core/src/main/java/org/solovyev/android/calculator/CalculatorButtons.java index 43e892ff..97bfdaa0 100644 --- a/android-app-core/src/main/java/org/solovyev/android/calculator/CalculatorButtons.java +++ b/android-app-core/src/main/java/org/solovyev/android/calculator/CalculatorButtons.java @@ -15,7 +15,7 @@ import jscl.AngleUnit; import jscl.NumeralBase; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.solovyev.android.AViews; +import org.solovyev.android.Views; import org.solovyev.android.calculator.core.R; import org.solovyev.android.calculator.model.AndroidCalculatorEngine; import org.solovyev.android.calculator.view.AngleUnitsButton; @@ -43,7 +43,7 @@ public final class CalculatorButtons { final float textSize = root.getContext().getResources().getDimension(R.dimen.cpp_keyboard_button_text_size_mobile); - AViews.processViewsOfType(root, DragButton.class, new AViews.ViewProcessor() { + Views.processViewsOfType(root, DragButton.class, new Views.ViewProcessor() { @Override public void process(@NotNull DragButton button) { button.setTextSize(TypedValue.COMPLEX_UNIT_DIP, textSize); @@ -68,11 +68,11 @@ public final class CalculatorButtons { @NotNull Activity activity) { preferences = preferences == null ? PreferenceManager.getDefaultSharedPreferences(activity) : preferences; - final boolean large = AViews.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE, activity.getResources().getConfiguration()) && + final boolean large = Views.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE, activity.getResources().getConfiguration()) && CalculatorPreferences.Gui.getLayout(preferences) != CalculatorPreferences.Gui.Layout.main_calculator_mobile; if (!large) { - if (AViews.getScreenOrientation(activity) == Configuration.ORIENTATION_PORTRAIT + if (Views.getScreenOrientation(activity) == Configuration.ORIENTATION_PORTRAIT || !CalculatorPreferences.Gui.autoOrientation.getPreference(preferences)) { final DragButton equalsButton = (DragButton)activity.findViewById(R.id.cpp_button_equals); diff --git a/android-app-core/src/main/java/org/solovyev/android/calculator/CalculatorDisplayOnClickListener.java b/android-app-core/src/main/java/org/solovyev/android/calculator/CalculatorDisplayOnClickListener.java index 7e9f9c48..f886fc80 100644 --- a/android-app-core/src/main/java/org/solovyev/android/calculator/CalculatorDisplayOnClickListener.java +++ b/android-app-core/src/main/java/org/solovyev/android/calculator/CalculatorDisplayOnClickListener.java @@ -1,6 +1,6 @@ package org.solovyev.android.calculator; -import android.content.Context; +import android.support.v4.app.FragmentActivity; import android.view.View; import org.jetbrains.annotations.NotNull; import org.solovyev.android.menu.ContextMenuBuilder; @@ -17,10 +17,10 @@ import java.util.List; public class CalculatorDisplayOnClickListener implements View.OnClickListener { @NotNull - private final Context context; + private final FragmentActivity activity; - public CalculatorDisplayOnClickListener(@NotNull Context context) { - this.context = context; + public CalculatorDisplayOnClickListener(@NotNull FragmentActivity activity) { + this.activity = activity; } @Override @@ -39,13 +39,13 @@ public class CalculatorDisplayOnClickListener implements View.OnClickListener { } if (!filteredMenuItems.isEmpty()) { - ContextMenuBuilder.newInstance(context, ListContextMenu.newInstance(filteredMenuItems)).create(displayViewState).show(); + ContextMenuBuilder.newInstance(activity, "display-menu", ListContextMenu.newInstance(filteredMenuItems)).build(displayViewState).show(); } } else { final String errorMessage = displayViewState.getErrorMessage(); if (errorMessage != null) { - Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_evaluation_error, errorMessage, context); + Locator.getInstance().getCalculator().fireCalculatorEvent(CalculatorEventType.show_evaluation_error, errorMessage, activity); } } } diff --git a/android-app-core/src/main/java/org/solovyev/android/calculator/CalculatorPreferences.java b/android-app-core/src/main/java/org/solovyev/android/calculator/CalculatorPreferences.java index 5737d276..2bd4c409 100644 --- a/android-app-core/src/main/java/org/solovyev/android/calculator/CalculatorPreferences.java +++ b/android-app-core/src/main/java/org/solovyev/android/calculator/CalculatorPreferences.java @@ -4,7 +4,8 @@ import android.content.SharedPreferences; import jscl.AngleUnit; import jscl.NumeralBase; import org.jetbrains.annotations.NotNull; -import org.solovyev.android.AndroidUtils; +import org.solovyev.android.Android; +import org.solovyev.android.DeviceModel; import org.solovyev.android.calculator.math.MathType; import org.solovyev.android.calculator.model.AndroidCalculatorEngine; import org.solovyev.android.calculator.plot.PlotLineColor; @@ -19,6 +20,10 @@ import org.solovyev.android.view.VibratorContainer; import java.text.DecimalFormatSymbols; import java.util.Locale; +import static org.solovyev.android.Android.isPhoneModel; +import static org.solovyev.android.DeviceModel.samsung_galaxy_s; +import static org.solovyev.android.DeviceModel.samsung_galaxy_s_2; + /** * User: serso * Date: 4/20/12 @@ -166,7 +171,7 @@ public final class CalculatorPreferences { } if (!AndroidCalculatorEngine.Preferences.multiplicationSign.isSet(preferences)) { - if (AndroidUtils.isPhoneModel(AndroidUtils.PhoneModel.samsung_galaxy_s) || AndroidUtils.isPhoneModel(AndroidUtils.PhoneModel.samsung_galaxy_s_2)) { + if (isPhoneModel(samsung_galaxy_s) || isPhoneModel(samsung_galaxy_s_2)) { // workaround ofr samsung galaxy s phones AndroidCalculatorEngine.Preferences.multiplicationSign.putPreference(preferences, "*"); } diff --git a/android-app-onscreen/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenService.java b/android-app-onscreen/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenService.java index 2273bc02..ec88d04a 100644 --- a/android-app-onscreen/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenService.java +++ b/android-app-onscreen/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenService.java @@ -11,7 +11,7 @@ import android.util.DisplayMetrics; import android.view.WindowManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.solovyev.android.AViews; +import org.solovyev.android.Views; import org.solovyev.android.calculator.CalculatorDisplayViewState; import org.solovyev.android.calculator.CalculatorEditorViewState; import org.solovyev.android.calculator.Locator; @@ -65,7 +65,7 @@ public class CalculatorOnscreenService extends Service implements ExternalCalcul twoThirdWidth = Math.min(twoThirdWidth, twoThirdHeight); twoThirdHeight = Math.max(twoThirdWidth, getHeight(twoThirdWidth)); - final int baseWidth = AViews.toPixels(dm, 300); + final int baseWidth = Views.toPixels(dm, 300); final int width0 = Math.min(twoThirdWidth, baseWidth); final int height0 = Math.min(twoThirdHeight, getHeight(baseWidth)); diff --git a/android-app-onscreen/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenStartActivity.java b/android-app-onscreen/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenStartActivity.java index 484e294d..b45139d8 100644 --- a/android-app-onscreen/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenStartActivity.java +++ b/android-app-onscreen/src/main/java/org/solovyev/android/calculator/onscreen/CalculatorOnscreenStartActivity.java @@ -6,7 +6,7 @@ import android.content.SharedPreferences; import android.os.Bundle; import android.preference.PreferenceManager; import org.jetbrains.annotations.NotNull; -import org.solovyev.android.AndroidUtils; +import org.solovyev.android.Android; import org.solovyev.android.App; import org.solovyev.android.calculator.AbstractFixableError; import org.solovyev.android.calculator.CalculatorPreferences; @@ -22,7 +22,7 @@ public class CalculatorOnscreenStartActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (AndroidUtils.isComponentEnabled(this, CalculatorOnscreenStartActivity.class)) { + if (Android.isComponentEnabled(this, CalculatorOnscreenStartActivity.class)) { final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); if (!CalculatorPreferences.OnscreenCalculator.removeIconDialogShown.getPreference(prefs)) { diff --git a/android-app/pom.xml b/android-app/pom.xml index a66d7bc6..e50157ac 100644 --- a/android-app/pom.xml +++ b/android-app/pom.xml @@ -114,7 +114,6 @@ com.google.guava guava - 11.0.2 diff --git a/android-app/res/layout/admob_pref.xml b/android-app/res/layout/admob_pref.xml deleted file mode 100644 index 15ddedd1..00000000 --- a/android-app/res/layout/admob_pref.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - diff --git a/android-app/res/xml/preferences.xml b/android-app/res/xml/preferences.xml index 3b28927a..7111519a 100644 --- a/android-app/res/xml/preferences.xml +++ b/android-app/res/xml/preferences.xml @@ -8,6 +8,6 @@ a:summary="@string/c_calc_ad_free_summary" a:defaultValue="false"/> - + \ No newline at end of file diff --git a/android-app/res/xml/preferences_appearance.xml b/android-app/res/xml/preferences_appearance.xml index 7bfb81d7..6aa38432 100644 --- a/android-app/res/xml/preferences_appearance.xml +++ b/android-app/res/xml/preferences_appearance.xml @@ -6,7 +6,7 @@ - + - + - + - + - + parent, View view, final int position, long id) { final CalculatorHistoryState historyState = (CalculatorHistoryState) parent.getItemAtPosition(position); - final Context context = getActivity(); + final FragmentActivity activity = getActivity(); final HistoryItemMenuData data = new HistoryItemMenuData(historyState, adapter); @@ -160,8 +160,8 @@ public abstract class AbstractCalculatorHistoryFragment extends SherlockListFrag menuItems.remove(HistoryItemMenuItem.copy_result); } - final ContextMenuBuilder menuBuilder = ContextMenuBuilder.newInstance(context, ListContextMenu.newInstance(menuItems)); - menuBuilder.create(data).show(); + final ContextMenuBuilder menuBuilder = ContextMenuBuilder.newInstance(activity, "history-menu", ListContextMenu.newInstance(menuItems)); + menuBuilder.build(data).show(); return true; } @@ -220,7 +220,7 @@ public abstract class AbstractCalculatorHistoryFragment extends SherlockListFrag historyState.setSaved(true); if ( Collections.contains(historyState, Locator.getInstance().getHistory().getSavedHistory(), new Equalizer() { @Override - public boolean equals(@Nullable CalculatorHistoryState first, @Nullable CalculatorHistoryState second) { + public boolean areEqual(@Nullable CalculatorHistoryState first, @Nullable CalculatorHistoryState second) { return first != null && second != null && first.getTime() == second.getTime() && first.getDisplayState().equals(second.getDisplayState()) && diff --git a/android-app/src/main/java/org/solovyev/android/calculator/math/edit/AbstractMathEntityListFragment.java b/android-app/src/main/java/org/solovyev/android/calculator/math/edit/AbstractMathEntityListFragment.java index 949cefeb..98ef92e6 100644 --- a/android-app/src/main/java/org/solovyev/android/calculator/math/edit/AbstractMathEntityListFragment.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/math/edit/AbstractMathEntityListFragment.java @@ -51,7 +51,7 @@ public abstract class AbstractMathEntityListFragment exten public static final String MATH_ENTITY_CATEGORY_EXTRA_STRING = "org.solovyev.android.calculator.CalculatorVarsActivity_math_entity_category"; - protected final static List acceptableChars = Arrays.asList(Strings.toObject("1234567890abcdefghijklmnopqrstuvwxyzйцукенгшщзхъфывапролджэячсмитьбюё_".toCharArray())); + protected final static List acceptableChars = Arrays.asList(Strings.toObjects("1234567890abcdefghijklmnopqrstuvwxyzйцукенгшщзхъфывапролджэячсмитьбюё_".toCharArray())); /* @@ -124,8 +124,8 @@ public abstract class AbstractMathEntityListFragment exten final List> menuItems = getMenuItemsOnLongClick(item); if (!menuItems.isEmpty()) { - final ContextMenuBuilder, T> menuBuilder = ContextMenuBuilder.newInstance(AbstractMathEntityListFragment.this.getActivity(), ListContextMenu.newInstance(menuItems)); - menuBuilder.create(item).show(); + final ContextMenuBuilder, T> menuBuilder = ContextMenuBuilder.newInstance(AbstractMathEntityListFragment.this.getActivity(), "math-entity-menu", ListContextMenu.newInstance(menuItems)); + menuBuilder.build(item).show(); } return true; diff --git a/android-app/src/main/java/org/solovyev/android/calculator/plot/AbstractCalculatorPlotFragment.java b/android-app/src/main/java/org/solovyev/android/calculator/plot/AbstractCalculatorPlotFragment.java index adc7f953..02e63e44 100644 --- a/android-app/src/main/java/org/solovyev/android/calculator/plot/AbstractCalculatorPlotFragment.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/plot/AbstractCalculatorPlotFragment.java @@ -16,8 +16,8 @@ import com.actionbarsherlock.view.MenuInflater; import com.actionbarsherlock.view.MenuItem; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.solovyev.android.AThreads; -import org.solovyev.android.AndroidUtils; +import org.solovyev.android.Android; +import org.solovyev.android.Threads; import org.solovyev.android.calculator.*; import org.solovyev.android.calculator.model.AndroidCalculatorEngine; import org.solovyev.android.menu.AMenuItem; @@ -153,19 +153,19 @@ public abstract class AbstractCalculatorPlotFragment extends CalculatorFragment } private void updateChart(@NotNull final PlotData plotData, @Nullable final SherlockFragmentActivity activity) { - AThreads.tryRunOnUiThread(activity, new Runnable() { - @Override - public void run() { - createChart(plotData); + Threads.tryRunOnUiThread(activity, new Runnable() { + @Override + public void run() { + createChart(plotData); - final View view = getView(); - if (view != null) { - createGraphicalView(view, plotData); - } + final View view = getView(); + if (view != null) { + createGraphicalView(view, plotData); + } - activity.invalidateOptionsMenu(); - } - }); + activity.invalidateOptionsMenu(); + } + }); } protected abstract void onError(); @@ -309,7 +309,7 @@ public abstract class AbstractCalculatorPlotFragment extends CalculatorFragment final File externalFilesDir = getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES); if (externalFilesDir != null) { final String path = externalFilesDir.getPath(); - AndroidUtils.saveBitmap(screenshot, path, screenShotFileName); + Android.saveBitmap(screenshot, path, screenShotFileName); Locator.getInstance().getNotifier().showMessage(R.string.cpp_plot_screenshot_saved, MessageType.info, path + "/" + screenShotFileName); } else { Locator.getInstance().getNotifier().showMessage(R.string.cpp_plot_unable_to_save_screenshot, MessageType.error); diff --git a/android-app/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotFunctionsActivity.java b/android-app/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotFunctionsActivity.java index 79855532..f8054011 100644 --- a/android-app/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotFunctionsActivity.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotFunctionsActivity.java @@ -10,7 +10,7 @@ import org.solovyev.android.calculator.CalculatorListFragment; import org.solovyev.android.calculator.Locator; import org.solovyev.android.calculator.R; import org.solovyev.android.fragments.FragmentUtils; -import org.solovyev.android.list.ListItemArrayAdapter; +import org.solovyev.android.list.ListItemAdapter; import java.util.List; @@ -48,7 +48,7 @@ public class CalculatorPlotFunctionsActivity extends SherlockFragmentActivity { } }); - ListItemArrayAdapter.createAndAttach(getListView(), this.getActivity(), items); + ListItemAdapter.createAndAttach(this, items); } } } diff --git a/android-app/src/main/java/org/solovyev/android/calculator/plot/TouchHandler.java b/android-app/src/main/java/org/solovyev/android/calculator/plot/TouchHandler.java index 40aab6e5..c9920180 100755 --- a/android-app/src/main/java/org/solovyev/android/calculator/plot/TouchHandler.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/plot/TouchHandler.java @@ -5,7 +5,7 @@ package org.solovyev.android.calculator.plot; import android.view.MotionEvent; import android.view.VelocityTracker; import org.jetbrains.annotations.NotNull; -import org.solovyev.android.AViews; +import org.solovyev.android.Views; class TouchHandler { @@ -43,7 +43,7 @@ class TouchHandler { float x = event.getX(); float y = event.getY(); - int pointerCount = AViews.getPointerCountFromMotionEvent(event); + int pointerCount = Views.getPointerCountFromMotionEvent(event); switch (action) { case MotionEvent.ACTION_DOWN: @@ -63,7 +63,7 @@ class TouchHandler { velocityTracker.addMovement(event); listener.onTouchMove(x, y); } else if (pointerCount == 2) { - listener.onTouchZoomMove(x, y, AViews.getXFromMotionEvent(event, 1), AViews.getYFromMotionEvent(event, 1)); + listener.onTouchZoomMove(x, y, Views.getXFromMotionEvent(event, 1), Views.getYFromMotionEvent(event, 1)); } break; @@ -75,7 +75,7 @@ class TouchHandler { case MotionEvent.ACTION_POINTER_DOWN: if (pointerCount == 2) { - listener.onTouchZoomDown(x, y, AViews.getXFromMotionEvent(event, 1), AViews.getYFromMotionEvent(event, 1)); + listener.onTouchZoomDown(x, y, Views.getXFromMotionEvent(event, 1), Views.getYFromMotionEvent(event, 1)); } break; diff --git a/android-app/src/main/java/org/solovyev/android/calculator/preferences/CalculatorPreferencesActivity.java b/android-app/src/main/java/org/solovyev/android/calculator/preferences/CalculatorPreferencesActivity.java index dc80d0e5..c90def7d 100644 --- a/android-app/src/main/java/org/solovyev/android/calculator/preferences/CalculatorPreferencesActivity.java +++ b/android-app/src/main/java/org/solovyev/android/calculator/preferences/CalculatorPreferencesActivity.java @@ -21,7 +21,7 @@ import net.robotmedia.billing.ResponseCode; import net.robotmedia.billing.helper.AbstractBillingObserver; import net.robotmedia.billing.model.Transaction; import org.jetbrains.annotations.NotNull; -import org.solovyev.android.AActivities; +import org.solovyev.android.Activities; import org.solovyev.android.App; import org.solovyev.android.ads.AdsController; import org.solovyev.android.calculator.*; @@ -156,7 +156,7 @@ public class CalculatorPreferencesActivity extends SherlockPreferenceActivity im case PURCHASED: adFreePreference.setEnabled(false); // restart activity to disable ads - AActivities.restartActivity(this); + Activities.restartActivity(this); break; case CANCELLED: adFreePreference.setEnabled(true); diff --git a/core/pom.xml b/core/pom.xml index ed94a327..8873b5b3 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -22,6 +22,11 @@ common-text + + org.solovyev + common-listeners + + junit junit @@ -57,6 +62,12 @@ simple-xml + + commons-cli + commons-cli + 1.2 + + diff --git a/core/src/main/java/org/solovyev/acraanalyzer/AcraAnalyzer.java b/core/src/main/java/org/solovyev/acraanalyzer/AcraAnalyzer.java new file mode 100644 index 00000000..d4bcbd6f --- /dev/null +++ b/core/src/main/java/org/solovyev/acraanalyzer/AcraAnalyzer.java @@ -0,0 +1,168 @@ +package org.solovyev.acraanalyzer; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; +import org.apache.commons.cli.*; +import org.solovyev.common.text.Strings; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.*; + +import static org.solovyev.common.collections.Collections.getFirstCollectionElement; + +/** + * User: serso + * Date: 6/12/13 + * Time: 10:08 PM + */ +public final class AcraAnalyzer { + + private static final String NEW_LINE = System.getProperty("line.separator"); + + public static void main(String[] args) throws ParseException { + final Options options = new Options(); + options.addOption("path", true, "Path to the ACRA reports"); + + final CommandLineParser parser = new GnuParser(); + final CommandLine cmd = parser.parse(options, args); + final String path = cmd.getOptionValue("path"); + if (Strings.isEmpty(path)) { + throw new IllegalArgumentException("Path should be specified"); + } else { + final Multimap reports = ArrayListMultimap.create(100, 20); + scanFiles(path, reports); + final List> sortedReports = new ArrayList>(reports.size()); + for (String stackTrace : reports.keys()) { + sortedReports.add(reports.get(stackTrace)); + } + Collections.sort(sortedReports, new Comparator>() { + @Override + public int compare(Collection lhs, Collection rhs) { + if (lhs.size() == rhs.size()) { + return 0; + } else if (lhs.size() < rhs.size()) { + return 1; + } else { + return -1; + } + } + }); + + for (Collection sortedReport : sortedReports) { + final AcraReport report = getFirstCollectionElement(sortedReport); + System.out.println("Count: " + sortedReport.size()); + System.out.println("App version: " + report.appVersion); + System.out.println("Stack trace: " + report.stackTrace); + } + } + } + + private static void scanFiles(String path, Multimap reports) { + final File directory = new File(path); + if (directory.isDirectory()) { + scanFiles(directory, reports); + } + } + + private static void scanFiles(File directory, Multimap reports) { + final File[] files = directory.listFiles(); + if (files != null) { + for (File file : files) { + if (file.isDirectory()) { + scanFiles(file, reports); + } else { + analyzeFile(file, reports); + } + } + } + } + + private static void analyzeFile(File file, Multimap reports) { + final AcraReport report = readReport(file); + if (!Strings.isEmpty(report.stackTrace)) { + reports.put(report.stackTrace, report); + } + } + + private static AcraReport readReport(File file) { + final AcraReport result = new AcraReport(); + + Scanner scanner = null; + + try { + scanner = new Scanner(file); + while (scanner.hasNextLine()) { + final String line = scanner.nextLine(); + if (line.startsWith("STACK_TRACE")) { + result.stackTrace = readStackTrace(line.substring("STACK_TRACE=".length()), scanner); + break; + } else if (line.startsWith("ANDROID_VERSION")) { + result.androidVersion = line.substring("ANDROID_VERSION=".length()); + } else if (line.startsWith("APP_VERSION_NAME")) { + result.appVersion = line.substring("APP_VERSION_NAME=".length()); + } else if (line.startsWith("BRAND")) { + result.brand = line.substring("BRAND=".length()); + } else if (line.startsWith("USER_COMMENT")) { + result.userComment = line.substring("USER_COMMENT=".length()); + } else if (line.startsWith("PHONE_MODEL")) { + result.phoneModel = line.substring("PHONE_MODEL=".length()); + } + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } finally { + if (scanner != null) { + scanner.close(); + } + } + + return result; + } + + private static String readStackTrace(String firstLine, Scanner scanner) { + final StringBuilder sb = new StringBuilder(); + sb.append(firstLine.trim()).append(newLine()); + + while (scanner.hasNextLine()) { + final String line = scanner.nextLine().trim(); + if (line.startsWith("at")) { + sb.append(line).append(newLine()); + } else { + break; + } + } + + return sb.toString(); + } + + private static final class AcraReport { + private String userComment; + private String phoneModel; + private String brand; + private String appVersion; + private String androidVersion; + private String stackTrace = ""; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + AcraReport that = (AcraReport) o; + + if (!stackTrace.equals(that.stackTrace)) return false; + + return true; + } + + @Override + public int hashCode() { + return stackTrace.hashCode(); + } + } + + public static String newLine() { + return NEW_LINE; + } +} diff --git a/pom.xml b/pom.xml index c7f0b5ed..7172017d 100644 --- a/pom.xml +++ b/pom.xml @@ -33,8 +33,8 @@ UTF-8 - 1.0.7-SNAPSHOT - 1.0.4-SNAPSHOT + 1.1.1-SNAPSHOT + 1.0.4 @@ -79,6 +79,12 @@ ${common.version} + + org.solovyev + common-listeners + ${common.version} + + org.solovyev.android android-common-core @@ -209,6 +215,12 @@ com.google.guava guava 11.0.2 + + + com.google.code.findbugs + jsr305 + + @@ -237,7 +249,7 @@ com.electriccloud javac2-maven-plugin - 1.0.1 + 1.0.2 @NotNull Instrumentation @@ -295,7 +307,7 @@ - 15 + 17