├── .gitignore ├── .idea ├── assetWizardSettings.xml ├── codeStyles │ └── Project.xml ├── gradle.xml ├── misc.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── google-services.json ├── proguard-rules.pro ├── release │ ├── E-Library_v2.0.apk │ └── output.json └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── android │ │ └── project │ │ └── elibrary │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── ic_launcher-web.png │ ├── java │ │ └── com │ │ │ └── android │ │ │ └── project │ │ │ └── elibrary │ │ │ ├── Admin.java │ │ │ ├── Book.java │ │ │ ├── BookList.java │ │ │ ├── Converter.java │ │ │ ├── Course.java │ │ │ ├── CourseList.java │ │ │ ├── Department.java │ │ │ ├── Download.java │ │ │ ├── DownloadDao.java │ │ │ ├── LocalDB.java │ │ │ ├── LocalData.java │ │ │ ├── MainActivity.java │ │ │ ├── OpenBook.java │ │ │ ├── PdfRead.java │ │ │ ├── Refresh.java │ │ │ ├── SearchableActivity.java │ │ │ ├── Semester.java │ │ │ └── SemesterList.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── ic_launcher_background.xml │ │ ├── ic_library_books.xml │ │ ├── ic_menu_bug.xml │ │ ├── ic_menu_camera.xml │ │ ├── ic_menu_gallery.xml │ │ ├── ic_menu_manage.xml │ │ ├── ic_menu_send.xml │ │ ├── ic_menu_share.xml │ │ ├── ic_menu_slideshow.xml │ │ └── side_nav_bar.xml │ │ ├── layout │ │ ├── activity_admin.xml │ │ ├── activity_main.xml │ │ ├── activity_open_book.xml │ │ ├── activity_pdf_read.xml │ │ ├── activity_refresh.xml │ │ ├── activity_semester_list.xml │ │ ├── app_bar_main.xml │ │ ├── content_main.xml │ │ └── nav_header_main.xml │ │ ├── menu │ │ ├── activity_main_drawer.xml │ │ └── main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── values-v21 │ │ └── styles.xml │ │ ├── values │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── ic_launcher_background.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ └── searchable.xml │ └── test │ └── java │ └── com │ └── android │ └── project │ └── elibrary │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── images └── elib-logo1.png └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches/build_file_checksums.ser 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | .DS_Store 9 | /build 10 | /captures 11 | .externalNativeBuild 12 | -------------------------------------------------------------------------------- /.idea/assetWizardSettings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 71 | 72 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 31 | 32 | 33 | 34 | 35 | 36 | 38 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # E-Library 2 | 3 | ## User friendly Android app to download and read books 4 | [Download Now](https://elibgithub.github.io) 5 | ### Functionalities: 6 | 1. Browse catalogues of books that are available. 7 | 2. Download a book. 8 | 3. Read the book from the app within. 9 | 4. Search for a book by its Name 10 | 5. Read recently opened book quickly 11 | ### Technologies used: 12 | * Cloud storage to store the entire catalogue and the books. 13 | * Local File storage to store books offline. 14 | * Local serverless database to store recently used books. 15 | * [PDF viewer](https://github.com/barteksc/AndroidPdfViewer) to read books. 16 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'com.google.gms.google-services' 3 | 4 | android { 5 | compileSdkVersion 28 6 | defaultConfig { 7 | applicationId "com.android.project.elibrary" 8 | minSdkVersion 21 9 | targetSdkVersion 28 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | allprojects { 22 | repositories { 23 | jcenter() 24 | maven { 25 | url "https://maven.google.com" 26 | } 27 | } 28 | } 29 | dependencies { 30 | implementation fileTree(dir: 'libs', include: ['*.jar']) 31 | implementation 'com.android.support:appcompat-v7:28.0.0' 32 | implementation 'com.android.support:support-v4:28.0.0' 33 | implementation 'com.android.support:design:28.0.0' 34 | implementation 'com.android.support.constraint:constraint-layout:1.1.3' 35 | testImplementation 'junit:junit:4.12' 36 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 37 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 38 | implementation 'com.google.firebase:firebase-core:16.0.1' 39 | implementation 'com.google.firebase:firebase-firestore:17.0.1' 40 | // Room components 41 | implementation "android.arch.persistence.room:runtime:$rootProject.roomVersion" 42 | annotationProcessor "android.arch.persistence.room:compiler:$rootProject.roomVersion" 43 | androidTestImplementation "android.arch.persistence.room:testing:$rootProject.roomVersion" 44 | // Lifecycle components 45 | implementation "android.arch.lifecycle:extensions:$rootProject.archLifecycleVersion" 46 | annotationProcessor "android.arch.lifecycle:compiler:$rootProject.archLifecycleVersion" 47 | implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' 48 | implementation 'org.jsoup:jsoup:1.11.1' 49 | implementation 'com.google.code.gson:gson:2.8.5' 50 | } 51 | -------------------------------------------------------------------------------- /app/google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "703861682115", 4 | "firebase_url": "https://e-library-2018.firebaseio.com", 5 | "project_id": "e-library-2018", 6 | "storage_bucket": "e-library-2018.appspot.com" 7 | }, 8 | "client": [ 9 | { 10 | "client_info": { 11 | "mobilesdk_app_id": "1:703861682115:android:f66e779f36fd1d62", 12 | "android_client_info": { 13 | "package_name": "com.android.project.elibrary" 14 | } 15 | }, 16 | "oauth_client": [ 17 | { 18 | "client_id": "703861682115-d50f4666qtjo14fmgt90m3sjuia354rp.apps.googleusercontent.com", 19 | "client_type": 1, 20 | "android_info": { 21 | "package_name": "com.android.project.elibrary", 22 | "certificate_hash": "e799c300b1ed36a912a822b6b01df168d186ba41" 23 | } 24 | }, 25 | { 26 | "client_id": "703861682115-rsbamegcckgvrmng20ol0pv1g2f2hjdd.apps.googleusercontent.com", 27 | "client_type": 3 28 | } 29 | ], 30 | "api_key": [ 31 | { 32 | "current_key": "AIzaSyBMzUZWZ67h8dlX18WoOvoi7703oUhfrcM" 33 | } 34 | ], 35 | "services": { 36 | "analytics_service": { 37 | "status": 1 38 | }, 39 | "appinvite_service": { 40 | "status": 2, 41 | "other_platform_oauth_client": [ 42 | { 43 | "client_id": "703861682115-rsbamegcckgvrmng20ol0pv1g2f2hjdd.apps.googleusercontent.com", 44 | "client_type": 3 45 | } 46 | ] 47 | }, 48 | "ads_service": { 49 | "status": 2 50 | } 51 | } 52 | } 53 | ], 54 | "configuration_version": "1" 55 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/release/E-Library_v2.0.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shashikdm/E-Library/3b2fcc8554acda9bc579b4f0e3668c871188c075/app/release/E-Library_v2.0.apk -------------------------------------------------------------------------------- /app/release/output.json: -------------------------------------------------------------------------------- 1 | [{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}] -------------------------------------------------------------------------------- /app/src/androidTest/java/com/android/project/elibrary/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.android.project.elibrary; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.android.project.elibrary", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 18 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 40 | 41 | 42 | 43 | 44 | 45 | 51 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shashikdm/E-Library/3b2fcc8554acda9bc579b4f0e3668c871188c075/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /app/src/main/java/com/android/project/elibrary/Admin.java: -------------------------------------------------------------------------------- 1 | package com.android.project.elibrary; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.net.ConnectivityManager; 6 | import android.net.NetworkInfo; 7 | import android.support.annotation.NonNull; 8 | import android.support.design.widget.Snackbar; 9 | import android.support.v7.app.AppCompatActivity; 10 | import android.os.Bundle; 11 | import android.view.View; 12 | import android.widget.ArrayAdapter; 13 | import android.widget.ListAdapter; 14 | import android.widget.ListView; 15 | import android.widget.Toast; 16 | 17 | import com.google.android.gms.tasks.OnCompleteListener; 18 | import com.google.android.gms.tasks.Task; 19 | import com.google.firebase.firestore.FirebaseFirestore; 20 | import com.google.firebase.firestore.QueryDocumentSnapshot; 21 | import com.google.firebase.firestore.QuerySnapshot; 22 | 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | 26 | public class Admin extends AppCompatActivity { 27 | ArrayList failures = new ArrayList(); 28 | @Override 29 | protected void onCreate(Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | setContentView(R.layout.activity_admin); 32 | FirebaseFirestore fdb = FirebaseFirestore.getInstance(); 33 | final ListView listView = findViewById(R.id.failed_list); 34 | fdb.collection("failed_links") 35 | .get() 36 | .addOnCompleteListener(new OnCompleteListener() { 37 | @Override 38 | public void onComplete(@NonNull Task task) { 39 | if (task.isSuccessful()) { 40 | for (QueryDocumentSnapshot document : task.getResult()) { 41 | //traversing through every document in the collection 42 | failures.add(document.getId()); 43 | } 44 | ListAdapter adapter = new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_list_item_1, failures.toArray()); 45 | listView.setAdapter(adapter); 46 | } 47 | } 48 | }); 49 | } 50 | public void refresh(View view) { 51 | ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); 52 | NetworkInfo activeNetworkInfo = null; 53 | if (connectivityManager != null) { 54 | activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); 55 | } 56 | if(!(activeNetworkInfo!=null && activeNetworkInfo.isConnected())) { 57 | Snackbar.make(findViewById(R.id.refresh),"No Internet",Snackbar.LENGTH_LONG).show(); 58 | } else { 59 | Intent intent = new Intent(getApplicationContext(), Refresh.class); 60 | startActivity(intent); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/com/android/project/elibrary/Book.java: -------------------------------------------------------------------------------- 1 | package com.android.project.elibrary; 2 | 3 | public class Book { 4 | int bookid; 5 | String name; 6 | String link; 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/android/project/elibrary/BookList.java: -------------------------------------------------------------------------------- 1 | package com.android.project.elibrary; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.content.Intent; 5 | import android.content.SharedPreferences; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.os.Bundle; 8 | import android.view.View; 9 | import android.widget.AdapterView; 10 | import android.widget.ArrayAdapter; 11 | import android.widget.ListAdapter; 12 | import android.widget.ListView; 13 | import android.widget.TextView; 14 | import android.widget.Toast; 15 | 16 | import com.google.gson.Gson; 17 | 18 | import java.util.ArrayList; 19 | import java.util.Objects; 20 | 21 | public class BookList extends AppCompatActivity { 22 | ArrayList bookObjects = new ArrayList<>(); 23 | ArrayList booklist = new ArrayList<>(); 24 | String courseid, department, semester; 25 | LocalData localData; 26 | @SuppressLint("SetTextI18n") 27 | @Override 28 | protected void onCreate(Bundle savedInstanceState) { 29 | super.onCreate(savedInstanceState); 30 | setContentView(R.layout.activity_semester_list); 31 | courseid = Objects.requireNonNull(Objects.requireNonNull(getIntent().getExtras()).get("courseid")).toString(); 32 | department = Objects.requireNonNull(Objects.requireNonNull(getIntent().getExtras()).get("department")).toString(); 33 | semester = Objects.requireNonNull(Objects.requireNonNull(getIntent().getExtras()).get("semester")).toString(); 34 | TextView textview = findViewById(R.id.deptname); 35 | textview.setText(department.toUpperCase()+" > " + semester + " > " + courseid); 36 | try { 37 | SharedPreferences sharedPreferences = getSharedPreferences("Data",MODE_PRIVATE); 38 | Gson gson = new Gson(); 39 | String json = sharedPreferences.getString("localData", ""); 40 | localData = gson.fromJson(json, LocalData.class); 41 | for(Book dbook : Objects.requireNonNull(Objects.requireNonNull(Objects.requireNonNull(localData.departments.get("DEPT" + department)).semesters.get(semester)).courses.get(courseid)).books.values()) { 42 | booklist.add(dbook.name); 43 | bookObjects.add(dbook); 44 | } 45 | ListAdapter adapter = new ArrayAdapter<>(BookList.this, android.R.layout.simple_list_item_1, booklist); 46 | ListView listView = findViewById(R.id.semlist); 47 | listView.setAdapter(adapter); 48 | listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 49 | @Override 50 | public void onItemClick(AdapterView adapterView, View view, int i, long l) { 51 | Intent intent = new Intent(getApplicationContext(),OpenBook.class); 52 | intent.putExtra("department", department); 53 | intent.putExtra("semester",semester); 54 | intent.putExtra("bookid",bookObjects.get(i).bookid); 55 | intent.putExtra("courseid",courseid); 56 | intent.putExtra("name", bookObjects.get(i).name); 57 | intent.putExtra("link", bookObjects.get(i).link); 58 | startActivity(intent); 59 | } 60 | }); 61 | } catch(Exception e) { 62 | Toast.makeText(getApplicationContext(),e.toString(),Toast.LENGTH_LONG).show(); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/java/com/android/project/elibrary/Converter.java: -------------------------------------------------------------------------------- 1 | package com.android.project.elibrary; 2 | 3 | import android.arch.persistence.room.TypeConverter; 4 | import java.util.Date; 5 | 6 | public class Converter { 7 | @TypeConverter 8 | public static Date fromTimestamp(Long value) { 9 | return value == null ? null : new Date(value); 10 | } 11 | 12 | @TypeConverter 13 | public static Long dateToTimestamp(Date date) { 14 | return date == null ? null : date.getTime(); 15 | } 16 | } -------------------------------------------------------------------------------- /app/src/main/java/com/android/project/elibrary/Course.java: -------------------------------------------------------------------------------- 1 | package com.android.project.elibrary; 2 | 3 | import java.util.Map; 4 | 5 | public class Course { 6 | Map books; 7 | String courseid, name; 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/android/project/elibrary/CourseList.java: -------------------------------------------------------------------------------- 1 | package com.android.project.elibrary; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.content.Intent; 5 | import android.content.SharedPreferences; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.os.Bundle; 8 | import android.view.View; 9 | import android.widget.AdapterView; 10 | import android.widget.ArrayAdapter; 11 | import android.widget.ListAdapter; 12 | import android.widget.ListView; 13 | import android.widget.TextView; 14 | import android.widget.Toast; 15 | 16 | import com.google.gson.Gson; 17 | 18 | import java.util.ArrayList; 19 | import java.util.Objects; 20 | 21 | public class CourseList extends AppCompatActivity { 22 | ArrayList courselist = new ArrayList<>(); 23 | ArrayList courses = new ArrayList<>(); 24 | String department; 25 | String semester; 26 | LocalData localData; 27 | @SuppressLint("SetTextI18n") 28 | @Override 29 | protected void onCreate(Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | setContentView(R.layout.activity_semester_list); 32 | department = Objects.requireNonNull(Objects.requireNonNull(getIntent().getExtras()).get("department")).toString(); 33 | semester = Objects.requireNonNull(Objects.requireNonNull(getIntent().getExtras()).get("semester")).toString(); 34 | TextView textview = findViewById(R.id.deptname); 35 | textview.setText(department.toUpperCase()+" > " + semester); 36 | try { 37 | SharedPreferences sharedPreferences = getSharedPreferences("Data",MODE_PRIVATE); 38 | Gson gson = new Gson(); 39 | String json = sharedPreferences.getString("localData", ""); 40 | localData = gson.fromJson(json, LocalData.class); 41 | for(Course dcourse : Objects.requireNonNull(Objects.requireNonNull(localData.departments.get("DEPT" + department)).semesters.get(semester)).courses.values()) { 42 | courselist.add(dcourse.name); 43 | courses.add(dcourse.courseid); 44 | } 45 | ListAdapter adapter = new ArrayAdapter<>(CourseList.this, android.R.layout.simple_list_item_1, courselist); 46 | ListView listView = findViewById(R.id.semlist); 47 | listView.setAdapter(adapter); 48 | listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 49 | @Override 50 | public void onItemClick(AdapterView adapterView, View view, int i, long l) { 51 | Intent intent = new Intent(getApplicationContext(),BookList.class); 52 | intent.putExtra("department", department); 53 | intent.putExtra("semester",semester); 54 | intent.putExtra("courseid",courses.get(i)); 55 | startActivity(intent); 56 | } 57 | }); 58 | } catch(Exception e) { 59 | Toast.makeText(getApplicationContext(),e.toString(),Toast.LENGTH_LONG).show(); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /app/src/main/java/com/android/project/elibrary/Department.java: -------------------------------------------------------------------------------- 1 | package com.android.project.elibrary; 2 | 3 | import java.util.Map; 4 | 5 | public class Department { 6 | Map semesters; 7 | String name; 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/android/project/elibrary/Download.java: -------------------------------------------------------------------------------- 1 | package com.android.project.elibrary; 2 | 3 | import android.arch.persistence.room.ColumnInfo; 4 | import android.arch.persistence.room.Entity; 5 | import android.arch.persistence.room.PrimaryKey; 6 | import android.support.annotation.NonNull; 7 | 8 | import java.util.Date; 9 | 10 | @Entity 11 | public class Download { 12 | @PrimaryKey 13 | @NonNull 14 | int bookid; 15 | @ColumnInfo(name = "name") 16 | String name; 17 | @ColumnInfo(name = "lastread") 18 | Date lastread; 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/android/project/elibrary/DownloadDao.java: -------------------------------------------------------------------------------- 1 | package com.android.project.elibrary; 2 | 3 | import android.arch.persistence.room.Dao; 4 | import android.arch.persistence.room.Insert; 5 | import android.arch.persistence.room.Query; 6 | 7 | import java.util.Date; 8 | 9 | @Dao 10 | public interface DownloadDao { 11 | @Insert 12 | void insert(Download download); 13 | @Query("SELECT bookid FROM Download") 14 | Integer[] fetch_bookids(); 15 | @Query("SELECT * FROM Download ORDER BY lastread DESC") 16 | Download[] fetch_recents(); 17 | @Query("DELETE FROM Download WHERE bookid = :bookid") 18 | void delete_download(int bookid); 19 | @Query("UPDATE Download SET lastread = :lastread WHERE bookid = :bookid") 20 | void update_download(int bookid, Date lastread); 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/android/project/elibrary/LocalDB.java: -------------------------------------------------------------------------------- 1 | package com.android.project.elibrary; 2 | 3 | import android.arch.persistence.room.Database; 4 | import android.arch.persistence.room.RoomDatabase; 5 | import android.arch.persistence.room.TypeConverters; 6 | 7 | @Database(entities = {Download.class}, version = 1, exportSchema = false) 8 | @TypeConverters({Converter.class}) 9 | public abstract class LocalDB extends RoomDatabase { 10 | public abstract DownloadDao downloadDao(); 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/android/project/elibrary/LocalData.java: -------------------------------------------------------------------------------- 1 | package com.android.project.elibrary; 2 | 3 | import java.util.Map; 4 | 5 | public class LocalData { 6 | Map departments; 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/android/project/elibrary/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.android.project.elibrary; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.app.AlertDialog; 5 | import android.arch.persistence.room.Room; 6 | import android.content.ActivityNotFoundException; 7 | import android.content.Context; 8 | import android.content.DialogInterface; 9 | import android.content.Intent; 10 | import android.content.SharedPreferences; 11 | import android.net.ConnectivityManager; 12 | import android.net.NetworkInfo; 13 | import android.net.Uri; 14 | import android.os.AsyncTask; 15 | import android.os.Bundle; 16 | import android.support.annotation.NonNull; 17 | import android.support.design.widget.Snackbar; 18 | import android.support.design.widget.NavigationView; 19 | import android.support.v4.view.GravityCompat; 20 | import android.support.v4.widget.DrawerLayout; 21 | import android.support.v7.app.ActionBarDrawerToggle; 22 | import android.support.v7.app.AppCompatActivity; 23 | import android.support.v7.widget.Toolbar; 24 | import android.view.Menu; 25 | import android.view.MenuItem; 26 | import android.view.View; 27 | import android.widget.AdapterView; 28 | import android.widget.ArrayAdapter; 29 | import android.widget.ListAdapter; 30 | import android.widget.ListView; 31 | import android.widget.ProgressBar; 32 | import android.widget.Toast; 33 | 34 | 35 | import com.google.android.gms.tasks.OnCompleteListener; 36 | import com.google.android.gms.tasks.Task; 37 | import com.google.firebase.firestore.DocumentSnapshot; 38 | import com.google.firebase.firestore.FirebaseFirestore; 39 | import com.google.firebase.firestore.QueryDocumentSnapshot; 40 | import com.google.firebase.firestore.QuerySnapshot; 41 | import com.google.gson.Gson; 42 | 43 | import java.util.ArrayList; 44 | import java.util.Arrays; 45 | import java.util.HashMap; 46 | import java.util.Map; 47 | import java.util.Objects; 48 | import java.util.concurrent.TimeUnit; 49 | 50 | public class MainActivity extends AppCompatActivity 51 | implements NavigationView.OnNavigationItemSelectedListener { 52 | String[] recentbooks; 53 | Integer[] recentids; 54 | AlertDialog.Builder builder; 55 | AlertDialog alert; 56 | FirebaseFirestore fdb; 57 | int counter = 0; 58 | LocalData localData; 59 | @Override 60 | protected void onCreate(Bundle savedInstanceState) { 61 | super.onCreate(savedInstanceState); 62 | setContentView(R.layout.activity_main); 63 | Toolbar toolbar = findViewById(R.id.toolbar); 64 | setSupportActionBar(toolbar); 65 | SharedPreferences sharedPref1 = getSharedPreferences("Data",MODE_PRIVATE); 66 | fdb = FirebaseFirestore.getInstance(); 67 | new Synchronise2().execute(); 68 | DrawerLayout drawer = findViewById(R.id.drawer_layout); 69 | ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( 70 | this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); 71 | drawer.addDrawerListener(toggle); 72 | toggle.syncState(); 73 | 74 | NavigationView navigationView = findViewById(R.id.nav_view); 75 | navigationView.setNavigationItemSelectedListener(this); 76 | final Menu menu = navigationView.getMenu(); 77 | try { 78 | SharedPreferences sharedPreferences = getSharedPreferences("Data",MODE_PRIVATE); 79 | Gson gson = new Gson(); 80 | String json = sharedPreferences.getString("localData", ""); 81 | 82 | localData = gson.fromJson(json, LocalData.class); 83 | int i = 0; 84 | String[] deptlist = localData.departments.keySet().toArray(new String[0]); 85 | Arrays.sort(deptlist); 86 | for (String depts : deptlist) { 87 | menu.add(R.id.deptgroup, Menu.NONE, i, depts.substring(4)); 88 | } 89 | } catch(Exception ignored) { 90 | 91 | } 92 | if(!sharedPref1.contains("notfirsttime")) { 93 | ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 94 | NetworkInfo activeNetworkInfo = null; 95 | if (connectivityManager != null) { 96 | activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); 97 | } 98 | if (!(activeNetworkInfo != null && activeNetworkInfo.isConnected())) { 99 | builder = new AlertDialog.Builder(this); 100 | builder.setMessage("Please connect to the internet when using the app for the first time"); 101 | builder.setCancelable(false); 102 | builder.setNegativeButton("Ok", new DialogInterface.OnClickListener() { 103 | @Override 104 | public void onClick(DialogInterface dialog, int which) { 105 | finish(); 106 | } 107 | }); 108 | alert = builder.create(); 109 | alert.show(); 110 | } else { 111 | try { 112 | TimeUnit.SECONDS.sleep(1); 113 | } catch (InterruptedException e) { 114 | 115 | } 116 | resync(); 117 | SharedPreferences sharedPref2 = getSharedPreferences("Data",MODE_PRIVATE); 118 | SharedPreferences.Editor editor = sharedPref2.edit(); 119 | editor.putBoolean("notfirsttime",true); 120 | editor.apply(); 121 | } 122 | } 123 | } 124 | @Override 125 | public void onBackPressed() { 126 | DrawerLayout drawer = findViewById(R.id.drawer_layout); 127 | if (drawer.isDrawerOpen(GravityCompat.START)) { 128 | drawer.closeDrawer(GravityCompat.START); 129 | } else { 130 | super.onBackPressed(); 131 | } 132 | } 133 | 134 | @Override 135 | public boolean onCreateOptionsMenu(Menu menu) { 136 | // Inflate the menu; this adds items to the action bar if it is present. 137 | getMenuInflater().inflate(R.menu.main, menu); 138 | return true; 139 | } 140 | 141 | @Override 142 | public boolean onOptionsItemSelected(MenuItem item) { 143 | // Handle action bar item clicks here. The action bar will 144 | // automatically handle clicks on the Home/Up button, so long 145 | // as you specify a parent activity in AndroidManifest.xml. 146 | int id = item.getItemId(); 147 | //noinspection SimplifiableIfStatement 148 | if (id == R.id.action_update) { 149 | String url = "https://elibgithub.github.io/index"; 150 | Intent i = new Intent(Intent.ACTION_VIEW); 151 | i.setData(Uri.parse(url)); 152 | startActivity(i); 153 | return true; 154 | } else if(id == R.id.action_search) { 155 | onSearchRequested(); 156 | } else if(id == R.id.admin) { 157 | 158 | Intent intent = new Intent(getApplicationContext(), Admin.class); 159 | startActivity(intent); 160 | } else if(id == R.id.resync) { 161 | ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); 162 | NetworkInfo activeNetworkInfo = null; 163 | if (connectivityManager != null) { 164 | activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); 165 | } 166 | if(!(activeNetworkInfo!=null && activeNetworkInfo.isConnected())) { 167 | Snackbar.make(findViewById(R.id.openbook),"No Internet", Snackbar.LENGTH_LONG).show(); 168 | } else { 169 | resync(); 170 | } 171 | } 172 | 173 | return super.onOptionsItemSelected(item); 174 | } 175 | protected void onRestoreInstanceState(Bundle savedInstanceState) { 176 | super.onRestoreInstanceState(savedInstanceState); 177 | new Synchronise2().execute(); 178 | } 179 | 180 | @Override 181 | protected void onResume() { 182 | super.onResume(); 183 | new Synchronise2().execute(); 184 | } 185 | 186 | @SuppressWarnings("StatementWithEmptyBody") 187 | @Override 188 | public boolean onNavigationItemSelected(@NonNull MenuItem item) { 189 | // Handle navigation view item clicks here. 190 | int id = item.getItemId(), gid = item.getGroupId(); 191 | Intent intent = new Intent(getApplicationContext(),SemesterList.class); 192 | if(gid == R.id.deptgroup) { 193 | intent.putExtra("department",item.getTitle()); 194 | startActivity(intent); 195 | //Toast.makeText(getApplicationContext(),item.getTitle(),Toast.LENGTH_LONG).show(); 196 | } else if (id == R.id.nav_share) { 197 | Intent sendIntent = new Intent(); 198 | sendIntent.setAction(Intent.ACTION_SEND); 199 | sendIntent.putExtra(Intent.EXTRA_TEXT,"Download E Library app from: https://elibgithub.github.io"); 200 | sendIntent.setType("text/plain"); 201 | Intent.createChooser(sendIntent,"Share via"); 202 | startActivity(sendIntent); 203 | } else if (id == R.id.nav_feedback) { 204 | Intent emailIntent = new Intent(Intent.ACTION_SENDTO); 205 | String Subject; 206 | Subject = "FEEDBACK"; 207 | String mailto = "mailto:elib.feedback@gmail.com"; 208 | emailIntent.putExtra(Intent.EXTRA_SUBJECT,Subject); 209 | emailIntent.setData(Uri.parse(mailto)); 210 | try { 211 | startActivity(emailIntent); 212 | } catch (ActivityNotFoundException e) { 213 | Snackbar.make(findViewById(R.id.drawer_layout),"No suitable app found",Snackbar.LENGTH_LONG).show(); 214 | 215 | } 216 | } else if (id == R.id.nav_suggestbook) { 217 | Intent emailIntent = new Intent(Intent.ACTION_SENDTO); 218 | String Subject; 219 | Subject = "SUGGESTION"; 220 | String mailto = "mailto:elib.feedback@gmail.com"; 221 | emailIntent.putExtra(Intent.EXTRA_SUBJECT,Subject); 222 | emailIntent.setData(Uri.parse(mailto)); 223 | try { 224 | startActivity(emailIntent); 225 | } catch (ActivityNotFoundException e) { 226 | Snackbar.make(findViewById(R.id.drawer_layout),"No suitable app found",Snackbar.LENGTH_LONG).show(); 227 | } 228 | } else if (id == R.id.nav_bugreport) { 229 | Intent emailIntent = new Intent(Intent.ACTION_SENDTO); 230 | String Subject; 231 | Subject = "BUG REPORT"; 232 | String mailto = "mailto:elib.feedback@gmail.com"; 233 | emailIntent.putExtra(Intent.EXTRA_SUBJECT,Subject); 234 | emailIntent.setData(Uri.parse(mailto)); 235 | try { 236 | startActivity(emailIntent); 237 | } catch (ActivityNotFoundException e) { 238 | Snackbar.make(findViewById(R.id.drawer_layout),"No suitable app found",Snackbar.LENGTH_LONG).show(); 239 | 240 | } 241 | } 242 | DrawerLayout drawer = findViewById(R.id.drawer_layout); 243 | drawer.closeDrawer(GravityCompat.START); 244 | return true; 245 | } 246 | @SuppressLint("StaticFieldLeak") 247 | private class Synchronise2 extends AsyncTask{ 248 | @Override 249 | protected Integer doInBackground(Void... updates) { 250 | LocalDB localDB = Room.databaseBuilder(getApplicationContext(), LocalDB.class, "localDB").build(); 251 | Download[] downloads = localDB.downloadDao().fetch_recents(); 252 | recentbooks = new String[downloads.length]; 253 | recentids = new Integer[downloads.length]; 254 | int i = 0; 255 | for(Download download : downloads) { 256 | recentbooks[i] = download.name; 257 | recentids[i] = download.bookid; 258 | i++; 259 | } 260 | return 1; 261 | } 262 | @Override 263 | protected void onPostExecute(Integer n) { 264 | if(recentbooks.length > 0) { 265 | try { 266 | ListAdapter adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, recentbooks); 267 | ListView listView = findViewById(R.id.recentlist); 268 | listView.setAdapter(adapter); 269 | listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 270 | @Override 271 | public void onItemClick(AdapterView adapterView, View view, int i, long l) { 272 | Intent intent = new Intent(getApplicationContext(), PdfRead.class); 273 | intent.putExtra("bookid", recentids[i]); 274 | startActivity(intent); 275 | } 276 | }); 277 | } catch(Exception e) { 278 | //Do nothing 279 | } 280 | } 281 | } 282 | } 283 | 284 | void resync() { 285 | localData = new LocalData(); 286 | builder = new AlertDialog.Builder(this); 287 | builder.setMessage("Synchronising..."); 288 | ProgressBar progressBar = new ProgressBar(this,null, android.R.attr.progressBarStyle); 289 | builder.setView(progressBar); 290 | builder.setCancelable(false); 291 | alert = builder.create(); 292 | alert.show(); 293 | 294 | fdb.collection("maxCount").get().addOnCompleteListener(new OnCompleteListener() { 295 | @Override 296 | public void onComplete(@NonNull Task task) { 297 | if(task.isSuccessful()) { 298 | Integer maxCount = 0; 299 | for(QueryDocumentSnapshot document: task.getResult()) { 300 | maxCount = Integer.parseInt(document.getId()); 301 | } 302 | new BusyWait().execute(maxCount); 303 | } 304 | } 305 | }); 306 | fdb.collection("departments").get().addOnCompleteListener(new OnCompleteListener() { 307 | @Override 308 | public void onComplete(@NonNull Task task) { 309 | if(task.isSuccessful()) { 310 | Map departmentMap = new HashMap<>(); 311 | final ArrayList fdepts = new ArrayList<>(); 312 | for (QueryDocumentSnapshot document : task.getResult()) { 313 | //traversing through every document in the collection 314 | Department department = new Department(); 315 | department.name = document.getId(); 316 | departmentMap.put(document.getId(),department); 317 | fdepts.add(department.name); 318 | } 319 | localData.departments = departmentMap; 320 | for(final String fdept : fdepts) { 321 | fdb.collection(fdept).get().addOnCompleteListener(new OnCompleteListener() { 322 | @Override 323 | public void onComplete(@NonNull Task task) { 324 | if(task.isSuccessful()) { 325 | Map semesterMap = new HashMap<>(); 326 | ArrayList fsems = new ArrayList<>(); 327 | for(QueryDocumentSnapshot document : task.getResult()) { 328 | Semester semester = new Semester(); 329 | semester.name = document.getId(); 330 | semesterMap.put(document.getId(), semester); 331 | fsems.add(semester.name); 332 | } 333 | Objects.requireNonNull(localData.departments.get(fdept)).semesters = semesterMap; 334 | for(final String fsem : fsems) { 335 | fdb.collection(fdept).document(fsem).get().addOnCompleteListener(new OnCompleteListener() { 336 | @Override 337 | public void onComplete(@NonNull Task task) { 338 | if(task.isSuccessful()) { 339 | Map courseMap = new HashMap<>(); 340 | ArrayList fcourses = new ArrayList<>(); 341 | Map map = task.getResult().getData(); 342 | for (final Map.Entry entry : Objects.requireNonNull(map).entrySet()) { 343 | Course course = new Course(); 344 | course.name = entry.getKey(); 345 | course.courseid = entry.getValue().toString(); 346 | courseMap.put(course.courseid,course); 347 | fcourses.add(course.courseid); 348 | } 349 | Objects.requireNonNull(Objects.requireNonNull(localData.departments.get(fdept)).semesters.get(fsem)).courses = courseMap; 350 | for(final String fcourse : fcourses) { 351 | fdb.collection(fdept).document(fsem).collection(fcourse).get().addOnCompleteListener(new OnCompleteListener() { 352 | @Override 353 | public void onComplete(@NonNull Task task) { 354 | if(task.isSuccessful()) { 355 | Map bookMap = new HashMap<>(); 356 | for(QueryDocumentSnapshot document : task.getResult()) { 357 | Book book = new Book(); 358 | book.bookid = Integer.parseInt(document.getId()); 359 | book.link = document.getString("link"); 360 | book.name = document.getString("name"); 361 | bookMap.put(document.getId(),book); 362 | counter++; 363 | //Toast.makeText(getApplicationContext(),Integer.valueOf(counter).toString(),Toast.LENGTH_SHORT).show(); 364 | } 365 | Objects.requireNonNull(Objects.requireNonNull(Objects.requireNonNull(localData.departments.get(fdept)).semesters.get(fsem)).courses.get(fcourse)).books = bookMap; 366 | } 367 | } 368 | }); 369 | } 370 | } 371 | } 372 | }); 373 | } 374 | } 375 | } 376 | }); 377 | } 378 | } 379 | } 380 | }); 381 | } 382 | @SuppressLint("StaticFieldLeak") 383 | private class BusyWait extends AsyncTask{ 384 | @Override 385 | protected Integer doInBackground(Integer... data) { 386 | while(counter < data[0]) { 387 | try { 388 | TimeUnit.SECONDS.sleep(1); 389 | } catch (InterruptedException ignored) { 390 | 391 | } 392 | } 393 | return 1; 394 | } 395 | @Override 396 | protected void onPostExecute(Integer n) { 397 | alert.cancel(); 398 | SharedPreferences sharedPreferences = getSharedPreferences("Data",MODE_PRIVATE); 399 | SharedPreferences.Editor editor = sharedPreferences.edit(); 400 | Gson gson = new Gson(); 401 | String json = gson.toJson(localData); 402 | editor.putString("localData",json); 403 | editor.apply(); 404 | Toast.makeText(getApplicationContext(),"Database updated", Toast.LENGTH_LONG).show(); 405 | try { 406 | Snackbar.make(findViewById(R.id.drawer_layout), "Database updated", Snackbar.LENGTH_LONG).show(); 407 | 408 | } catch(Exception e) { 409 | Toast.makeText(getApplicationContext(),"Database updated", Toast.LENGTH_LONG).show(); 410 | } 411 | recreate(); 412 | } 413 | } 414 | } 415 | -------------------------------------------------------------------------------- /app/src/main/java/com/android/project/elibrary/OpenBook.java: -------------------------------------------------------------------------------- 1 | package com.android.project.elibrary; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.app.AlertDialog; 5 | import android.app.DownloadManager; 6 | import android.arch.persistence.room.Room; 7 | import android.content.BroadcastReceiver; 8 | import android.content.Context; 9 | import android.content.DialogInterface; 10 | import android.content.Intent; 11 | import android.content.IntentFilter; 12 | import android.content.res.ColorStateList; 13 | import android.database.Cursor; 14 | import android.graphics.Color; 15 | import android.net.ConnectivityManager; 16 | import android.net.NetworkInfo; 17 | import android.net.Uri; 18 | import android.os.AsyncTask; 19 | import android.os.Environment; 20 | import android.support.design.widget.FloatingActionButton; 21 | import android.support.design.widget.Snackbar; 22 | import android.support.v4.content.ContextCompat; 23 | import android.support.v7.app.AppCompatActivity; 24 | import android.os.Bundle; 25 | import android.view.View; 26 | import android.widget.TextView; 27 | import android.widget.Toast; 28 | 29 | import com.google.firebase.firestore.FirebaseFirestore; 30 | 31 | import java.io.File; 32 | import java.io.FileInputStream; 33 | import java.io.FileOutputStream; 34 | import java.io.IOException; 35 | import java.util.Arrays; 36 | import java.util.Calendar; 37 | import java.util.HashMap; 38 | import java.util.Map; 39 | import java.util.Objects; 40 | 41 | public class OpenBook extends AppCompatActivity { 42 | String title, downloadlink; 43 | Integer bookid; 44 | FloatingActionButton downloadb, openb , deleteb ; 45 | 46 | @SuppressLint("SetTextI18n") 47 | @Override 48 | protected void onCreate(Bundle savedInstanceState) { 49 | new Synchronise1().execute(); 50 | super.onCreate(savedInstanceState); 51 | setContentView(R.layout.activity_open_book); 52 | downloadb = findViewById(R.id.downloadb); 53 | openb = findViewById(R.id.openb); 54 | deleteb = findViewById(R.id.deleteb); 55 | String department = Objects.requireNonNull(Objects.requireNonNull(getIntent().getExtras()).get("department")).toString(); 56 | String semester = Objects.requireNonNull(Objects.requireNonNull(getIntent().getExtras()).get("semester")).toString(); 57 | String courseid = Objects.requireNonNull(Objects.requireNonNull(getIntent().getExtras()).get("courseid")).toString(); 58 | downloadlink = Objects.requireNonNull(Objects.requireNonNull(getIntent().getExtras()).get("link")).toString(); 59 | title = Objects.requireNonNull(Objects.requireNonNull(getIntent().getExtras()).get("name")).toString(); 60 | bookid = Integer.parseInt(Objects.requireNonNull(Objects.requireNonNull(getIntent().getExtras()).get("bookid")).toString()); 61 | 62 | TextView textview = findViewById(R.id.topbar); 63 | textview.setText(department+" > "+semester+" > "+courseid+" >"); 64 | textview = findViewById(R.id.title); 65 | textview.setText(title); 66 | new Synchronise1().execute(); 67 | } 68 | @SuppressLint("StaticFieldLeak") 69 | private class Synchronise1 extends AsyncTask { 70 | @Override 71 | protected Integer doInBackground(Void... data) { 72 | LocalDB localDB = Room.databaseBuilder(getApplicationContext(), LocalDB.class, "localDB").build(); 73 | Integer[] bookids = localDB.downloadDao().fetch_bookids(); 74 | if(Arrays.asList(bookids).contains(bookid)) { 75 | return 1; 76 | } 77 | return 0; 78 | } 79 | @Override 80 | protected void onPostExecute(Integer exists) { 81 | try { 82 | if (exists == 1) { 83 | openb.setClickable(true); 84 | openb.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(getApplicationContext(), R.color.design_default_color_primary))); 85 | deleteb.setClickable(true); 86 | deleteb.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(getApplicationContext(), R.color.colorAccent))); 87 | downloadb.setClickable(false); 88 | downloadb.setBackgroundTintList(ColorStateList.valueOf(Color.GRAY)); 89 | } else { 90 | downloadb.setClickable(true); 91 | downloadb.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary))); 92 | openb.setClickable(false); 93 | openb.setBackgroundTintList(ColorStateList.valueOf(Color.GRAY)); 94 | deleteb.setClickable(false); 95 | deleteb.setBackgroundTintList(ColorStateList.valueOf(Color.GRAY)); 96 | } 97 | } catch(Exception e) { 98 | //Do nothing 99 | } 100 | } 101 | } 102 | @SuppressLint("StaticFieldLeak") 103 | private class Synchronise2 extends AsyncTask { 104 | @Override 105 | protected Integer doInBackground(Void... data) { 106 | LocalDB localDB = Room.databaseBuilder(getApplicationContext(), LocalDB.class, "localDB").build(); 107 | Download download = new Download(); 108 | download.bookid = bookid; 109 | download.name = title; 110 | download.lastread = Calendar.getInstance().getTime(); 111 | String filename= Objects.requireNonNull(getApplicationContext().getExternalFilesDir("")).getAbsolutePath()+File.separator+Environment.DIRECTORY_DOWNLOADS+File.separator+bookid.toString(); 112 | File file = new File(filename); 113 | byte[] byteform = new byte[(int) file.length()]; 114 | try { 115 | FileInputStream fis = new FileInputStream(file); 116 | //noinspection ResultOfMethodCallIgnored 117 | fis.read(byteform); //read file into bytes[] 118 | fis.close(); 119 | } catch(Exception e) { 120 | return 0; 121 | } 122 | byteform[0] = (byte)(-byteform[0]); 123 | //noinspection ResultOfMethodCallIgnored 124 | file.delete(); 125 | try { 126 | FileOutputStream fileOuputStream = new FileOutputStream(filename); 127 | fileOuputStream.write(byteform); 128 | fileOuputStream.close(); 129 | } catch (IOException ignored) { 130 | } 131 | localDB.downloadDao().insert(download); 132 | return 1; 133 | } 134 | @Override 135 | protected void onPostExecute(Integer exists) { 136 | try { 137 | if (exists == 1) { 138 | openb.setClickable(true); 139 | openb.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(getApplicationContext(), R.color.design_default_color_primary))); 140 | deleteb.setClickable(true); 141 | deleteb.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(getApplicationContext(), R.color.colorAccent))); 142 | downloadb.setClickable(false); 143 | downloadb.setBackgroundTintList(ColorStateList.valueOf(Color.GRAY)); 144 | 145 | } else { 146 | downloadb.setClickable(true); 147 | downloadb.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary))); 148 | openb.setClickable(false); 149 | openb.setBackgroundTintList(ColorStateList.valueOf(Color.GRAY)); 150 | deleteb.setClickable(false); 151 | deleteb.setBackgroundTintList(ColorStateList.valueOf(Color.GRAY)); 152 | } 153 | } catch(Exception ignored) { 154 | } 155 | } 156 | } 157 | @SuppressLint("StaticFieldLeak") 158 | private class Synchronise3 extends AsyncTask { 159 | @Override 160 | protected Integer doInBackground(Void... data) { 161 | LocalDB localDB = Room.databaseBuilder(getApplicationContext(), LocalDB.class, "localDB").build(); 162 | localDB.downloadDao().delete_download(bookid); 163 | return 1; 164 | } 165 | @Override 166 | protected void onPostExecute(Integer exists) { 167 | } 168 | } 169 | public void downloadbook(View view) { 170 | ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); 171 | NetworkInfo activeNetworkInfo = null; 172 | if (connectivityManager != null) { 173 | activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); 174 | } 175 | if(!(activeNetworkInfo!=null && activeNetworkInfo.isConnected())) { 176 | Snackbar.make(findViewById(R.id.openbook),"No Internet", Snackbar.LENGTH_LONG).show(); 177 | return; 178 | } 179 | downloadb.setBackgroundTintList(ColorStateList.valueOf(Color.GRAY)); 180 | downloadb.setClickable(false); 181 | Snackbar.make(findViewById(R.id.openbook),"Downloading",Snackbar.LENGTH_LONG).show(); 182 | Uri link = Uri.parse(downloadlink); 183 | DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); 184 | final DownloadManager.Request request = new DownloadManager.Request(link); 185 | request.setTitle("Downloading"); 186 | request.setDescription(title); 187 | request.setDestinationInExternalFilesDir(getApplicationContext(), Environment.DIRECTORY_DOWNLOADS, bookid.toString()); 188 | request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE); 189 | 190 | dm.enqueue(request); 191 | BroadcastReceiver onComplete=new BroadcastReceiver() { 192 | public void onReceive(Context ctxt, Intent intent) { 193 | String action = intent.getAction(); 194 | assert action != null; 195 | if(action.equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) { 196 | DownloadManager.Query query = new DownloadManager.Query(); 197 | query.setFilterById(intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0)); 198 | DownloadManager manager = (DownloadManager) ctxt.getSystemService(Context.DOWNLOAD_SERVICE); 199 | Cursor cursor = manager.query(query); 200 | if (cursor.moveToFirst()) { 201 | if (cursor.getCount() > 0) { 202 | int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)); 203 | if (status == DownloadManager.STATUS_SUCCESSFUL) { 204 | String filename= Objects.requireNonNull(getApplicationContext().getExternalFilesDir("")).getAbsolutePath()+File.separator+Environment.DIRECTORY_DOWNLOADS+File.separator+bookid.toString(); 205 | File file = new File(filename); 206 | byte[] byteform = new byte[(int) file.length()]; 207 | try { 208 | FileInputStream fis = new FileInputStream(file); 209 | //noinspection ResultOfMethodCallIgnored 210 | fis.read(byteform); //read file into bytes[] 211 | fis.close(); 212 | } catch(Exception ignored) { 213 | } 214 | StringBuilder type = new StringBuilder(); 215 | for(int i = 0; i < 4; i++) { 216 | type.append((char)byteform[i]); 217 | } 218 | if(type.toString().equalsIgnoreCase("%PDF")) { 219 | try { 220 | Snackbar.make(findViewById(R.id.openbook), "Download complete", Snackbar.LENGTH_LONG).show(); 221 | } catch (Exception e) { 222 | Toast.makeText(getApplicationContext(), "Download complete", Toast.LENGTH_LONG).show(); 223 | } 224 | new Synchronise2().execute(); 225 | } else { 226 | //notify in firebase and admin notification also delete the file 227 | FirebaseFirestore fdb = FirebaseFirestore.getInstance(); 228 | Map request = new HashMap<>(); 229 | try { 230 | fdb.collection("failed_links").document(bookid.toString()).set(request); 231 | } catch(Exception ignored) { 232 | } 233 | try { 234 | Snackbar.make(findViewById(R.id.openbook), "Download link expired", Snackbar.LENGTH_LONG).show(); 235 | AlertDialog.Builder builder = new AlertDialog.Builder(OpenBook.this); 236 | builder.setMessage("Download link has expired\nPlease resync and try again after some time"); 237 | builder.setNegativeButton("Ok", new DialogInterface.OnClickListener() { 238 | @Override 239 | public void onClick(DialogInterface dialog, int which) { 240 | } 241 | }); 242 | final AlertDialog alertDialog = builder.create(); 243 | alertDialog.setOnShowListener(new DialogInterface.OnShowListener() { 244 | @Override 245 | public void onShow(DialogInterface dialog) { 246 | alertDialog.getButton(alertDialog.BUTTON_NEGATIVE).setTextColor(ColorStateList.valueOf(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary))); 247 | } 248 | }); 249 | alertDialog.show(); 250 | 251 | } catch (Exception e) { 252 | Toast.makeText(getApplicationContext(), "Download link has expired\nPlease resync and try again after some time", Toast.LENGTH_LONG).show(); 253 | } 254 | //noinspection ResultOfMethodCallIgnored 255 | file.delete(); 256 | } 257 | } else { 258 | try { 259 | Snackbar.make(findViewById(R.id.openbook), "Download failed", Snackbar.LENGTH_LONG).show(); 260 | downloadb.setClickable(true); 261 | downloadb.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary))); 262 | openb.setClickable(false); 263 | openb.setBackgroundTintList(ColorStateList.valueOf(Color.GRAY)); 264 | deleteb.setClickable(false); 265 | deleteb.setBackgroundTintList(ColorStateList.valueOf(Color.GRAY)); 266 | } catch(Exception e) { 267 | Toast.makeText(getApplicationContext(), "Download failed", Toast.LENGTH_LONG).show(); 268 | 269 | } 270 | } 271 | } else { 272 | try { 273 | Snackbar.make(findViewById(R.id.openbook), "Download failed", Snackbar.LENGTH_LONG).show(); 274 | downloadb.setClickable(true); 275 | downloadb.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary))); 276 | openb.setClickable(false); 277 | openb.setBackgroundTintList(ColorStateList.valueOf(Color.GRAY)); 278 | deleteb.setClickable(false); 279 | deleteb.setBackgroundTintList(ColorStateList.valueOf(Color.GRAY)); 280 | } catch(Exception e) { 281 | Toast.makeText(getApplicationContext(), "Download failed", Toast.LENGTH_LONG).show(); 282 | 283 | } 284 | } 285 | } else { 286 | try { 287 | Snackbar.make(findViewById(R.id.openbook), "Download failed", Snackbar.LENGTH_LONG).show(); 288 | downloadb.setClickable(true); 289 | downloadb.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary))); 290 | openb.setClickable(false); 291 | openb.setBackgroundTintList(ColorStateList.valueOf(Color.GRAY)); 292 | deleteb.setClickable(false); 293 | deleteb.setBackgroundTintList(ColorStateList.valueOf(Color.GRAY)); 294 | } catch(Exception e) { 295 | Toast.makeText(getApplicationContext(), "Download failed", Toast.LENGTH_LONG).show(); 296 | 297 | } 298 | } 299 | } else { 300 | try { 301 | Snackbar.make(findViewById(R.id.openbook), "Download failed", Snackbar.LENGTH_LONG).show(); 302 | downloadb.setClickable(true); 303 | downloadb.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary))); 304 | openb.setClickable(false); 305 | openb.setBackgroundTintList(ColorStateList.valueOf(Color.GRAY)); 306 | deleteb.setClickable(false); 307 | deleteb.setBackgroundTintList(ColorStateList.valueOf(Color.GRAY)); 308 | } catch(Exception e) { 309 | Toast.makeText(getApplicationContext(), "Download failed", Toast.LENGTH_LONG).show(); 310 | 311 | } 312 | } 313 | } 314 | }; 315 | registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); 316 | } 317 | public void openbook(View view) { 318 | Intent intent = new Intent(getApplicationContext(), PdfRead.class); 319 | intent.putExtra("bookid",bookid); 320 | startActivity(intent); 321 | } 322 | public void deletebook(View view) { 323 | AlertDialog.Builder builder = new AlertDialog.Builder(this); 324 | builder.setMessage("ARE YOU SURE YOU WANT TO DELETE?"); 325 | builder.setCancelable(true); 326 | builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() { 327 | @Override 328 | public void onClick(DialogInterface dialog, int which) { 329 | String filename = Objects.requireNonNull(getApplicationContext().getExternalFilesDir("")).getAbsolutePath() + File.separator + Environment.DIRECTORY_DOWNLOADS + File.separator + bookid.toString(); 330 | File file = new File(filename); 331 | boolean deleted = file.delete(); 332 | if (deleted) { 333 | Snackbar.make(findViewById(R.id.openbook), "Deleted", Snackbar.LENGTH_LONG).show(); 334 | new Synchronise3().execute(); 335 | new Synchronise1().execute(); 336 | } 337 | } 338 | }); 339 | builder.setNegativeButton("No", new DialogInterface.OnClickListener() { 340 | @Override 341 | public void onClick(DialogInterface dialog, int which) { 342 | } 343 | }); 344 | AlertDialog alert = builder.create(); 345 | alert.show(); 346 | } 347 | } -------------------------------------------------------------------------------- /app/src/main/java/com/android/project/elibrary/PdfRead.java: -------------------------------------------------------------------------------- 1 | package com.android.project.elibrary; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.arch.persistence.room.Room; 5 | import android.os.AsyncTask; 6 | import android.os.Environment; 7 | import android.support.design.widget.Snackbar; 8 | import android.support.v7.app.AppCompatActivity; 9 | import android.os.Bundle; 10 | import android.view.Window; 11 | import android.view.WindowManager; 12 | 13 | import com.github.barteksc.pdfviewer.PDFView; 14 | import com.github.barteksc.pdfviewer.listener.OnLoadCompleteListener; 15 | import com.github.barteksc.pdfviewer.listener.OnPageChangeListener; 16 | import com.github.barteksc.pdfviewer.scroll.DefaultScrollHandle; 17 | import java.io.File; 18 | import java.io.FileInputStream; 19 | import java.util.Calendar; 20 | import java.util.Objects; 21 | 22 | 23 | public class PdfRead extends AppCompatActivity implements OnPageChangeListener, OnLoadCompleteListener { 24 | PDFView pdfview; 25 | private int pageNumber; 26 | Integer bookid; 27 | private final static String KEY_CURRENT_PAGE = "current_page"; 28 | @SuppressWarnings("ResultOfMethodCallIgnored") 29 | @Override 30 | protected void onCreate(Bundle savedInstanceState) { 31 | super.onCreate(savedInstanceState); 32 | supportRequestWindowFeature(Window.FEATURE_NO_TITLE); 33 | getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 34 | WindowManager.LayoutParams.FLAG_FULLSCREEN); 35 | setContentView(R.layout.activity_pdf_read); 36 | new Synchronise().execute(); 37 | if (savedInstanceState != null) 38 | { 39 | pageNumber = savedInstanceState.getInt(KEY_CURRENT_PAGE); 40 | } 41 | else 42 | { 43 | pageNumber = -1; 44 | } 45 | pdfview = findViewById(R.id.pdfread); 46 | bookid = Integer.parseInt(Objects.requireNonNull(Objects.requireNonNull(getIntent().getExtras()).get("bookid")).toString()); 47 | String filename= Objects.requireNonNull(getApplicationContext().getExternalFilesDir("")).getAbsolutePath()+File.separator+Environment.DIRECTORY_DOWNLOADS+File.separator+bookid.toString(); 48 | File file = new File(filename); 49 | byte[] byteform = new byte[(int) file.length()]; 50 | try { 51 | FileInputStream fis = new FileInputStream(file); 52 | fis.read(byteform); //read file into bytes[] 53 | fis.close(); 54 | } catch(Exception e) { 55 | Snackbar.make(findViewById(R.id.openbook), e.toString(), Snackbar.LENGTH_LONG).show(); 56 | } 57 | byteform[0] = (byte)(-byteform[0]); 58 | pdfview.fromBytes(byteform).defaultPage(pageNumber) 59 | .onPageChange(this) 60 | .onLoad(this) 61 | .scrollHandle(new DefaultScrollHandle(this)) 62 | .spacing(1) 63 | .load(); 64 | } 65 | @Override 66 | public void onPageChanged(int page, int pageCount){ 67 | pageNumber = page; 68 | } 69 | @Override 70 | public void loadComplete(int nbPages) { 71 | if (pageNumber >= 0) 72 | { 73 | pdfview.jumpTo(pageNumber); 74 | } 75 | } 76 | @Override 77 | protected void onRestoreInstanceState(Bundle savedInstanceState) 78 | { 79 | super.onRestoreInstanceState(savedInstanceState); 80 | pageNumber = savedInstanceState.getInt(KEY_CURRENT_PAGE); 81 | } 82 | 83 | @Override 84 | public void onSaveInstanceState(Bundle outState) 85 | { 86 | super.onSaveInstanceState(outState); 87 | outState.putInt(KEY_CURRENT_PAGE, pageNumber); 88 | } 89 | @SuppressLint("StaticFieldLeak") 90 | private class Synchronise extends AsyncTask { 91 | @Override 92 | protected Integer doInBackground(Void... updates) { 93 | LocalDB localDB = Room.databaseBuilder(getApplicationContext(), LocalDB.class, "localDB").build(); 94 | try { 95 | localDB.downloadDao().update_download(bookid, Calendar.getInstance().getTime()); 96 | } catch (Exception e) { 97 | } 98 | return 1; 99 | } 100 | @Override 101 | protected void onPostExecute(Integer n) { 102 | } 103 | } 104 | } -------------------------------------------------------------------------------- /app/src/main/java/com/android/project/elibrary/Refresh.java: -------------------------------------------------------------------------------- 1 | package com.android.project.elibrary; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.arch.persistence.room.Room; 5 | import android.content.Context; 6 | import android.graphics.Color; 7 | import android.net.ConnectivityManager; 8 | import android.net.NetworkInfo; 9 | import android.os.AsyncTask; 10 | import android.os.Environment; 11 | import android.support.annotation.NonNull; 12 | import android.support.design.widget.Snackbar; 13 | import android.support.v7.app.AppCompatActivity; 14 | import android.os.Bundle; 15 | import android.text.method.ScrollingMovementMethod; 16 | import android.widget.ArrayAdapter; 17 | import android.widget.ListAdapter; 18 | import android.widget.ProgressBar; 19 | import android.widget.TextView; 20 | import android.widget.Toast; 21 | 22 | import com.google.android.gms.tasks.OnCompleteListener; 23 | import com.google.android.gms.tasks.OnSuccessListener; 24 | import com.google.android.gms.tasks.Task; 25 | import com.google.firebase.firestore.DocumentReference; 26 | import com.google.firebase.firestore.DocumentSnapshot; 27 | import com.google.firebase.firestore.FirebaseFirestore; 28 | import com.google.firebase.firestore.QueryDocumentSnapshot; 29 | import com.google.firebase.firestore.QuerySnapshot; 30 | 31 | import org.jsoup.Jsoup; 32 | import org.jsoup.nodes.Document; 33 | import org.jsoup.nodes.Element; 34 | 35 | import java.io.File; 36 | import java.io.FileNotFoundException; 37 | import java.io.FileOutputStream; 38 | import java.io.FileWriter; 39 | import java.io.IOException; 40 | import java.lang.reflect.Array; 41 | import java.util.ArrayList; 42 | import java.util.Calendar; 43 | import java.util.HashMap; 44 | import java.util.List; 45 | import java.util.Map; 46 | import java.util.Objects; 47 | import java.util.concurrent.TimeUnit; 48 | 49 | public class Refresh extends AppCompatActivity { 50 | final ArrayList finalBooks = new ArrayList<>(); 51 | final FirebaseFirestore fdb = FirebaseFirestore.getInstance(); 52 | TextView textView; 53 | QueryDocumentSnapshot sem; 54 | String filename; 55 | File file; 56 | @Override 57 | protected void onCreate(Bundle savedInstanceState) { 58 | super.onCreate(savedInstanceState); 59 | setContentView(R.layout.activity_refresh); 60 | textView = findViewById(R.id.details); 61 | textView.setMovementMethod(new ScrollingMovementMethod()); 62 | filename = Objects.requireNonNull(getApplicationContext().getExternalFilesDir("")).getAbsolutePath() + File.separator + "Log_" + Calendar.getInstance().getTime().toString()+".txt"; 63 | file = new File(filename); 64 | try { 65 | file.createNewFile(); 66 | FileOutputStream fileOuputStream = new FileOutputStream(filename); 67 | fileOuputStream.write(Calendar.getInstance().getTime().toString().getBytes()); 68 | fileOuputStream.write("\n".getBytes()); 69 | fileOuputStream.close(); 70 | } catch (FileNotFoundException e) { 71 | Snackbar.make(findViewById(R.id.refresh), e.toString(), Snackbar.LENGTH_LONG).show(); 72 | } catch (IOException e) { 73 | Snackbar.make(findViewById(R.id.refresh), e.toString(), Snackbar.LENGTH_LONG).show(); 74 | } 75 | textView.append("Begin\n"); 76 | fdb.collection("DEPTCSE").document("SEMESTER II").get().addOnSuccessListener(new OnSuccessListener() { 77 | @Override 78 | public void onSuccess(DocumentSnapshot documentSnapshot) { 79 | fdb.collection("DEPTMEC").document("SEMESTER II").set(documentSnapshot.getData()); 80 | fdb.collection("DEPTMEC").document("SEMESTER II").get().addOnSuccessListener(new OnSuccessListener() { 81 | @Override 82 | public void onSuccess(final DocumentSnapshot documentSnapshot) { 83 | Map map = documentSnapshot.getData(); 84 | for (final Map.Entry entry : Objects.requireNonNull(map).entrySet()) { 85 | fdb.collection("DEPTCSE").document("SEMESTER II").collection(entry.getValue().toString()).get().addOnSuccessListener(new OnSuccessListener() { 86 | @Override 87 | public void onSuccess(QuerySnapshot queryDocumentSnapshots) { 88 | for (QueryDocumentSnapshot documentSnapshot1 : queryDocumentSnapshots) { 89 | fdb.collection("DEPTMEC").document("SEMESTER II").collection(entry.getValue().toString()).document(documentSnapshot1.getId()).set(documentSnapshot1.getData()); 90 | } 91 | } 92 | }); 93 | } 94 | } 95 | }); 96 | } 97 | }); 98 | /*fdb.collection("DEPTCSE").get().addOnSuccessListener(new OnSuccessListener() {//FROM 99 | @Override 100 | public void onSuccess(QuerySnapshot queryDocumentSnapshots) {//TO 101 | for(QueryDocumentSnapshot documentSnapshot: queryDocumentSnapshots) { 102 | if(documentSnapshot.getId().equals("SEMESTER II")) { 103 | fdb.collection("DEPTECE").document("SEMESTER II").set(documentSnapshot.getData()); 104 | fdb.collection("DEPTECE").document("SEMESTER II").get().addOnSuccessListener(new OnSuccessListener() { 105 | @Override 106 | public void onSuccess(final DocumentSnapshot documentSnapshot) { 107 | Map map = documentSnapshot.getData(); 108 | for (final Map.Entry entry : Objects.requireNonNull(map).entrySet()) { 109 | fdb.collection("DEPTCSE").document("SEMESTER II").collection(entry.getValue().toString()).get().addOnSuccessListener(new OnSuccessListener() { 110 | @Override 111 | public void onSuccess(QuerySnapshot queryDocumentSnapshots) { 112 | for (QueryDocumentSnapshot documentSnapshot1 : queryDocumentSnapshots) { 113 | fdb.collection("DEPTECE").document("SEMESTER II").collection(entry.getValue().toString()).document(documentSnapshot1.getId()).set(documentSnapshot1.getData()); 114 | } 115 | } 116 | }); 117 | } 118 | } 119 | }); 120 | } 121 | } 122 | } 123 | });*/ 124 | /*fdb.collection("departments").get().addOnCompleteListener(new OnCompleteListener() { 125 | @Override 126 | public void onComplete(@NonNull Task task) { 127 | if(task.isSuccessful()) { 128 | for (final QueryDocumentSnapshot dept : task.getResult()) { 129 | //traversing through every document in the collection 130 | fdb.collection(dept.getId()).get().addOnCompleteListener(new OnCompleteListener() { 131 | @Override 132 | public void onComplete(@NonNull Task task) { 133 | if(task.isSuccessful()) { 134 | for (QueryDocumentSnapshot semtemp : task.getResult()) { 135 | sem = semtemp; 136 | fdb.collection(dept.getId()).document(sem.getId()).get().addOnCompleteListener(new OnCompleteListener() { 137 | @Override 138 | public void onComplete(@NonNull Task task) { 139 | if(task.isSuccessful()) { 140 | Map map = task.getResult().getData(); 141 | for (final Map.Entry entry : Objects.requireNonNull(map).entrySet()) { 142 | //entry.getkey contains all the courseids 143 | fdb.collection(dept.getId()).document(sem.getId()).collection(entry.getValue().toString()).get().addOnCompleteListener(new OnCompleteListener() { 144 | @Override 145 | public void onComplete(@NonNull Task task) { 146 | if(task.isSuccessful()) { 147 | //through every book 148 | ArrayList books = new ArrayList<>(); 149 | for(QueryDocumentSnapshot book : task.getResult()) { 150 | books.add(book); 151 | } 152 | Synchronise1 synchronise1 = new Synchronise1(); 153 | synchronise1.dept = dept.getId(); 154 | synchronise1.course = entry.getValue().toString(); 155 | synchronise1.innersem = sem.getId(); 156 | synchronise1.execute(books); 157 | } 158 | } 159 | }); 160 | } 161 | } 162 | } 163 | }); 164 | } 165 | } 166 | } 167 | }); 168 | } 169 | } 170 | } 171 | });*/ 172 | fdb.collection("departments").get().addOnCompleteListener(new OnCompleteListener() { 173 | @Override 174 | public void onComplete(@NonNull Task task) { 175 | if(task.isSuccessful()) { 176 | final ArrayList fdepts = new ArrayList<>(); 177 | for (QueryDocumentSnapshot document : task.getResult()) { 178 | //traversing through every document in the collection 179 | fdepts.add(document.getId()); 180 | } 181 | for(final String fdept : fdepts) { 182 | fdb.collection(fdept).get().addOnCompleteListener(new OnCompleteListener() { 183 | @Override 184 | public void onComplete(@NonNull Task task) { 185 | if(task.isSuccessful()) { 186 | ArrayList fsems = new ArrayList<>(); 187 | for(QueryDocumentSnapshot document : task.getResult()) { 188 | fsems.add(document.getId()); 189 | } 190 | for(final String fsem : fsems) { 191 | fdb.collection(fdept).document(fsem).get().addOnCompleteListener(new OnCompleteListener() { 192 | @Override 193 | public void onComplete(@NonNull Task task) { 194 | if(task.isSuccessful()) { 195 | ArrayList fcourses = new ArrayList<>(); 196 | Map map = task.getResult().getData(); 197 | for (final Map.Entry entry : Objects.requireNonNull(map).entrySet()) { 198 | fcourses.add(entry.getValue().toString()); 199 | } 200 | for(final String fcourse : fcourses) { 201 | fdb.collection(fdept).document(fsem).collection(fcourse).get().addOnCompleteListener(new OnCompleteListener() { 202 | @Override 203 | public void onComplete(@NonNull Task task) { 204 | if(task.isSuccessful()) { 205 | ArrayList books = new ArrayList<>(); 206 | for(QueryDocumentSnapshot book : task.getResult()) { 207 | books.add(book); 208 | } 209 | Synchronise1 synchronise1 = new Synchronise1(); 210 | synchronise1.dept = fdept; 211 | synchronise1.course = fcourse; 212 | synchronise1.innersem = fsem; 213 | synchronise1.execute(books); 214 | } 215 | } 216 | }); 217 | } 218 | } 219 | } 220 | }); 221 | } 222 | } 223 | } 224 | }); 225 | } 226 | } 227 | } 228 | }); 229 | } 230 | Boolean flag1 = false, flag2 = false, flag3 = false; 231 | @SuppressLint("StaticFieldLeak") 232 | private class Synchronise1 extends AsyncTask,String,Integer> { 233 | public String dept, course, innersem; 234 | @Override 235 | protected Integer doInBackground(ArrayList... books) { 236 | for(QueryDocumentSnapshot book: books[0]) { 237 | publishProgress(dept+">"+innersem+">"+course+">"+book.getId()+": "); 238 | Document document; 239 | String newlink, url; 240 | //Create url 241 | url = "http://www.mediafire.com/file/"; 242 | int pos, slashcount = 0; 243 | for (pos = 0; slashcount < 4; pos++) { 244 | if (book.getString("link").charAt(pos) == '/') { 245 | slashcount++; 246 | } 247 | } 248 | url = url + book.getString("link").substring(pos); 249 | try { 250 | document = Jsoup.connect(url).userAgent("Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0").get(); 251 | try { 252 | Element linkelement = document.select("div[class=download_link]").first(); 253 | linkelement = linkelement.child(1); 254 | newlink = linkelement.attributes().get("href"); 255 | newlink = "https://" + newlink.substring(7); 256 | //Toast.makeText(getApplicationContext(),newlink,Toast.LENGTH_LONG).show(); 257 | if (newlink.substring(0, 16).equals("https://download")) { 258 | fdb.collection(dept).document(innersem).collection(course).document(book.getId()).update("link",newlink); 259 | fdb.collection("failed_links").document(book.getId()).delete(); 260 | //Toast.makeText(getApplicationContext(), newlink, Toast.LENGTH_LONG).show(); 261 | //todo succesully obtained link 262 | publishProgress("Successfully updated\n"); 263 | } else { 264 | publishProgress("New link invalid\n"); 265 | 266 | } 267 | } catch (Exception e) { 268 | //todo will occur if they change webpage format 269 | //Toast.makeText(getApplicationContext(),e.toString(),Toast.LENGTH_LONG).show(); 270 | publishProgress("New link not found\n"); 271 | 272 | } 273 | } catch (IOException e) { 274 | //todo comes here due to copystrike 275 | publishProgress("Copyright claim\n"); 276 | } 277 | } 278 | return 1; 279 | } 280 | 281 | @Override 282 | protected void onProgressUpdate(String... text) { 283 | textView.append(text[0]); 284 | try { 285 | FileOutputStream fileOuputStream = new FileOutputStream(filename,true); 286 | fileOuputStream.write(text[0].getBytes()); 287 | fileOuputStream.close(); 288 | } catch (FileNotFoundException e) { 289 | //Do nothing 290 | } catch (IOException e) { 291 | //Do nothing 292 | } 293 | } 294 | @Override 295 | protected void onPostExecute(Integer n) { 296 | 297 | } 298 | } 299 | } 300 | -------------------------------------------------------------------------------- /app/src/main/java/com/android/project/elibrary/SearchableActivity.java: -------------------------------------------------------------------------------- 1 | package com.android.project.elibrary; 2 | 3 | import android.app.AlertDialog; 4 | import android.app.ListActivity; 5 | import android.app.SearchManager; 6 | import android.content.Intent; 7 | import android.content.SharedPreferences; 8 | import android.os.Bundle; 9 | import android.view.View; 10 | import android.widget.ArrayAdapter; 11 | import android.widget.ListAdapter; 12 | import android.widget.ListView; 13 | import android.widget.ProgressBar; 14 | import android.widget.Toast; 15 | 16 | import com.google.gson.Gson; 17 | 18 | import java.util.ArrayList; 19 | 20 | public class SearchableActivity extends ListActivity { 21 | ArrayList bdept = new ArrayList<>(); 22 | ArrayList bsem = new ArrayList<>(); 23 | ArrayList bcourse = new ArrayList<>(); 24 | ArrayList bid = new ArrayList<>(); 25 | ArrayList bname = new ArrayList<>(); 26 | ArrayList blink = new ArrayList<>(); 27 | AlertDialog.Builder builder; 28 | AlertDialog alert; 29 | LocalData localData; 30 | @Override 31 | protected void onCreate(Bundle savedInstanceState) { 32 | super.onCreate(savedInstanceState); 33 | Intent intent = getIntent(); 34 | if (Intent.ACTION_SEARCH.equals(intent.getAction())) { 35 | 36 | final String query = intent.getStringExtra(SearchManager.QUERY); 37 | builder = new AlertDialog.Builder(SearchableActivity.this); 38 | builder.setMessage("Searching..."); 39 | ProgressBar progressBar = new ProgressBar(SearchableActivity.this,null, android.R.attr.progressBarStyle); 40 | builder.setView(progressBar); 41 | builder.setCancelable(false); 42 | alert = builder.create(); 43 | alert.show(); 44 | try { 45 | SharedPreferences sharedPreferences = getSharedPreferences("Data",MODE_PRIVATE); 46 | Gson gson = new Gson(); 47 | String json = sharedPreferences.getString("localData", ""); 48 | 49 | localData = gson.fromJson(json, LocalData.class); 50 | for(Department department : localData.departments.values()) { 51 | for(Semester semester : department.semesters.values()) { 52 | for(Course course : semester.courses.values()) { 53 | for(Book book : course.books.values()) { 54 | if(book.name.toUpperCase().contains(query.toUpperCase()) && !bid.contains(Integer.valueOf(book.bookid).toString())) { 55 | bname.add(book.name); 56 | bdept.add(department.name.substring(4)); 57 | bsem.add(semester.name); 58 | bcourse.add(course.courseid); 59 | blink.add(book.link); 60 | bid.add(Integer.valueOf(book.bookid).toString()); 61 | } 62 | } 63 | } 64 | } 65 | } 66 | alert.cancel(); 67 | if(bname.isEmpty()) { 68 | Toast.makeText(getApplicationContext(),"No result", Toast.LENGTH_LONG).show(); 69 | finish(); 70 | } 71 | ListAdapter adapter; 72 | try { 73 | adapter = new ArrayAdapter<>(SearchableActivity.this, android.R.layout.simple_list_item_1, bname); 74 | setListAdapter(adapter); 75 | } catch(Exception ignored) { 76 | } 77 | } catch(Exception e) { 78 | alert.cancel(); 79 | } 80 | } 81 | } 82 | protected void onListItemClick (ListView l, 83 | View v, 84 | int position, 85 | long id) { 86 | try { 87 | Intent intent = new Intent(getApplicationContext(), OpenBook.class); 88 | intent.putExtra("bookid", bid.get(position)); 89 | intent.putExtra("name", bname.get(position)); 90 | intent.putExtra("department", bdept.get(position)); 91 | intent.putExtra("semester", bsem.get(position)); 92 | intent.putExtra("courseid", bcourse.get(position)); 93 | intent.putExtra("link",blink.get(position)); 94 | startActivity(intent); 95 | } catch(Exception e) { 96 | Toast.makeText(getApplicationContext(),e.toString(),Toast.LENGTH_LONG).show(); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /app/src/main/java/com/android/project/elibrary/Semester.java: -------------------------------------------------------------------------------- 1 | package com.android.project.elibrary; 2 | 3 | import java.util.Map; 4 | 5 | public class Semester { 6 | Map courses; 7 | String name; 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/android/project/elibrary/SemesterList.java: -------------------------------------------------------------------------------- 1 | package com.android.project.elibrary; 2 | 3 | import android.content.Intent; 4 | import android.content.SharedPreferences; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.os.Bundle; 7 | import android.view.View; 8 | import android.widget.AdapterView; 9 | import android.widget.ArrayAdapter; 10 | import android.widget.ListAdapter; 11 | import android.widget.ListView; 12 | import android.widget.TextView; 13 | import android.widget.Toast; 14 | 15 | import com.google.gson.Gson; 16 | 17 | import java.util.Arrays; 18 | import java.util.Objects; 19 | 20 | public class SemesterList extends AppCompatActivity { 21 | String[] semesters; 22 | LocalData localData; 23 | @Override 24 | protected void onCreate(Bundle savedInstanceState) { 25 | super.onCreate(savedInstanceState); 26 | setContentView(R.layout.activity_semester_list); 27 | final String department = Objects.requireNonNull(Objects.requireNonNull(getIntent().getExtras()).get("department")).toString(); 28 | TextView textview = findViewById(R.id.deptname); 29 | textview.setText(department.toUpperCase()); 30 | try { 31 | SharedPreferences sharedPreferences = getSharedPreferences("Data",MODE_PRIVATE); 32 | Gson gson = new Gson(); 33 | String json = sharedPreferences.getString("localData", ""); 34 | localData = gson.fromJson(json, LocalData.class); 35 | semesters = Objects.requireNonNull(localData.departments.get("DEPT" + department)).semesters.keySet().toArray(new String[0]); 36 | Arrays.sort(semesters); 37 | ListAdapter adapter = new ArrayAdapter<>(SemesterList.this, android.R.layout.simple_list_item_1, semesters); 38 | ListView listView = findViewById(R.id.semlist); 39 | listView.setAdapter(adapter); 40 | listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 41 | @Override 42 | public void onItemClick(AdapterView adapterView, View view, int i, long l) { 43 | Intent intent = new Intent(getApplicationContext(),CourseList.class); 44 | intent.putExtra("department", department); 45 | intent.putExtra("semester",semesters[i]); 46 | startActivity(intent); 47 | } 48 | }); 49 | } catch(Exception e) { 50 | Toast.makeText(getApplicationContext(),e.toString(),Toast.LENGTH_LONG).show(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_library_books.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu_bug.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu_camera.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu_gallery.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu_manage.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu_send.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu_share.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu_slideshow.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/side_nav_bar.xml: -------------------------------------------------------------------------------- 1 | 3 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_admin.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 26 | 27 | 40 | 41 |