Skip to content

Commit 1246d1a

Browse files
committed
initial commit
1 parent 305305b commit 1246d1a

File tree

72 files changed

+2680
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+2680
-0
lines changed

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2022 Vinayak Patil
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
### <center> Questioner - An Offline Quiz App </center>
2+
#### Fetures
3+
4+
- Cleaner interface
5+
- Demo Topic Creation
6+
- Works Offline
7+
- Add/Remove Topic
8+
- Time Limit for Questions
9+
- Clean and Simple Coding
10+
- Add/Remove Questions
11+
- Local Account Creation
12+
- Animations for wrong and correct option selection
13+
14+
15+
[<img src="media/app.jpg" />](https://t.me/vinayak_09)
16+
17+
#### Prerequisites :
18+
- Android Studio
19+
- Basic knowledge about android app developing.
20+
21+
#### How to Build this Project?
22+
- Clone this project or Download Zip.
23+
- Extract it and Open the Project in Android Studio.
24+
- Wait to download required files.
25+
- Build App.
26+
- Install and Open.
27+
- Login using Admin's credentials (Username - admin | Password - admin).
28+
- Click on Create Demo Quiz button for testing.
29+
- Click top right dots and logout.
30+
- Create account and login using new created account.
31+
32+
### FAQs
33+
1. Other Questions.<br>
34+
-->Feel free to Connect with me on Telegram [@vinayak_09](http://t.me/vinayak_09).
35+
36+
#### PS:NOTE
37+
- You can download [Questioner Android App Demo](https://drive.google.com/file/d/1GtHpXUbQXo-aK5wZVSAJqLRcYMhABBLv/view?usp=sharing)
38+
39+
------------
40+
41+
Full Project demonstration Youtube :<br>
42+
Link - https://youtu.be/lWN9nhKnIZo
43+

app/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

app/build.gradle

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
plugins {
2+
id 'com.android.application'
3+
}
4+
5+
android {
6+
compileSdk 32
7+
8+
defaultConfig {
9+
applicationId "com.example.questioner"
10+
minSdk 24
11+
targetSdk 32
12+
versionCode 1
13+
versionName "1.0"
14+
15+
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
16+
}
17+
18+
buildTypes {
19+
release {
20+
minifyEnabled false
21+
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
22+
}
23+
}
24+
compileOptions {
25+
sourceCompatibility JavaVersion.VERSION_1_8
26+
targetCompatibility JavaVersion.VERSION_1_8
27+
}
28+
}
29+
30+
dependencies {
31+
32+
implementation 'androidx.appcompat:appcompat:1.4.2'
33+
implementation 'com.google.android.material:material:1.6.1'
34+
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
35+
testImplementation 'junit:junit:4.13.2'
36+
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
37+
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
38+
}

app/proguard-rules.pro

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.example.questioner;
2+
3+
import android.content.Context;
4+
5+
import androidx.test.platform.app.InstrumentationRegistry;
6+
import androidx.test.ext.junit.runners.AndroidJUnit4;
7+
8+
import org.junit.Test;
9+
import org.junit.runner.RunWith;
10+
11+
import static org.junit.Assert.*;
12+
13+
/**
14+
* Instrumented test, which will execute on an Android device.
15+
*
16+
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
17+
*/
18+
@RunWith(AndroidJUnit4.class)
19+
public class ExampleInstrumentedTest {
20+
@Test
21+
public void useAppContext() {
22+
// Context of the app under test.
23+
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
24+
assertEquals("com.example.questioner", appContext.getPackageName());
25+
}
26+
}

app/src/main/AndroidManifest.xml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:tools="http://schemas.android.com/tools"
4+
package="com.example.questioner">
5+
6+
<application
7+
android:allowBackup="true"
8+
android:dataExtractionRules="@xml/data_extraction_rules"
9+
android:fullBackupContent="@xml/backup_rules"
10+
android:icon="@mipmap/ic_launcher"
11+
android:label="@string/app_name"
12+
android:roundIcon="@mipmap/ic_launcher_round"
13+
android:supportsRtl="true"
14+
android:theme="@style/Theme.Questioner"
15+
tools:targetApi="31">
16+
<activity
17+
android:name=".ResultActivity"
18+
android:exported="false" />
19+
<activity
20+
android:name=".AddQuestionActivity"
21+
android:exported="false" />
22+
<activity
23+
android:name=".QuestionActivity"
24+
android:exported="false" />
25+
<activity
26+
android:name=".AdminTopicActivity"
27+
android:exported="false" />
28+
<activity
29+
android:name=".AdminMainActivity"
30+
android:exported="false" />
31+
<activity
32+
android:name=".TopicActivity"
33+
android:exported="false" />
34+
<activity
35+
android:name=".RegisterActivity"
36+
android:exported="false" />
37+
<activity
38+
android:name=".LoginActivity"
39+
android:exported="false" />
40+
<activity
41+
android:name=".SplashScreenActivity"
42+
android:exported="true">
43+
<intent-filter>
44+
<action android:name="android.intent.action.MAIN" />
45+
46+
<category android:name="android.intent.category.LAUNCHER" />
47+
</intent-filter>
48+
</activity>
49+
</application>
50+
51+
</manifest>
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package com.example.questioner;
2+
3+
import androidx.appcompat.app.AppCompatActivity;
4+
5+
import android.os.Bundle;
6+
import android.widget.ArrayAdapter;
7+
import android.widget.EditText;
8+
import android.widget.Spinner;
9+
import android.widget.Toast;
10+
11+
public class AddQuestionActivity extends AppCompatActivity {
12+
13+
MyDbHelper myDbHelper;
14+
EditText optionAEditText,optionBEditText, optionCEditText, optionDEditText, questionEditText;
15+
@Override
16+
protected void onCreate(Bundle savedInstanceState) {
17+
super.onCreate(savedInstanceState);
18+
setContentView(R.layout.activity_add_question);
19+
20+
myDbHelper = new MyDbHelper(this);
21+
22+
questionEditText = findViewById(R.id.addQuestionEditText);
23+
optionAEditText = findViewById(R.id.addQuestionOptionA);
24+
optionBEditText = findViewById(R.id.addQuestionOptionB);
25+
optionCEditText = findViewById(R.id.addQuestionOptionC);
26+
optionDEditText = findViewById(R.id.addQuestionOptionD);
27+
28+
Spinner spinner = findViewById(R.id.addQuestionSpinner);
29+
ArrayAdapter<String> arrayAdapterTopics = new ArrayAdapter<>(this, androidx.appcompat.R.layout.support_simple_spinner_dropdown_item, myDbHelper.getAllTopics());
30+
spinner.setAdapter(arrayAdapterTopics);
31+
32+
Spinner spinnerAnswer = findViewById(R.id.addQuestionSpinnerAnswer);
33+
ArrayAdapter<String> arrayAdapterAnswer = new ArrayAdapter<>(this, androidx.appcompat.R.layout.support_simple_spinner_dropdown_item, new String[]{"A", "B", "C", "D"});
34+
spinnerAnswer.setAdapter(arrayAdapterAnswer);
35+
36+
spinner.setSelection(0);
37+
spinnerAnswer.setSelection(0);
38+
39+
40+
findViewById(R.id.addQuestionButton).setOnClickListener(view -> {
41+
if(arrayAdapterTopics.getCount() > 0){
42+
addQuestionToDb(spinner.getSelectedItem().toString(),
43+
questionEditText.getText().toString().trim(),
44+
optionAEditText.getText().toString().trim(),
45+
optionBEditText.getText().toString().trim(),
46+
optionCEditText.getText().toString().trim(),
47+
optionDEditText.getText().toString().trim(),
48+
spinnerAnswer.getSelectedItem().toString());
49+
}else {
50+
Toast.makeText(AddQuestionActivity.this, "Please Add Few Topics First To Proceed", Toast.LENGTH_SHORT).show();
51+
}
52+
});
53+
}
54+
55+
private void addQuestionToDb(String topic, String question, String optionA, String optionB, String optionC, String optionD, String correctOption) {
56+
if(question.isEmpty() || optionA.isEmpty() || optionB.isEmpty() || optionC.isEmpty() || optionD.isEmpty()){
57+
Toast.makeText(this, "Fill all the fields!", Toast.LENGTH_SHORT).show();
58+
}else{
59+
long result = myDbHelper.addQuestion(question,optionA,optionB,optionC,optionD,correctOption,topic);
60+
if(result == -1){
61+
Toast.makeText(this, "Error!", Toast.LENGTH_SHORT).show();
62+
}else{
63+
Toast.makeText(this, "Question Added!", Toast.LENGTH_SHORT).show();
64+
}
65+
}
66+
}
67+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package com.example.questioner;
2+
3+
import androidx.appcompat.app.AppCompatActivity;
4+
5+
import android.content.Intent;
6+
import android.content.SharedPreferences;
7+
import android.os.Bundle;
8+
import android.view.MenuInflater;
9+
import android.view.MenuItem;
10+
import android.view.View;
11+
import android.widget.PopupMenu;
12+
import android.widget.Toast;
13+
14+
public class AdminMainActivity extends AppCompatActivity {
15+
16+
MyDbHelper dbHelper;
17+
@Override
18+
protected void onCreate(Bundle savedInstanceState) {
19+
super.onCreate(savedInstanceState);
20+
setContentView(R.layout.activity_admin_main);
21+
dbHelper = new MyDbHelper(this);
22+
23+
24+
findViewById(R.id.topic_more).setOnClickListener(view -> showPopUpMenu(view));
25+
26+
27+
findViewById(R.id.adminMainAddQuestions).setOnClickListener(new View.OnClickListener() {
28+
@Override
29+
public void onClick(View view) {
30+
startActivity(new Intent(AdminMainActivity.this,AddQuestionActivity.class));
31+
}
32+
});
33+
34+
findViewById(R.id.adminMainAddRemove).setOnClickListener(new View.OnClickListener() {
35+
@Override
36+
public void onClick(View view) {
37+
startActivity(new Intent(AdminMainActivity.this,AdminTopicActivity.class));
38+
}
39+
});
40+
41+
42+
findViewById(R.id.adminDemo).setOnClickListener(new View.OnClickListener() {
43+
@Override
44+
public void onClick(View view) {
45+
SharedPreferences sharedPreferences = getSharedPreferences("QUESTIONER",MODE_PRIVATE);
46+
if(sharedPreferences.getBoolean("DemoCreated",false)){
47+
Toast.makeText(AdminMainActivity.this, "Demo Quiz already created!", Toast.LENGTH_SHORT).show();
48+
}else {
49+
SharedPreferences.Editor editor = sharedPreferences.edit();
50+
editor.putBoolean("DemoCreated",true);
51+
editor.apply();
52+
dbHelper.createDemoQuiz();
53+
Toast.makeText(AdminMainActivity.this, "Created!", Toast.LENGTH_SHORT).show();
54+
}
55+
56+
}
57+
});
58+
}
59+
60+
private void showPopUpMenu(View view){
61+
PopupMenu popupMenu = new PopupMenu(AdminMainActivity.this,view);
62+
MenuInflater inflater = popupMenu.getMenuInflater();
63+
inflater.inflate(R.menu.topic_screen_menu,popupMenu.getMenu());
64+
popupMenu.show();
65+
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
66+
@Override
67+
public boolean onMenuItemClick(MenuItem menuItem) {
68+
startActivity(new Intent(AdminMainActivity.this,LoginActivity.class));
69+
AdminMainActivity.this.finish();
70+
return true;
71+
}
72+
});
73+
}
74+
}

0 commit comments

Comments
 (0)