Giter Club home page Giter Club logo

dharmaseed-android's Introduction

Dharma Seed App for Android

Stream dharma talks from the Dharma Seed archive to your Android device.

Dharma Seed is dedicated to preserving and sharing the spoken teachings of Theravada Buddhism in modern languages.

Features

  • Stream dharma talks
  • Find the most recent talks
  • Search talk titles and descriptions by keyword
  • Find talks by specific teachers
  • Search a teacher's talks by keyword
  • View teacher information
  • Download talks and listen without cellular or internet connectivity

Screenshots

Contributing

Fork the repo using Github and clone your fork locally. To run the project, plug in your device and click the green 'Play' button in Android Studio. Once you're ready to start making changes, create a branch: git ch -b <branch_name>. Name it something related to the changes you plan on working on, like update-db. Once you've made your changes, run the tests to make sure you didn't break anything and then add and commit to git. Once you've made as many commits as you need, push them to Github and create a PR.

Running the Tests

As of right now, all of our tests are Instrumentation Tests (as opposed to Unit Tests) which means that they require a device to run. They are located in app/src/androidTest/. Make sure your device is plugged in (you can also use an emulator but it's much slower), right click the package org.dharmaseed.android (androidTest) in the project window of Android Studio, and select Run tests in org.dharmaseed.android (androidTest).

Notes

  • Access to retreatants only talks is not currently supported.

These talks are freely offered in the spirit of dana, or generosity. You may visit the Dharma Seed website if you would like to support our work. We are a small non-profit organization supported solely through donations and we deeply appreciate your help in making these priceless teachings available to all.

Operating since the early 1980's, Dharma Seed collects and distributes dharma talks by teachers transmitting the Vipassana or Insight practices of Theravada Buddhism, the oldest Buddhist tradition still actively pursued in the 21st century.

We hope you enjoy the app.

May all beings be happy.

dharmaseed-android's People

Contributors

bb4242 avatar intermarc avatar jakewilson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

dharmaseed-android's Issues

PlayTalkActivity null object reference

The following crash appears to be caused by a null object reference of the mediaPlayer member of TalkPlayerFragment:

java.lang.RuntimeException: Unable to start activity ComponentInfo{org.dharmaseed.androidapp/org.dharmaseed.androidapp.PlayTalkActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.media.MediaPlayer.isPlaying()' on a null object reference
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2358)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2420)
    at android.app.ActivityThread.access$900(ActivityThread.java:154)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1321)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5294)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.media.MediaPlayer.isPlaying()' on a null object reference
    at org.dharmaseed.androidapp.PlayTalkActivity.onCreate(PlayTalkActivity.java:173)
    at android.app.Activity.performCreate(Activity.java:5990)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2311)
    ... 10 more

Distribute pre-seeded database

Include a recent database and teacher photos with the app, to avoid long initial data sync times on first use.

Need to figure out how not to overwrite the database if the user already has one.

Back button in talk view is broken

Oops, I broke the talk view's back button in 8d80911, which renamed the applicationID from org.dharmaseed.androidapp to org.dharmaseed.android. Clicking that button now yields the following error:

E/NavUtils: getParentActivityIntent: bad parentActivityName 'org.dharmaseed.android.NavigationActivity' in manifest

Store failed talk IDs in database

See #52. Sometimes we fail to download talks, and it would be nice to remember the talks that fail in the DB so that we can re-try them later on.

on a fresh install, browse the FS for downloaded dharma talks

If the user downloads some talks and for whatever reason deletes and re-installs the app or deletes the data, the dharma talks will remain on their device (which I intended), but we will not know that those talks are downloaded. So on boot up, we should check the DIRECTORY_MUSIC/dharmaseed folder for dharma talks and update any talks in the DB. This will prevent confusing behavior if I downloaded a talk, uninstalled the app, re-installed, and then clicked that talk in the app - the app would not recognize I had downloaded it and I would have to download it again.

Adjust teacher visibility and ordering

  • The app should list only the teachers that are considered "Dharma Seed public teachers", as indicated by the "public" field of the teacher API.
  • When listing the teachers, the monastics should be listed first, as indicated by the "monastic" field of the teacher API.

Add status/notification bar support

When a talk is playing in Dharma Seed, there should be an icon in the status bar indicating that a talk is playing, and swiping down from the top should allow the user to pause the talk without having to enter the app.

When downloading all talks, some requests timeout

Sometimes in RequestAggregator.fireRequest(), where we download talk data 500 at a time, we get a SocketTimeout. Then we just move on to the next batch of 500, so we lose out on 500 talks. I think instead we can save the talks we timed out on and try them again at the end.

Downloading a talk, exiting, and re-opening removes the loading animation

