futurice / freesound-android Goto Github PK
View Code? Open in Web Editor NEWUnofficial Android client for the Freesound Project
License: Apache License 2.0
Unofficial Android client for the Freesound Project
License: Apache License 2.0
Common dependency versions, such as those used by the Android support library dependencies, should be moved into the project.ext
for reuse.
Includes:
Evidently, having Leak Canary in the app would be useful to find memory leaks. This should only be in the debug build type.
The search screen needs to have a mechanism to indicate that a search is currently in progress.
We need an nice looking app icon!
Types of Observables in Rx 2 does not help with reasoning about if an observable emits any event on subscription and if it ever completes.
How about using those to suffixes: OnceAndStream
and Stream
.
Once
we do not need to as Single
and Maybe
will give us this information.
Thanks!
The Views created by the RecyclerViewAdapter will stay bound to their ViewModels even when the host Activity/Fragment is paused/stopped. This means that changes may still be propagated to Views when it is unnecessary to do so. In terms of data binding; Views should be subject to the same lifecycle as their host Activity/Fragment.
Since I am not in Futurice anymore I created my own clientId and clientSecret. There is a problem though for the "users/{user}/" call, the user is hardcoded in the app to SpiceProgram and I have my own user, so this won't work. If I change it to my user name it works but then I don't see the awesome spice program chillicorn avatar anymore :´´´´´´´(
What should we do?
Hi, i played with code and observed that "handleResults" method in SearchFragment is executed 2 times consecutive when searching. It means that "search results stream" in data model emit data 2 times. Is it normal? This issue make difficult adding additional functionality regarding that stream.
Thanks!
The following error causes the search activity's search capability to no longer function:
10-18 22:57:57.815 2738-2925/com.futurice.freesound.debug E/SearchViewModel: Error when setting search term
It would seem that the onError
event is propagated too far, causing the searchQuery stream Observable to error and no longer accept requests.
This can occur when the search API call has a network failure. The app should instead be able to accept future queries.
Espresso tests should be added for the search feature.
Hi,
I use your application as reference.
You/We have View Widgets and Injected dependencies that are annotated with @nullable.
@nullable annotation act like in Kotlin "?". It means that we need to write use case to deal with both cases when something can be null or not. In other words its part of business logic.
Lets analyze View Widget:
@Nullable @BindView(id.search_view) SearchView searchView;
If is annotated with @nullable then probably there are some business logic regarding this widget where in some cases it can be null and in other not.
The same are with injected dependencies.
Analyzing the code we see that only case when widgets and dependencies can be null is case when something goes wrong with Butterknife and Dagger but its have nothing related to business logic.
I think that both widgets and dependencies needed to be annotated with @nonnull because there is no use case when they can be null and run specific logic.
All these @nullable annotations make class full of "non null" checks to fix "lint" warnings.
Probably you put @nullable instead of @nonnull to fix "lint" warning that suggest to initialize the property.
Maybe in case with generated initializations (Butterknife, Dagger ...) we no need to use @NonNull/@nullable annotations at all.
Thanks for helping me understand!
There is no .travis.yml
file in the root directory
It will make in the future easier to add new ways to consume events from retrofit.
How is it possible to make a communication between these too?
Hi.
I use your project as main reference to my production app and now i need to implement persistence (local database).
You not add it yet (but i hope you will add soon) and i want to ask how would you will implement it in the future.
How i see it:
If we have API and it is consumed directly in DataModel then for local database we also need to have an Datasource/Repository class (for managing local database) that will be also consumed in DataModel directly.
And if we need to interact API and database (for example to save remote data in local database) we will need to do it in DataModel.
Or?
We need to have an additional repository class/es that will manage both API and local database.
And DataModel will consume only that repository class/es. (More like traditional repository pattern that we find in most examples).
P.S. Yesterday was released RxRelay with RxJava2 support, how you look at replacing Subjects with RxRelay?
Thanks and Sorry for these stupid questions!
The search screen needs to have a mechanism to report an error in the event of a failed API call - this does not include when the search gives no results. A Snackbar would be suitable.
Retrofit 2 has a better way to use Interceptors but it is now harder to test them.
There is a way how okhttp tests it.
Due to plugin incompatibilities, I've disabled the SonarQube check in the Travis builds as a part of #131
Once the issues are resolved, we should re-instate it. The following links describe and track the issue:
Once the app is open sourced, then we should add either Travis-CI or some other CI service to verify commits.
Traditionally the convention for naming classes was feature + component, for instance SearchFragment
, which made sense because the packaging was made by component. In this project the packaging is done by feature which makes me wonder if the naming should be reversed. It doesn't seem very useful to have the word Search
in the beginning of most of the classes inside the search package, it is redundant and reduces the potential of autocompletion tool since we have to type Search
always first when all the classes available inside the search package are search feature related.
Wouldn't be better to type Fragment
and get all the fragments available inside the search feature?
First of all Thanks for such a clean project. I was looking very long fora good implementation of MVVM with RxJava and this project is the best that i found!
You have plans to complete him with some more complex things like permissions, services, db, orientation changes... I mean their position in MVVM architecture.
Thanks!
Stetho should only be used in release builds. Any change request should await the delivery of #21 to add debug/release variants.
This class has only one test!
The search result item should show the total running time of the sound. I picture this being an semi-transparent overlay on the waveform view.
Hi, from what i read recently sounds that if we want to use CompositeDisposable then we need to use subscribeWith and DisposableObserver (and other consumers for each (single, maybe, completable ...)).
You tested if your current implementation works?
Error:
Error:(56, 0) Cannot convert the provided notation to a File or URI: [./proguard-rules/android-support-rules.pro, ./proguard-rules/autovalue-rules.pro, ./proguard-rules/okhttp3-rules.pro, ./proguard-rules/picasso-rules.pro, ./proguard-rules/retrofit2-rules.pro, ./proguard-rules/retrolambda-rules.pro, ./proguard-rules/rxjava2-rules.pro, ./proguard-rules/okio-rules.pro, ./proguard-rules/picasso-rules.pro].
The following types/formats are supported:
Line:
proguardFiles getDefaultProguardFile('proguard-android.txt'), releaseProguardFiles
P.S. If comment this line build work :)
Thanks
Ubuntu 16.04
Currently the search results only return the first page. We should instead support the paging from the underlying API results.
SonarQube supports free hosting for open source projects: https://about.sonarqube.com/ we should use this and integrate it into our Travis PR and merge builds and ideally show the analysis on the associated PR.
We currently have no tests for our API model JSON parsing, meaning that changes to mapping libraries etc cannot be verified without running the app.
We should have tests for the basic parsing of the model objects.
There is a memory leak caused by the subscription of the view holders to its respective view models. The problem is that the 'unbind' happens only in onViewRecycled() method which is not called when the user navigates away from the recycler view.
I've tried to use onViewDetachedFromWindow(ViewHolder) but it is also not called when navigating away.
Our view code (Activity, Fragment, View) is looking quite messy in regards to the bind of view components. We should use ButterKnife to bind Views.
Change existing Android Log
calls to Timber calls.
It would be nice to come up with another list element to show case how to deal with different types of items in a list. Any ideas?
Caused by: java.lang.NullPointerException: Cannot return null from a non-@Nullable @Provides method at dagger.internal.Preconditions.checkNotNull(Preconditions.java:47) at com.futurice.freesound.app.module.ConfigModule_ProvideApiModuleApiTokenConfigFactory.get(ConfigModule_ProvideApiModuleApiTokenConfigFactory.java:16) at com.futurice.freesound.app.module.ConfigModule_ProvideApiModuleApiTokenConfigFactory.get(ConfigModule_ProvideApiModuleApiTokenConfigFactory.java:7) at dagger.internal.DoubleCheck.get(DoubleCheck.java:46) at com.futurice.freesound.app.module.ApiModule_ProvideApiInterceptorFactory.get(ApiModule_ProvideApiInterceptorFactory.java:25) at com.futurice.freesound.app.module.ApiModule_ProvideApiInterceptorFactory.get(ApiModule_ProvideApiInterceptorFactory.java:9) at dagger.internal.DoubleCheck.get(DoubleCheck.java:46) at com.futurice.freesound.app.module.ApiModule_ProvideApiOkHttpClientFactory.get(ApiModule_ProvideApiOkHttpClientFactory.java:41) at com.futurice.freesound.app.module.ApiModule_ProvideApiOkHttpClientFactory.get(ApiModule_ProvideApiOkHttpClientFactory.java:12) at dagger.internal.DoubleCheck.get(DoubleCheck.java:46) at com.futurice.freesound.app.module.ApiModule_ProvideFreeSoundApiFactory.get(ApiModule_ProvideFreeSoundApiFactory.java:37) at com.futurice.freesound.app.module.ApiModule_ProvideFreeSoundApiFactory.get(ApiModule_ProvideFreeSoundApiFactory.java:11) at dagger.internal.DoubleCheck.get(DoubleCheck.java:46) at com.futurice.freesound.app.DaggerFreesoundApplicationComponent.getApi(DaggerFreesoundApplicationComponent.java:177) at com.futurice.freesound.feature.search.DaggerSearchActivityComponent$1.get(DaggerSearchActivityComponent.java:75) at com.futurice.freesound.feature.search.DaggerSearchActivityComponent$1.get(DaggerSearchActivityComponent.java:68) at com.futurice.freesound.feature.search.SearchActivityModule_ProvideFreeSoundsSearchServiceFactory.get(SearchActivityModule_ProvideFreeSoundsSearchServiceFactory.java:27) at com.futurice.freesound.feature.search.SearchActivityModule_ProvideFreeSoundsSearchServiceFactory.get(SearchActivityModule_ProvideFreeSoundsSearchServiceFactory.java:10) at dagger.internal.DoubleCheck.get(DoubleCheck.java:46) at com.futurice.freesound.feature.search.SearchActivityModule_ProvideSearchDataModelFactory.get(SearchActivityModule_ProvideSearchDataModelFactory.java:26) at com.futurice.freesound.feature.search.SearchActivityModule_ProvideSearchDataModelFactory.get(SearchActivityModule_ProvideSearchDataModelFactory.java:9) at dagger.internal.DoubleCheck.get(DoubleCheck.java:46) at com.futurice.freesound.feature.search.SearchActivityModule_ProvideSearchViewModelFactory.get(SearchActivityModule_ProvideSearchViewModelFactory.java:38) at com.futurice.freesound.feature.search.SearchActivityModule_ProvideSearchViewModelFactory.get(SearchActivityModule_ProvideSearchViewModelFactory.java:10) at dagger.internal.DoubleCheck.get(DoubleCheck.java:46) at com.futurice.freesound.feature.search.SearchActivity_MembersInjector.injectMembers(SearchActivity_MembersInjector.java:29
P.S. I updated gradle plugin only!
There should be a playback progress indicator associated with the waveform view. This would show the progress across the width of the waveform. The current playback time should also be reported.
When the search query is cleared, either directly through the clear button or via the clearing of the search field, then the clearing of the search results list is not processed until after the debounce period (2 seconds). This makes the UI appear sluggish/buggy. The clear of the results should happen immediately.
We want to have a content on home screen.
Download the data of Spice Program user and display it there
The file app/freesound-api.properties
is not in git repo
As a first task I thought I could fix the compiler warnings. Is it fine?
:app:compileDebugJavaWithJavac
Note: C:\Users\Joan\AndroidStudioProjects\freesound-android\app\src\main\java\com\futurice\freesound\feature\search\SearchSnackbar.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
:app:compileDebugNdk UP-TO-DATE
:app:compileDebugSources
:app:incrementalDebugAndroidTestJavaCompilationSafeguard
:app:javaPreCompileDebugAndroidTest
:app:compileDebugAndroidTestJavaWithJavac
:app:compileDebugAndroidTestNdk UP-TO-DATE
:app:compileDebugAndroidTestSources
:app:incrementalDebugUnitTestJavaCompilationSafeguard UP-TO-DATE
:app:javaPreCompileDebugUnitTest
:app:compileDebugUnitTestJavaWithJavac
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: C:\Users\Joan\AndroidStudioProjects\freesound-android\app\src\test\java\com\futurice\freesound\common\utils\CollectionUtilsTest.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Create an initial playback solution for the sounds.
A screen with some information and images about the app, Futurice, Spice Program.
We need to dynamically request the fields to be populated in the response object. This is currently done by reusing the same Sound
class definition, perhaps it would be better to define specific POJOs for the usecase. For example, SummarySound
or DetailedSounds
.
Another are open for improvement is how we should define the required fields used in the request - they could be defined based on the response object.
We should have an easy way to use TimeSkipScheduler to use in tests but still be able to have computation scheduler in the application.
The WaveformExtractor
class (and its concrete implementations) have logic in them that would be very useful to test. The classes contain Android dependencies, such as Bitmap
, so either use Android instrumentation tests or possibly add a testable Bitmap
interface.
Currently some fields are defined as nullable, simply because the API, being outside of the control of the application, could not define values for certain fields by error, even though they are required. We should not be propagating nullability so far into the application, ideally the network layer should enforce the desired nullability.
Build fails when trying trying to deploy the 'release' flavor. Apparently the ProGuard files are not up to date.
Note: android.support.v4.media.IMediaBrowserServiceCallbacksAdapterApi21: can't find dynamically referenced class android.service.media.IMediaBrowserServiceCallbacks
Note: android.support.v4.media.IMediaBrowserServiceCallbacksAdapterApi21: can't find dynamically referenced class android.content.pm.ParceledListSlice
Note: android.support.v4.media.IMediaBrowserServiceCallbacksAdapterApi21$Stub: can't find dynamically referenced class android.service.media.IMediaBrowserServiceCallbacks$Stub
Note: android.support.v4.media.ParceledListSliceAdapterApi21: can't find dynamically referenced class android.content.pm.ParceledListSlice
Note: android.support.v4.text.ICUCompatApi23: can't find dynamically referenced class libcore.icu.ICU
Note: android.support.v4.text.ICUCompatIcs: can't find dynamically referenced class libcore.icu.ICU
Note: android.support.v7.widget.DrawableUtils: can't find dynamically referenced class android.graphics.Insets
Note: com.facebook.stetho.inspector.runtime.RhinoDetectingRuntimeReplFactory: can't find dynamically referenced class com.facebook.stetho.rhino.JsRuntimeReplFactoryBuilder
Note: com.google.android.gms.internal.zzanx: can't find dynamically referenced class sun.misc.Unsafe
Note: com.google.gson.internal.UnsafeAllocator: can't find dynamically referenced class sun.misc.Unsafe
Note: com.squareup.picasso.Utils: can't find dynamically referenced class com.squareup.okhttp.OkHttpClient
Note: okhttp3.internal.platform.AndroidPlatform: can't find dynamically referenced class com.android.org.conscrypt.SSLParametersImpl
Note: okhttp3.internal.platform.AndroidPlatform: can't find dynamically referenced class org.apache.harmony.xnet.provider.jsse.SSLParametersImpl
Note: okhttp3.internal.platform.Platform: can't find dynamically referenced class sun.security.ssl.SSLContextImpl
Note: retrofit2.Platform: can't find dynamically referenced class java.util.Optional
Note: retrofit2.Platform: can't find dynamically referenced class org.robovm.apple.foundation.NSObject
Note: retrofit2.Platform$IOS$MainThreadExecutor: can't find dynamically referenced class org.robovm.apple.foundation.NSOperationQueue
Note: android.support.v4.app.NotificationCompatJellybean accesses a declared field 'icon' dynamically
Maybe this is program field 'android.support.design.R$attr { int icon; }'
Maybe this is program field 'android.support.design.R$id { int icon; }'
Maybe this is program field 'android.support.v4.app.NotificationCompat$Action { int icon; }'
Maybe this is program field 'android.support.v7.appcompat.R$attr { int icon; }'
Maybe this is program field 'android.support.v7.appcompat.R$id { int icon; }'
Maybe this is program field 'com.facebook.stetho.R$attr { int icon; }'
Maybe this is program field 'com.facebook.stetho.R$id { int icon; }'
Maybe this is program field 'com.facebook.stetho.okhttp3.R$attr { int icon; }'
Maybe this is program field 'com.facebook.stetho.okhttp3.R$id { int icon; }'
Maybe this is program field 'com.futurice.freesound.R$attr { int icon; }'
Maybe this is program field 'com.futurice.freesound.R$id { int icon; }'
Maybe this is library field 'android.R$attr { int icon; }'
Maybe this is library field 'android.R$id { int icon; }'
Maybe this is library field 'android.app.LauncherActivity$ListItem { android.graphics.drawable.Drawable icon; }'
Maybe this is library field 'android.app.Notification { int icon; }'
Maybe this is library field 'android.app.Notification$Action { int icon; }'
Maybe this is library field 'android.appwidget.AppWidgetProviderInfo { int icon; }'
Maybe this is library field 'android.content.pm.PackageItemInfo { int icon; }'
Maybe this is library field 'android.content.pm.ResolveInfo { int icon; }'
Maybe this is library field 'android.inputmethodservice.Keyboard$Key { android.graphics.drawable.Drawable icon; }'
Maybe this is library field 'android.speech.tts.TextToSpeech$EngineInfo { int icon; }'
Note: android.support.v4.app.NotificationCompatJellybean accesses a declared field 'title' dynamically
Maybe this is program field 'android.support.design.R$attr { int title; }'
Maybe this is program field 'android.support.design.R$id { int title; }'
Maybe this is program field 'android.support.v4.app.NotificationCompat$Action { java.lang.CharSequence title; }'
Maybe this is program field 'android.support.v7.appcompat.R$attr { int title; }'
Maybe this is program field 'android.support.v7.appcompat.R$id { int title; }'
Maybe this is program field 'com.facebook.stetho.R$attr { int title; }'
Maybe this is program field 'com.facebook.stetho.R$id { int title; }'
Maybe this is program field 'com.facebook.stetho.inspector.protocol.module.HeapProfiler$ProfileHeader { java.lang.String title; }'
Maybe this is program field 'com.facebook.stetho.inspector.protocol.module.Profiler$ProfileHeader { java.lang.String title; }'
Maybe this is program field 'com.facebook.stetho.okhttp3.R$attr { int title; }'
Maybe this is program field 'com.facebook.stetho.okhttp3.R$id { int title; }'
Maybe this is program field 'com.futurice.freesound.R$attr { int title; }'
Maybe this is program field 'com.futurice.freesound.R$id { int title; }'
Maybe this is library field 'android.R$attr { int title; }'
Maybe this is library field 'android.R$id { int title; }'
Maybe this is library field 'android.app.Notification$Action { java.lang.CharSequence title; }'
Maybe this is library field 'android.preference.PreferenceActivity$Header { java.lang.CharSequence title; }'
Note: android.support.v4.app.NotificationCompatJellybean accesses a declared field 'actionIntent' dynamically
Maybe this is program field 'android.support.v4.app.NotificationCompat$Action { android.app.PendingIntent actionIntent; }'
Maybe this is library field 'android.app.Notification$Action { android.app.PendingIntent actionIntent; }'
Note: com.google.android.gms.internal.zzanx accesses a declared field 'theUnsafe' dynamically
Note: com.google.android.gms.internal.zzsb accesses a declared field 'MODULE_ID' dynamically
Maybe this is program field 'com.google.android.gms.dynamite.descriptors.com.google.android.gms.flags.ModuleDescriptor { java.lang.String MODULE_ID; }'
Note: com.google.android.gms.internal.zzsb accesses a declared field 'MODULE_VERSION' dynamically
Maybe this is program field 'com.google.android.gms.dynamite.descriptors.com.google.android.gms.flags.ModuleDescriptor { int MODULE_VERSION; }'
Note: com.google.gson.internal.UnsafeAllocator accesses a declared field 'theUnsafe' dynamically
Note: the configuration keeps the entry point 'com.google.android.gms.flags.impl.FlagProviderImpl { void init(com.google.android.gms.dynamic.zzd); }', but not the descriptor class 'com.google.android.gms.dynamic.zzd'
Note: the configuration keeps the entry point 'com.google.firebase.crash.FirebaseCrash { com.google.firebase.crash.FirebaseCrash getInstance(com.google.firebase.FirebaseApp); }', but not the descriptor class 'com.google.firebase.FirebaseApp'
Note: the configuration keeps the entry point 'com.google.firebase.iid.FirebaseInstanceId { com.google.firebase.iid.FirebaseInstanceId getInstance(com.google.firebase.FirebaseApp); }', but not the descriptor class 'com.google.firebase.FirebaseApp'
Note: there were 7 references to unknown classes.
You should check your configuration for typos.
(http://proguard.sourceforge.net/manual/troubleshooting.html#unknownclass)
Note: there were 3 classes trying to access enclosing classes using reflection.
You should consider keeping the inner classes attributes
(using '-keepattributes InnerClasses').
(http://proguard.sourceforge.net/manual/troubleshooting.html#attributes)
Note: there were 3 unkept descriptor classes in kept class members.
You should consider explicitly keeping the mentioned classes
(using '-keep').
(http://proguard.sourceforge.net/manual/troubleshooting.html#descriptorclass)
Note: there were 17 unresolved dynamic references to classes or interfaces.
You should check if you need to specify additional program jars.
(http://proguard.sourceforge.net/manual/troubleshooting.html#dynamicalclass)
Note: there were 7 accesses to class members by means of introspection.
You should consider explicitly keeping the mentioned class members
(using '-keep' or '-keepclassmembers').
(http://proguard.sourceforge.net/manual/troubleshooting.html#dynamicalclassmember)Warning: there were 6 unresolved references to classes or interfaces.
You may need to add missing library jars or update their versions.
If your code works fine without the missing classes, you can suppress
the warnings with '-dontwarn' options.
(http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedclass)
Warning: there were 1 unresolved references to library class members.
You probably need to update the library versions.
(http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedlibraryclassmember)Warning: Exception while processing task java.io.IOException: Please correct the above warnings first.
:app:transformClassesAndResourcesWithProguardForRelease FAILEDFAILURE: Build failed with an exception.
What went wrong:
Execution failed for task ':app:transformClassesAndResourcesWithProguardForRelease'.java.io.IOException: Please correct the above warnings first.
Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.BUILD FAILED
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.