Merge gamification branch with master (#1752)

* Quiz  (#1629)

*  Layout inflated

*  Layout for mcq added

*  Inflated Basic Layout

*  Implemented basic flow

*  Added the basic implementation pf score

*  Added the result layout

*  Added the result layout

*  Added functionality to set result

*  Changed the launcher intent to Quiz Activity for testing purpose

*  Explanations of answers added

*  Improved the layout of quiz result a bit

*  Fixed some minor issues

*  Fixed build issues

* Api Added and basic structure for calling implemented

* Added intents

*  Added the title

*  Fixed image error and improved quality of pr

*  Made separate class for checking quiz

*  Added counter

* Implemented back and next for quiz result

*  Added back functionality to quiz

*  Added progressBar

*  Fixed bugs

*  Improved code quality

*  Imporved code Quality

*  Updated strings

*  Added share screenshot function

*  Added checks and improved UI

*  Removed unused string

*  Removed unused string

* Adding checks and improving code quality

* Changed string

* Improved code quality

* Update strings.xml

* Update MediaWikiApi.java

* Fix build
This commit is contained in:
Vivek Maskara 2018-07-28 01:09:23 +05:30 committed by GitHub
parent 80068f7e9f
commit 386bd0a106
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 1067 additions and 8 deletions

View file

@ -9,6 +9,7 @@ import com.viewpagerindicator.CirclePageIndicator;
import butterknife.BindView;
import butterknife.ButterKnife;
import fr.free.nrw.commons.quiz.QuizActivity;
import fr.free.nrw.commons.theme.BaseActivity;
public class WelcomeActivity extends BaseActivity {
@ -17,6 +18,7 @@ public class WelcomeActivity extends BaseActivity {
@BindView(R.id.welcomePagerIndicator) CirclePageIndicator indicator;
private WelcomePagerAdapter adapter = new WelcomePagerAdapter();
private boolean isQuiz;
/**
* Initialises exiting fields and dependencies
@ -28,6 +30,15 @@ public class WelcomeActivity extends BaseActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
if(getIntent() != null) {
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
isQuiz = bundle.getBoolean("isQuiz");
}
} else{
isQuiz = false;
}
ButterKnife.bind(this);
pager.setAdapter(adapter);
@ -40,6 +51,10 @@ public class WelcomeActivity extends BaseActivity {
*/
@Override
public void onDestroy() {
if(isQuiz){
Intent i = new Intent(WelcomeActivity.this, QuizActivity.class);
startActivity(i);
}
adapter.setCallback(null);
super.onDestroy();
}

View file

@ -221,7 +221,7 @@ public class AchievementsActivity extends NavigationBaseActivity {
private void setRevertCount(){
if(checkAccount()) {
compositeDisposable.add(mediaWikiApi
.getRevertCount(sessionManager.getCurrentAccount().name)
.getRevertRespObjectSingle(sessionManager.getCurrentAccount().name)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(

View file

@ -1,5 +1,6 @@
package fr.free.nrw.commons.contributions;
import android.accounts.Account;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@ -34,8 +35,10 @@ import fr.free.nrw.commons.auth.AuthenticatedActivity;
import fr.free.nrw.commons.auth.SessionManager;
import fr.free.nrw.commons.media.MediaDetailPagerFragment;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import fr.free.nrw.commons.quiz.QuizChecker;
import fr.free.nrw.commons.settings.Prefs;
import fr.free.nrw.commons.upload.UploadService;
import fr.free.nrw.commons.utils.ViewUtil;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
@ -137,10 +140,17 @@ public class ContributionsActivity
getSupportLoaderManager().initLoader(0, null, this);
}
requestAuthToken();
initDrawer();
setTitle(getString(R.string.title_activity_contributions));
if(checkAccount()) {
new QuizChecker(this,
sessionManager.getCurrentAccount().name,
mediaWikiApi);
}
if(!BuildConfig.FLAVOR.equalsIgnoreCase("beta")){
setUploadCount();
}
@ -338,6 +348,21 @@ public class ContributionsActivity
}
}
/**
* to ensure user is logged in
* @return
*/
private boolean checkAccount() {
Account currentAccount = sessionManager.getCurrentAccount();
if (currentAccount == null) {
Timber.d("Current account is null");
ViewUtil.showLongToast(this, getResources().getString(R.string.user_not_logged_in));
sessionManager.forceLogin(this);
return false;
}
return true;
}
@Override
public void onBackStackChanged() {
initBackButton();

View file

@ -894,6 +894,7 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
}
/**
* Checks to see if a user is currently blocked from Commons
* @return whether or not the user is blocked from Commons
*/
@ -964,7 +965,7 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
*/
@NonNull
@Override
public Single<JSONObject> getRevertCount(String userName){
public Single<JSONObject> getRevertRespObjectSingle(String userName){
final String fetchRevertCountUrlTemplate =
wikiMediaToolforgeUrl + "urbanecmbot/commonsmisc/feedback.py";
return Single.fromCallable(() -> {

View file

@ -97,14 +97,14 @@ public interface MediaWikiApi {
@NonNull
Single<Integer> getUploadCount(String userName);
@NonNull
Single<JSONObject> getRevertRespObjectSingle(String userName);
boolean isUserBlockedFromCommons();
@NonNull
Single<JSONObject> getAchievements(String userName);
@NonNull
Single<JSONObject> getRevertCount(String userName);
interface ProgressListener {
void onProgress(long transferred, long total);
}

View file

@ -0,0 +1,165 @@
package fr.free.nrw.commons.quiz;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.graphics.drawable.VectorDrawableCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.RadioButton;
import android.widget.TextView;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.drawable.ProgressBarDrawable;
import com.facebook.drawee.generic.GenericDraweeHierarchy;
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder;
import com.facebook.drawee.view.SimpleDraweeView;
import java.util.ArrayList;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.contributions.ContributionsActivity;
public class QuizActivity extends AppCompatActivity {
@BindView(R.id.question_image) SimpleDraweeView imageView;
@BindView(R.id.question_text) TextView questionText;
@BindView(R.id.question_title) TextView questionTitle;
@BindView(R.id.quiz_positive_answer) RadioButton positiveAnswer;
@BindView(R.id.quiz_negative_answer) RadioButton negativeAnswer;
@BindView(R.id.toolbar) Toolbar toolbar;
private QuizController quizController = new QuizController();
private ArrayList<QuizQuestion> quiz = new ArrayList<QuizQuestion>();
private int questionIndex = 0;
private int score;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz);
Fresco.initialize(this);
quizController.initialize(this);
ButterKnife.bind(this);
setSupportActionBar(toolbar);
displayQuestion();
}
/**
* to move to next question and check whether answer is selected or not
*/
@OnClick(R.id.next_button)
public void setNextQuestion(){
if( questionIndex <= quiz.size() && (positiveAnswer.isChecked() || negativeAnswer.isChecked())) {
evaluateScore();
} else if ( !positiveAnswer.isChecked() && !negativeAnswer.isChecked()){
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle(getResources().getString(R.string.warning));
alert.setMessage(getResources().getString(R.string.warning_for_no_answer));
alert.setPositiveButton(R.string.continue_message, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
AlertDialog dialog = alert.create();
dialog.show();
}
}
/**
* to give warning before ending quiz
*/
@Override
public void onBackPressed() {
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle(getResources().getString(R.string.warning));
alert.setMessage(getResources().getString(R.string.quiz_back_button));
alert.setPositiveButton(R.string.continue_message, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent i = new Intent(QuizActivity.this, QuizResultActivity.class);
dialog.dismiss();
i.putExtra("QuizResult",score);
startActivity(i);
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
});
AlertDialog dialog = alert.create();
dialog.show();
}
/**
* to display the question
*/
public void displayQuestion() {
quiz = quizController.getQuiz();
questionText.setText(quiz.get(questionIndex).getQuestion());
questionTitle.setText(getResources().getString(R.string.question)+quiz.get(questionIndex).getQuestionNumber());
imageView.setHierarchy(GenericDraweeHierarchyBuilder
.newInstance(getResources())
.setFailureImage(VectorDrawableCompat.create(getResources(),
R.drawable.ic_error_outline_black_24dp, getTheme()))
.setProgressBarImage(new ProgressBarDrawable())
.build());
imageView.setImageURI(quiz.get(questionIndex).getUrl());
new RadioGroupHelper(this, R.id.quiz_positive_answer, R.id.quiz_negative_answer);
positiveAnswer.setChecked(false);
negativeAnswer.setChecked(false);
}
/**
* to evaluate score and check whether answer is correct or wrong
*/
public void evaluateScore() {
if((quiz.get(questionIndex).isAnswer() && positiveAnswer.isChecked()) ||
(!quiz.get(questionIndex).isAnswer() && negativeAnswer.isChecked()) ){
customAlert(getResources().getString(R.string.correct),quiz.get(questionIndex).getAnswerMessage() );
score++;
} else{
customAlert(getResources().getString(R.string.wrong), quiz.get(questionIndex).getAnswerMessage());
}
}
/**
* to display explanation after each answer, update questionIndex and move to next question
* @param title
* @param Message
*/
public void customAlert(String title, String Message) {
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle(title);
alert.setMessage(Message);
alert.setPositiveButton(R.string.continue_message, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
questionIndex++;
if(questionIndex == quiz.size()){
Intent i = new Intent(QuizActivity.this, QuizResultActivity.class);
dialog.dismiss();
i.putExtra("QuizResult",score);
startActivity(i);
}else {
displayQuestion();
}
}
});
AlertDialog dialog = alert.create();
dialog.show();
}
}

View file

@ -0,0 +1,160 @@
package fr.free.nrw.commons.quiz;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v7.app.AlertDialog.Builder;
import android.util.Log;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.WelcomeActivity;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
import timber.log.Timber;
/**
* fetches the number of images uploaded and number of images reverted.
* Then it calculates the percentage of the images reverted
* if the percentage of images reverted after last quiz exceeds 50% and number of images uploaded is
* greater than 50, then quiz is popped up
*/
public class QuizChecker {
private int revertCount ;
private int totalUploadCount ;
private boolean isRevertCountFetched;
private boolean isUploadCountFetched;
private CompositeDisposable compositeDisposable = new CompositeDisposable();
public Context context;
private String userName;
private MediaWikiApi mediaWikiApi;
private SharedPreferences revertPref;
private SharedPreferences countPref;
private final int UPLOAD_COUNT_THRESHOLD = 5;
private final String REVERT_PERCENTAGE_FOR_MESSAGE = "50%";
private final String REVERT_SHARED_PREFERENCE = "revertCount";
private final String UPLOAD_SHARED_PREFERENCE = "uploadCount";
/**
* constructor to set the parameters for quiz
* @param context
* @param userName
* @param mediaWikiApi
*/
public QuizChecker(Context context, String userName, MediaWikiApi mediaWikiApi) {
this.context = context;
this.userName = userName;
this.mediaWikiApi = mediaWikiApi;
revertPref = context.getSharedPreferences(REVERT_SHARED_PREFERENCE, Context.MODE_PRIVATE);
countPref = context.getSharedPreferences(UPLOAD_SHARED_PREFERENCE,Context.MODE_PRIVATE);
setUploadCount();
setRevertCount();
}
/**
* to fet the total number of images uploaded
*/
private void setUploadCount() {
compositeDisposable.add(mediaWikiApi
.getUploadCount(userName)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
uploadCount -> setTotalUploadCount(uploadCount),
t -> Timber.e(t, "Fetching upload count failed")
));
}
/**
* set the sub Title of Contibutions Activity and
* call function to check for quiz
* @param uploadCount
*/
private void setTotalUploadCount(int uploadCount) {
totalUploadCount = uploadCount - countPref.getInt(UPLOAD_SHARED_PREFERENCE,0);
if( totalUploadCount < 0){
totalUploadCount = 0;
countPref.edit().putInt(UPLOAD_SHARED_PREFERENCE,0).apply();
}
isUploadCountFetched = true;
calculateRevertParameter();
}
/**
* To call the API to get reverts count in form of JSONObject
*/
private void setRevertCount() {
compositeDisposable.add(mediaWikiApi
.getRevertRespObjectSingle(userName)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
object -> setRevertParameter(object.getInt("deletedUploads"))
));
}
/**
* to calculate the number of images reverted after previous quiz
* @param revertCountFetched
*/
private void setRevertParameter(int revertCountFetched) {
revertCount = revertCountFetched - revertPref.getInt(REVERT_SHARED_PREFERENCE,0);
if(revertCount < 0){
revertCount = 0;
revertPref.edit().putInt(REVERT_SHARED_PREFERENCE, 0).apply();
}
isRevertCountFetched = true;
calculateRevertParameter();
}
/**
* to check whether the criterion to call quiz is satisfied
*/
private void calculateRevertParameter() {
if( revertCount < 0 || totalUploadCount < 0){
revertPref.edit().putInt(REVERT_SHARED_PREFERENCE, 0).apply();
countPref.edit().putInt(UPLOAD_SHARED_PREFERENCE,0).apply();
return;
}
if (isRevertCountFetched && isUploadCountFetched &&
totalUploadCount >= UPLOAD_COUNT_THRESHOLD &&
(revertCount * 100) / totalUploadCount >= 50) {
callQuiz();
}
}
/**
* Alert which prompts to quiz
*/
public void callQuiz() {
Builder alert = new Builder(context);
alert.setTitle(context.getResources().getString(R.string.quiz));
alert.setMessage(context.getResources().getString(R.string.quiz_alert_message,
REVERT_PERCENTAGE_FOR_MESSAGE));
alert.setPositiveButton("Proceed", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
int newRevetSharedPrefs = revertCount+ revertPref.getInt(REVERT_SHARED_PREFERENCE,0);
revertPref.edit().putInt(REVERT_SHARED_PREFERENCE, newRevetSharedPrefs).apply();
int newUploadCount = totalUploadCount + countPref.getInt(UPLOAD_SHARED_PREFERENCE,0);
countPref.edit().putInt(UPLOAD_SHARED_PREFERENCE,newUploadCount).apply();
Intent i = new Intent(context, WelcomeActivity.class);
i.putExtra("isQuiz", true);
dialog.dismiss();
context.startActivity(i);
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
}
});
android.support.v7.app.AlertDialog dialog = alert.create();
dialog.show();
}
}

View file

@ -0,0 +1,64 @@
package fr.free.nrw.commons.quiz;
import android.content.Context;
import java.util.ArrayList;
import butterknife.BindView;
import fr.free.nrw.commons.R;
/**
* controls the quiz in the Activity
*/
public class QuizController {
ArrayList<QuizQuestion> quiz = new ArrayList<QuizQuestion>();
private final String URL_FOR_SELFIE = "https://i.imgur.com/0fMYcpM.jpg";
private final String URL_FOR_TAJ_MAHAL = "https://upload.wikimedia.org/wikipedia/commons/1/15/Taj_Mahal-03.jpg";
private final String URL_FOR_BLURRY_IMAGE = "https://i.imgur.com/Kepb5jR.jpg";
private final String URL_FOR_SCREENSHOT = "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8b/Social_media_app_mockup_screenshot.svg/500px-Social_media_app_mockup_screenshot.svg.png";
private final String URL_FOR_EVENT = "https://upload.wikimedia.org/wikipedia/commons/5/51/HouseBuildingInNorthernVietnam.jpg";
public void initialize(Context context){
QuizQuestion q1 = new QuizQuestion(1,
context.getResources().getString(R.string.quiz_question_string),
URL_FOR_SELFIE,
false,
context.getResources().getString(R.string.selfie_answer));
quiz.add(q1);
QuizQuestion q2 = new QuizQuestion(2,
context.getResources().getString(R.string.quiz_question_string),
URL_FOR_TAJ_MAHAL,
true,
context.getResources().getString(R.string.taj_mahal_answer));
quiz.add(q2);
QuizQuestion q3 = new QuizQuestion(3,
context.getResources().getString(R.string.quiz_question_string),
URL_FOR_BLURRY_IMAGE,
false,
context.getResources().getString(R.string.blurry_image_answer));
quiz.add(q3);
QuizQuestion q4 = new QuizQuestion(4,
context.getResources().getString(R.string.quiz_question_string),
URL_FOR_SCREENSHOT,
false,
context.getResources().getString(R.string.screenshot_answer));
quiz.add(q4);
QuizQuestion q5 = new QuizQuestion(5,
context.getResources().getString(R.string.quiz_question_string),
URL_FOR_EVENT,
true,
context.getResources().getString(R.string.construction_event_answer));
quiz.add(q5);
}
public ArrayList<QuizQuestion> getQuiz() {
return quiz;
}
}

View file

@ -0,0 +1,62 @@
package fr.free.nrw.commons.quiz;
import android.net.Uri;
/**
* class contains information about all the quiz questions
*/
public class QuizQuestion {
private int questionNumber;
private String question;
private boolean answer;
private String url;
private String answerMessage;
QuizQuestion(int questionNumber, String question, String url, boolean answer, String answerMessage){
this.questionNumber = questionNumber;
this.question = question;
this.url = url;
this.answer = answer;
this.answerMessage = answerMessage;
}
public Uri getUrl() {
return Uri.parse(url);
}
public void setUrl(String url) {
this.url = url;
}
public boolean isAnswer() {
return answer;
}
public int getQuestionNumber() {
return questionNumber;
}
public String getQuestion() {
return question;
}
public void setAnswer(boolean answer) {
this.answer = answer;
}
public void setQuestion(String question) {
this.question = question;
}
public void setQuestionNumber(int questionNumber) {
this.questionNumber = questionNumber;
}
public String getAnswerMessage() {
return answerMessage;
}
public void setAnswerMessage(String answerMessage) {
this.answerMessage = answerMessage;
}
}

View file

@ -0,0 +1,199 @@
package fr.free.nrw.commons.quiz;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.dinuscxj.progressbar.CircleProgressBar;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.contributions.ContributionsActivity;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import java.io.File;
import java.io.FileOutputStream;
/**
* Displays the final score of quiz and congratulates the user
*/
public class QuizResultActivity extends AppCompatActivity {
@BindView(R.id.result_progress_bar) CircleProgressBar resultProgressBar;
@BindView(R.id.toolbar) Toolbar toolbar;
@BindView(R.id.congratulatory_message) TextView congratulatoryMessageText;
private final int NUMBER_OF_QUESTIONS = 5;
private final int MULTIPLIER_TO_GET_PERCENTAGE = 20;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz_result);
ButterKnife.bind(this);
setSupportActionBar(toolbar);
if( getIntent() != null) {
Bundle extras = getIntent().getExtras();
int score = extras.getInt("QuizResult");
setScore(score);
}else{
startActivityWithFlags(
this, ContributionsActivity.class, Intent.FLAG_ACTIVITY_CLEAR_TOP,
Intent.FLAG_ACTIVITY_SINGLE_TOP);
super.onBackPressed();
}
}
/**
* to calculate and display percentage and score
* @param score
*/
public void setScore(int score) {
int per = score * MULTIPLIER_TO_GET_PERCENTAGE;
resultProgressBar.setProgress(per);
resultProgressBar.setProgressTextFormatPattern(score +" / " + NUMBER_OF_QUESTIONS);
String message = getResources().getString(R.string.congratulatory_message_quiz,per + "%");
congratulatoryMessageText.setText(message);
}
/**
* to go to Contibutions Activity
*/
@OnClick(R.id.quiz_result_next)
public void launchContributionActivity(){
startActivityWithFlags(
this, ContributionsActivity.class, Intent.FLAG_ACTIVITY_CLEAR_TOP,
Intent.FLAG_ACTIVITY_SINGLE_TOP);
}
@Override
public void onBackPressed() {
startActivityWithFlags(
this, ContributionsActivity.class, Intent.FLAG_ACTIVITY_CLEAR_TOP,
Intent.FLAG_ACTIVITY_SINGLE_TOP);
super.onBackPressed();
}
/**
* Function to call intent to an activity
* @param context
* @param cls
* @param flags
* @param <T>
*/
public static <T> void startActivityWithFlags(Context context, Class<T> cls, int... flags) {
Intent intent = new Intent(context, cls);
for (int flag: flags) {
intent.addFlags(flag);
}
context.startActivity(intent);
}
/**
* to inflate menu
* @param menu
* @return
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_about, menu);
return true;
}
/**
* if share option selected then take screenshot and launch alert
* @param item
* @return
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.share_app_icon) {
View rootView = getWindow().getDecorView().findViewById(android.R.id.content);
Bitmap screenShot = getScreenShot(rootView);
showAlert(screenShot);
}
return super.onOptionsItemSelected(item);
}
/**
* to store the screenshot of image in bitmap variable temporarily
* @param view
* @return
*/
public static Bitmap getScreenShot(View view) {
View screenView = view.getRootView();
screenView.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(screenView.getDrawingCache());
screenView.setDrawingCacheEnabled(false);
return bitmap;
}
/**
* share the screenshot through social media
* @param bitmap
*/
void shareScreen(Bitmap bitmap) {
try {
File file = new File(this.getExternalCacheDir(),"screen.png");
FileOutputStream fOut = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
file.setReadable(true, false);
final Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
intent.setType("image/png");
startActivity(Intent.createChooser(intent, "Share image via"));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* It display the alertDialog with Image of screenshot
* @param screenshot
*/
public void showAlert(Bitmap screenshot) {
AlertDialog.Builder alertadd = new AlertDialog.Builder(QuizResultActivity.this);
LayoutInflater factory = LayoutInflater.from(QuizResultActivity.this);
final View view = factory.inflate(R.layout.image_alert_layout, null);
ImageView screenShotImage = (ImageView) view.findViewById(R.id.alert_image);
screenShotImage.setImageBitmap(screenshot);
TextView shareMessage = (TextView) view.findViewById(R.id.alert_text);
shareMessage.setText(R.string.quiz_result_share_message);
alertadd.setView(view);
alertadd.setPositiveButton("Proceed", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
shareScreen(screenshot);
}
});
alertadd.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
alertadd.show();
}
}

View file

@ -0,0 +1,64 @@
package fr.free.nrw.commons.quiz;
import android.app.Activity;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.RadioButton;
import java.util.ArrayList;
import java.util.List;
/**
* Used to group to or more radio buttons to ensure
* that at a particular time only one of them is selected
*/
public class RadioGroupHelper {
public List<CompoundButton> radioButtons = new ArrayList<>();
/**
* Constructor to group radio buttons
* @param radios
*/
public RadioGroupHelper(RadioButton... radios) {
super();
for (RadioButton rb : radios) {
add(rb);
}
}
/**
* Constructor to group radio buttons
* @param activity
* @param radiosIDs
*/
public RadioGroupHelper(Activity activity, int... radiosIDs) {
this(activity.findViewById(android.R.id.content),radiosIDs);
}
/**
* Constructor to group radio buttons
* @param rootView
* @param radiosIDs
*/
public RadioGroupHelper(View rootView, int... radiosIDs) {
super();
for (int radioButtonID : radiosIDs) {
add((RadioButton)rootView.findViewById(radioButtonID));
}
}
private void add(CompoundButton button){
this.radioButtons.add(button);
button.setOnClickListener(onClickListener);
}
/**
* listener to ensure only one of the radio button is selected
*/
View.OnClickListener onClickListener = v -> {
for (CompoundButton rb : radioButtons) {
if(rb != v) rb.setChecked(false);
}
};
}