This can be confusing if the user quickly exits and re-opens a talk that is being downloaded. The original button will be there, perhaps looking like the download was cancelled, which is untrue. This could potentially be solved by having a "download" status column in the DB for talks, with statuses like not_downloaded, downloading, and downloaded, so we can set the appropriate image. But this isn't very high priority.

Add the repository pattern to the project

The Repository Pattern separates the DB logic code from the 'client' (in this case, the presentation layer, or the activities). This is useful to allow for testing of DB methods, cleaning up the presentation layer, and removing duplication of code, among others. This became clear to me after trying to address issue #37 . With the current architecture, the best way to do this would be a query on line 283 here:

case DETAIL_MODE_TEACHER:
getSupportActionBar().setTitle("Teacher Detail");
query = String.format("SELECT * FROM %s WHERE %s=%s",
DBManager.C.Teacher.TABLE_NAME,
DBManager.C.Teacher.ID, id);
headerIdx = DBManager.C.Teacher.NAME;
detailIdx = DBManager.C.Teacher.BIO;
break;

And then circumventing a function call later down in the code. But this would only add to the vast amounts of querying done from the Activity and serve to make the logic less intuitive, less maintainable, and harder for a newcomer to understand. The goal would be to remove all queries from any Activity and to instead retrieve data via the respective Repository.

A good first step is to create a TalkRepository class for just the Talk entity, and then expanding as needed, only creating methods for accessing the DB as needed and not creating a whole bunch of generic methods that aren't used.

This should be done before #37.

column 'recording_date' is incorrect

The recording_date column in the table talks is incorrect.
We insert values into talks based on the info we get from the api. So if there is a recording_date in the talk json from the api, we insert that into the db. But in the api, the field is rec_date, so recording_date doesn't get inserted. Since we don't have a recording_date, we use the update_date, which causes the most recent talks in the NavigationActivity to often be from one teacher because that teacher got updated last of all. For example:
brian

Looking at the returned json for the talk "The Kalama Sutta":

{"edition": "2019-01-06 21:02:07", "items": {"54055": {"upload_date": "2019-01-04 00:00:00", "is_featured": false, "audio_url": "/teacher/484/talk/54055/20170724-Brian_Lesage-FIMC-the_kalama_sutta-54055.mp3", "original_audio_file_name": "uploads/7_24_17_THE_KALAMA_SUTTA___NAVIGATING_THE_PATH.MP3", "id": 54055, "description": "This talk offers reflections on the Kalama sutta that make this discourse relevant to our lives.", "update_date": "2019-01-04 22:44:25", "venue_id": 256, "title": "The Kalama Sutta", "is_not_sellable": false, "destination": "web", "language_id": 1, "recording_type": "Talk", "duration_in_minutes": 30.7713333333333, "rec_date": "2017-07-24 19:00:00", "is_album": false, "retreat_id": 4129, "tracks": [], "publishability": "general", "teacher_id": 484, "isNotSellable": false, "recording_date_in_seconds": 1500922800.0, "talk_code": "", "isAlbum": false}}}

We see that the key is rec_date and that the rec_date is "2017-07-24 19:00:00", but the update_date is "2019-01-04 22:44:25", so it appears near first in the list of talks.

Check out these two queries:

sqlite> select count(_id) from talks where recording_date IS NOT NULL;
0
sqlite> select count(_id) from talks where recording_date IS NULL;
32022

So a simple change in the DB from recording_date to rec_date should fix this.

Follow redirects when downloading a talk

Instead of hitting the media.dharmaseed.org server directly, follow the redirect when hitting dharmaseed.org so that if a talk title changes, we can still download the file.

Starting the app seems unpredictable

Downloading the talks when opening the app for the first time seems unpredictable:

I fresh install the app, it downloads a single talk (or it only displays a single one), but navigating to the teachers page, it is filled with teachers. I clear data, re-run and it downloads what seems to be all the talks, but takes minutes and the "loading" circle animation doesn't go away.

This is vague, but the downloading of the dharma seed api on app start-up needs to be examined and improved.

onUpgrade() should use `ALTER TABLE` instead of `DROP TABLE`

For example, when the file_path column was added to the Talk table, I added code in onUpgrade() to drop the table and re-create it:

// DB version 31 added the "file_path" column to the talk table
// DB version 32 changed the column `recording_date` to `rec_date` in the talk table
// see (#30 for v32)
db.execSQL(C.Talk.DROP_TABLE);
db.execSQL(C.Talk.CREATE_TABLE);

But we should strive to avoid dropping and re-adding any table because of the time taken to re-populate the entire thing (the Talk table takes somewhere around 10 minutes). Instead we should alter the table if we're just adding a column.

Profile & improve performance

Goal is to eliminate all messages like I/Choreographer(1378): Skipped 55 frames! The application may be doing too much work on its main thread.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.