Browse Source

More code cleanup and (javadoc style) commenting, FileManager begin

pull/24/head
Apostolos Fanakis 8 years ago
parent
commit
be5e8cc868
  1. 6
      app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java
  2. 26
      app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java
  3. 293
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
  4. 48
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java
  5. 43
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java
  6. 10
      app/src/main/java/gr/thmmy/mthmmy/data/Post.java
  7. 183
      app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java

6
app/src/main/java/gr/thmmy/mthmmy/activities/main/MainActivity.java

@ -18,6 +18,8 @@ import gr.thmmy.mthmmy.activities.main.recent.RecentFragment;
import gr.thmmy.mthmmy.activities.topic.TopicActivity; import gr.thmmy.mthmmy.activities.topic.TopicActivity;
import gr.thmmy.mthmmy.data.TopicSummary; import gr.thmmy.mthmmy.data.TopicSummary;
import static gr.thmmy.mthmmy.activities.topic.TopicActivity.EXTRAS_TOPIC_TITLE;
import static gr.thmmy.mthmmy.activities.topic.TopicActivity.EXTRAS_TOPIC_URL;
import static gr.thmmy.mthmmy.session.SessionManager.LOGGED_OUT; import static gr.thmmy.mthmmy.session.SessionManager.LOGGED_OUT;
public class MainActivity extends BaseActivity implements RecentFragment.RecentFragmentInteractionListener, ForumFragment.ForumFragmentInteractionListener { public class MainActivity extends BaseActivity implements RecentFragment.RecentFragmentInteractionListener, ForumFragment.ForumFragmentInteractionListener {
@ -83,8 +85,8 @@ public class MainActivity extends BaseActivity implements RecentFragment.RecentF
@Override @Override
public void onFragmentInteraction(TopicSummary topicSummary) { public void onFragmentInteraction(TopicSummary topicSummary) {
Intent i = new Intent(MainActivity.this, TopicActivity.class); Intent i = new Intent(MainActivity.this, TopicActivity.class);
i.putExtra("TOPIC_URL", topicSummary.getTopicUrl()); i.putExtra(EXTRAS_TOPIC_URL, topicSummary.getTopicUrl());
i.putExtra("TOPIC_TITLE", topicSummary.getTitle()); i.putExtra(EXTRAS_TOPIC_TITLE, topicSummary.getTitle());
startActivity(i); startActivity(i);
} }

26
app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java

@ -72,6 +72,7 @@ public class ProfileActivity extends BaseActivity {
* {@link ArrayList} of Strings used to hold profile's information. Data are added in {@link ProfileTask}. * {@link ArrayList} of Strings used to hold profile's information. Data are added in {@link ProfileTask}.
*/ */
private ArrayList<String> parsedProfileData; private ArrayList<String> parsedProfileData;
private ProfileTask profileTask;
private static final int THUMBNAIL_SIZE = 200; private static final int THUMBNAIL_SIZE = 200;
@Override @Override
@ -82,7 +83,7 @@ public class ProfileActivity extends BaseActivity {
PACKAGE_NAME = getApplicationContext().getPackageName(); PACKAGE_NAME = getApplicationContext().getPackageName();
Bundle extras = getIntent().getExtras(); Bundle extras = getIntent().getExtras();
//Initialize graphic elements //Initializes graphic elements
toolbar = (Toolbar) findViewById(R.id.toolbar); toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle(null); toolbar.setTitle(null);
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
@ -90,7 +91,9 @@ public class ProfileActivity extends BaseActivity {
getSupportActionBar().setDisplayShowTitleEnabled(false); getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);
} }
createDrawer(); createDrawer();
progressBar = (ProgressBar) findViewById(R.id.progressBar); progressBar = (ProgressBar) findViewById(R.id.progressBar);
userThumbnail = (ImageView) findViewById(R.id.user_thumbnail); userThumbnail = (ImageView) findViewById(R.id.user_thumbnail);
@ -100,24 +103,19 @@ public class ProfileActivity extends BaseActivity {
replyFAB = (FloatingActionButton) findViewById(R.id.profile_fab); replyFAB = (FloatingActionButton) findViewById(R.id.profile_fab);
replyFAB.setEnabled(false); replyFAB.setEnabled(false);
replyFAB.setOnClickListener(new View.OnClickListener() { replyFAB.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
SharedPreferences sharedPrefs = getSharedPreferences(SHARED_PREFS_NAME, MODE_PRIVATE); SharedPreferences sharedPrefs = getSharedPreferences(SHARED_PREFS_NAME, MODE_PRIVATE);
int tmp_curr_status = sharedPrefs.getInt(LOGIN_STATUS, -1); int tmp_curr_status = sharedPrefs.getInt(LOGIN_STATUS, -1);
if (tmp_curr_status == -1) { if (tmp_curr_status == -1) {
Report.e(TAG, "Error while getting LOGIN_STATUS");
new AlertDialog.Builder(ProfileActivity.this) new AlertDialog.Builder(ProfileActivity.this)
.setTitle("ERROR!") .setTitle("ERROR!")
.setMessage("An error occurred while trying to find your LOGIN_STATUS.\n" + .setMessage("An error occurred while trying to find your LOGIN_STATUS.")
"Please sent below info to developers:\n"
+ getLocalClassName() + "." + "l"
+ Thread.currentThread().getStackTrace()[1].getLineNumber())
.setNeutralButton("Dismiss", new DialogInterface.OnClickListener() { .setNeutralButton("Dismiss", new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialogInterface, int i) { public void onClick(DialogInterface dialogInterface, int i) {
//Todo
//Maybe sent info back to developers?
} }
}) })
.show(); .show();
@ -146,7 +144,17 @@ public class ProfileActivity extends BaseActivity {
} }
}); });
new ProfileTask().execute(extras.getString(EXTRAS_PROFILE_URL)); //Attempt data parsing //Gets info
parsedProfileData = new ArrayList<>();
profileTask = new ProfileTask();
profileTask.execute(extras.getString(EXTRAS_PROFILE_URL)); //Attempt data parsing
}
@Override
protected void onDestroy() {
super.onDestroy();
if (profileTask != null && profileTask.getStatus() != AsyncTask.Status.RUNNING)
profileTask.cancel(true);
} }
/** /**

293
app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java

@ -1,25 +1,19 @@
package gr.thmmy.mthmmy.activities.topic; package gr.thmmy.mthmmy.activities.topic;
import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment;
import android.os.Handler; import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton; import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.util.SparseArray; import android.util.SparseArray;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.webkit.MimeTypeMap;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
@ -28,8 +22,6 @@ import android.widget.Toast;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -40,34 +32,47 @@ import gr.thmmy.mthmmy.activities.LoginActivity;
import gr.thmmy.mthmmy.activities.base.BaseActivity; import gr.thmmy.mthmmy.activities.base.BaseActivity;
import gr.thmmy.mthmmy.data.Post; import gr.thmmy.mthmmy.data.Post;
import mthmmy.utils.Report; import mthmmy.utils.Report;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static gr.thmmy.mthmmy.session.SessionManager.LOGGED_IN; import static gr.thmmy.mthmmy.session.SessionManager.LOGGED_IN;
import static gr.thmmy.mthmmy.session.SessionManager.LOGIN_STATUS; import static gr.thmmy.mthmmy.session.SessionManager.LOGIN_STATUS;
/**
* Activity for topics. When creating an Intent of this activity you need to bundle a <b>String</b>
* containing this topics's url using the key {@link #EXTRAS_TOPIC_URL} and a <b>String</b> containing
* this topic's title using the key {@link #EXTRAS_TOPIC_TITLE}.
*/
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public class TopicActivity extends BaseActivity { public class TopicActivity extends BaseActivity {
//Class variables
//-----------------------------------------CLASS VARIABLES------------------------------------------ /**
* Debug Tag for logging debug output to LogCat
*/
@SuppressWarnings("unused")
private static final String TAG = "TopicActivity";
/**
* The key to use when putting topic's url String to {@link TopicActivity}'s Bundle.
*/
public static final String EXTRAS_TOPIC_URL = "TOPIC_URL";
/**
* The key to use when putting topic's title String to {@link TopicActivity}'s Bundle.
*/
public static final String EXTRAS_TOPIC_TITLE = "TOPIC_TITLE";
static String PACKAGE_NAME;
private TopicTask topicTask; private TopicTask topicTask;
//About posts
/* --Posts-- */
private List<Post> postsList; private List<Post> postsList;
static final int NO_POST_FOCUS = -1; static final int NO_POST_FOCUS = -1;
static int postFocus = NO_POST_FOCUS; static int postFocus = NO_POST_FOCUS;
//Quote //Quotes
public static final ArrayList<Integer> toQuoteList = new ArrayList<>(); public static final ArrayList<Integer> toQuoteList = new ArrayList<>();
/* --Topic's pages-- */ //Topic's pages
private int thisPage = 1; private int thisPage = 1;
public static String base_url = ""; public static String base_url = "";
private int numberOfPages = 1; private int numberOfPages = 1;
private final SparseArray<String> pagesUrls = new SparseArray<>(); private final SparseArray<String> pagesUrls = new SparseArray<>();
//Page select //Page select
private TextView pageIndicator;
private final Handler repeatUpdateHandler = new Handler(); private final Handler repeatUpdateHandler = new Handler();
private final long INITIAL_DELAY = 500; private final long INITIAL_DELAY = 500;
private boolean autoIncrement = false; private boolean autoIncrement = false;
@ -75,22 +80,20 @@ public class TopicActivity extends BaseActivity {
private static final int SMALL_STEP = 1; private static final int SMALL_STEP = 1;
private static final int LARGE_STEP = 10; private static final int LARGE_STEP = 10;
private Integer pageRequestValue; private Integer pageRequestValue;
//Bottom navigation graphics
private ImageButton firstPage; private ImageButton firstPage;
private ImageButton previousPage; private ImageButton previousPage;
private TextView pageIndicator;
private ImageButton nextPage; private ImageButton nextPage;
private ImageButton lastPage; private ImageButton lastPage;
//Other variables //Other variables
private ProgressBar progressBar; private ProgressBar progressBar;
@SuppressWarnings("unused")
private static final String TAG = "TopicActivity";
private String topicTitle; private String topicTitle;
private FloatingActionButton replyFAB; private FloatingActionButton replyFAB;
private String parsedTitle; private String parsedTitle;
private RecyclerView recyclerView; private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager; private RecyclerView.LayoutManager layoutManager;
static String PACKAGE_NAME;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -98,11 +101,10 @@ public class TopicActivity extends BaseActivity {
setContentView(R.layout.activity_topic); setContentView(R.layout.activity_topic);
PACKAGE_NAME = getApplicationContext().getPackageName(); PACKAGE_NAME = getApplicationContext().getPackageName();
Bundle extras = getIntent().getExtras(); Bundle extras = getIntent().getExtras();
topicTitle = getIntent().getExtras().getString("TOPIC_TITLE"); topicTitle = extras.getString("TOPIC_TITLE");
//Initialize toolbar, drawer and ProgressBar //Initializes graphics
toolbar = (Toolbar) findViewById(R.id.toolbar); toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle(topicTitle); toolbar.setTitle(topicTitle);
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
@ -115,44 +117,29 @@ public class TopicActivity extends BaseActivity {
progressBar = (ProgressBar) findViewById(R.id.progressBar); progressBar = (ProgressBar) findViewById(R.id.progressBar);
postsList = new ArrayList<>(); postsList = new ArrayList<>();
firstPage = (ImageButton) findViewById(R.id.page_first_button); recyclerView = (RecyclerView) findViewById(R.id.topic_recycler_view);
previousPage = (ImageButton) findViewById(R.id.page_previous_button); recyclerView.setHasFixedSize(true);
pageIndicator = (TextView) findViewById(R.id.page_indicator); layoutManager = new LinearLayoutManager(getApplicationContext());
nextPage = (ImageButton) findViewById(R.id.page_next_button); recyclerView.setLayoutManager(layoutManager);
lastPage = (ImageButton) findViewById(R.id.page_last_button); recyclerView.setAdapter(new TopicAdapter(getApplicationContext(), postsList));
initDecrementButton(firstPage, LARGE_STEP);
initDecrementButton(previousPage, SMALL_STEP);
initIncrementButton(nextPage, SMALL_STEP);
initIncrementButton(lastPage, LARGE_STEP);
firstPage.setEnabled(false);
previousPage.setEnabled(false);
nextPage.setEnabled(false);
lastPage.setEnabled(false);
replyFAB = (FloatingActionButton) findViewById(R.id.topic_fab); replyFAB = (FloatingActionButton) findViewById(R.id.topic_fab);
replyFAB.setEnabled(false); replyFAB.setEnabled(false);
replyFAB.setOnClickListener(new View.OnClickListener() { replyFAB.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
SharedPreferences sharedPrefs = getSharedPreferences(SHARED_PREFS_NAME, MODE_PRIVATE); SharedPreferences sharedPrefs = getSharedPreferences(SHARED_PREFS_NAME, MODE_PRIVATE);
int tmp_curr_status = sharedPrefs.getInt(LOGIN_STATUS, -1); int tmp_curr_status = sharedPrefs.getInt(LOGIN_STATUS, -1);
if (tmp_curr_status == -1) { if (tmp_curr_status == -1) {
Report.e(TAG, "Error while getting LOGIN_STATUS");
new AlertDialog.Builder(TopicActivity.this) new AlertDialog.Builder(TopicActivity.this)
.setTitle("ERROR!") .setTitle("ERROR!")
.setMessage("An error occurred while trying to find your LOGIN_STATUS.\n" + .setMessage("An error occurred while trying to find your LOGIN_STATUS.")
"Please sent below info to developers:\n"
+ getLocalClassName() + "." + "l"
+ Thread.currentThread().getStackTrace()[1].getLineNumber())
.setNeutralButton("Dismiss", new DialogInterface.OnClickListener() { .setNeutralButton("Dismiss", new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialogInterface, int i) { public void onClick(DialogInterface dialogInterface, int i) {
//Todo
//Maybe sent info back to developers?
} }
}) })
.show(); .show();
@ -181,14 +168,26 @@ public class TopicActivity extends BaseActivity {
} }
}); });
recyclerView = (RecyclerView) findViewById(R.id.topic_recycler_view); //Sets bottom navigation bar
recyclerView.setHasFixedSize(true); firstPage = (ImageButton) findViewById(R.id.page_first_button);
layoutManager = new LinearLayoutManager(getApplicationContext()); previousPage = (ImageButton) findViewById(R.id.page_previous_button);
recyclerView.setLayoutManager(layoutManager); pageIndicator = (TextView) findViewById(R.id.page_indicator);
recyclerView.setAdapter(new TopicAdapter(getApplicationContext(), postsList)); nextPage = (ImageButton) findViewById(R.id.page_next_button);
lastPage = (ImageButton) findViewById(R.id.page_last_button);
initDecrementButton(firstPage, LARGE_STEP);
initDecrementButton(previousPage, SMALL_STEP);
initIncrementButton(nextPage, SMALL_STEP);
initIncrementButton(lastPage, LARGE_STEP);
firstPage.setEnabled(false);
previousPage.setEnabled(false);
nextPage.setEnabled(false);
lastPage.setEnabled(false);
//Gets posts
topicTask = new TopicTask(); topicTask = new TopicTask();
topicTask.execute(extras.getString("TOPIC_URL")); //Attempt data parsing topicTask.execute(extras.getString(EXTRAS_TOPIC_URL)); //Attempt data parsing
} }
@Override @Override
@ -260,8 +259,8 @@ public class TopicActivity extends BaseActivity {
changePage(0); changePage(0);
return; return;
} }
//Clicked and holden //Clicked and hold
autoDecrement = false; //Stop incrementing autoDecrement = false; //Stop decrementing
decrementPageRequestValue(step); decrementPageRequestValue(step);
changePage(pageRequestValue - 1); changePage(pageRequestValue - 1);
} }
@ -296,10 +295,6 @@ public class TopicActivity extends BaseActivity {
} else } else
pageRequestValue = numberOfPages; pageRequestValue = numberOfPages;
pageIndicator.setText(pageRequestValue + "/" + String.valueOf(numberOfPages)); pageIndicator.setText(pageRequestValue + "/" + String.valueOf(numberOfPages));
if (pageRequestValue >= 1000)
pageIndicator.setTextSize(16);
else
pageIndicator.setTextSize(20);
} }
private void decrementPageRequestValue(int step) { private void decrementPageRequestValue(int step) {
@ -308,10 +303,6 @@ public class TopicActivity extends BaseActivity {
else else
pageRequestValue = 1; pageRequestValue = 1;
pageIndicator.setText(pageRequestValue + "/" + String.valueOf(numberOfPages)); pageIndicator.setText(pageRequestValue + "/" + String.valueOf(numberOfPages));
if (numberOfPages >= 1000)
pageIndicator.setTextSize(16);
else
pageIndicator.setTextSize(20);
} }
private void changePage(int pageRequested) { private void changePage(int pageRequested) {
@ -326,15 +317,24 @@ public class TopicActivity extends BaseActivity {
} }
//------------------------------------BOTTOM NAV BAR METHODS END------------------------------------ //------------------------------------BOTTOM NAV BAR METHODS END------------------------------------
//---------------------------------------TOPIC ASYNC TASK------------------------------------------- /**
* An {@link AsyncTask} that handles asynchronous fetching of a topic page and parsing it's
* data. {@link AsyncTask#onPostExecute(Object) OnPostExecute} method calls {@link RecyclerView#swapAdapter}
* to build graphics.
* <p>
* <p>Calling ProfileTask's {@link AsyncTask#execute execute} method needs to have profile's url
* as String parameter!</p>
*/
public class TopicTask extends AsyncTask<String, Void, Integer> { public class TopicTask extends AsyncTask<String, Void, Integer> {
//Class variables //Class variables
/**
* Debug Tag for logging debug output to LogCat
*/
private static final String TAG = "TopicTask"; //Separate tag for AsyncTask private static final String TAG = "TopicTask"; //Separate tag for AsyncTask
private static final int SUCCESS = 0; private static final int SUCCESS = 0;
private static final int NETWORK_ERROR = 1; private static final int NETWORK_ERROR = 1;
private static final int OTHER_ERROR = 2; private static final int OTHER_ERROR = 2;
//Show a progress bar until done
protected void onPreExecute() { protected void onPreExecute() {
progressBar.setVisibility(ProgressBar.VISIBLE); progressBar.setVisibility(ProgressBar.VISIBLE);
replyFAB.setEnabled(false); replyFAB.setEnabled(false);
@ -343,9 +343,9 @@ public class TopicActivity extends BaseActivity {
protected Integer doInBackground(String... strings) { protected Integer doInBackground(String... strings) {
Document document; Document document;
base_url = strings[0].substring(0, strings[0].lastIndexOf(".")); //This topic's base url base_url = strings[0].substring(0, strings[0].lastIndexOf(".")); //This topic's base url
String pageUrl = strings[0]; //This page's url String pageUrl = strings[0];
//Find message focus if present //Finds message focus if present
{ {
postFocus = NO_POST_FOCUS; postFocus = NO_POST_FOCUS;
if (pageUrl.contains("msg")) { if (pageUrl.contains("msg")) {
@ -363,7 +363,7 @@ public class TopicActivity extends BaseActivity {
try { try {
Response response = client.newCall(request).execute(); Response response = client.newCall(request).execute();
document = Jsoup.parse(response.body().string()); document = Jsoup.parse(response.body().string());
parse(document); //Parse data parse(document);
return SUCCESS; return SUCCESS;
} catch (IOException e) { } catch (IOException e) {
Report.i(TAG, "IO Exception", e); Report.i(TAG, "IO Exception", e);
@ -374,18 +374,26 @@ public class TopicActivity extends BaseActivity {
} }
} }
protected void onPostExecute(Integer result) { protected void onPostExecute(Integer parseResult) {
switch (result) { switch (parseResult) {
case SUCCESS: case SUCCESS:
//Parse was successful progressBar.setVisibility(ProgressBar.INVISIBLE);
progressBar.setVisibility(ProgressBar.INVISIBLE); //Hide progress bar
populateLayout(); //Show parsed data recyclerView.swapAdapter(new TopicAdapter(getApplicationContext(), postsList), false);
//Set post focus
if (postFocus != NO_POST_FOCUS) {
for (int i = postsList.size() - 1; i >= 0; --i) {
int currentPostIndex = postsList.get(i).getPostIndex();
if (currentPostIndex == postFocus) {
layoutManager.scrollToPosition(i);
}
}
}
replyFAB.setEnabled(true);
//Set current page //Set current page
pageIndicator.setText(String.valueOf(thisPage) + "/" + String.valueOf(numberOfPages)); pageIndicator.setText(String.valueOf(thisPage) + "/" + String.valueOf(numberOfPages));
pageRequestValue = thisPage; pageRequestValue = thisPage;
if (numberOfPages >= 1000)
pageIndicator.setTextSize(16);
firstPage.setEnabled(true); firstPage.setEnabled(true);
previousPage.setEnabled(true); previousPage.setEnabled(true);
@ -406,13 +414,18 @@ public class TopicActivity extends BaseActivity {
} }
} }
/* Parse method */ /**
private void parse(Document document) { * All the parsing a topic needs.
String language = TopicParser.defineLanguage(document); *
* @param topic {@link Document} object containing this topic's source code
* @see org.jsoup.Jsoup Jsoup
*/
private void parse(Document topic) {
String language = TopicParser.defineLanguage(topic);
//Find topic title if missing //Finds topic title if missing
if (topicTitle == null || Objects.equals(topicTitle, "")) { if (topicTitle == null || Objects.equals(topicTitle, "")) {
parsedTitle = document.select("td[id=top_subject]").first().text(); parsedTitle = topic.select("td[id=top_subject]").first().text();
if (parsedTitle.contains("Topic:")) { if (parsedTitle.contains("Topic:")) {
parsedTitle = parsedTitle.substring(parsedTitle.indexOf("Topic:") + 7 parsedTitle = parsedTitle.substring(parsedTitle.indexOf("Topic:") + 7
, parsedTitle.indexOf("(Read") - 2); , parsedTitle.indexOf("(Read") - 2);
@ -423,11 +436,11 @@ public class TopicActivity extends BaseActivity {
} }
} }
{ //Find current page's index { //Finds current page's index
thisPage = TopicParser.parseCurrentPageIndex(document, language); thisPage = TopicParser.parseCurrentPageIndex(topic, language);
} }
{ //Find number of pages { //Finds number of pages
numberOfPages = TopicParser.parseTopicNumberOfPages(document, thisPage, language); numberOfPages = TopicParser.parseTopicNumberOfPages(topic, thisPage, language);
for (int i = 0; i < numberOfPages; i++) { for (int i = 0; i < numberOfPages; i++) {
//Generate each page's url from topic's base url +".15*numberOfPage" //Generate each page's url from topic's base url +".15*numberOfPage"
@ -435,44 +448,20 @@ public class TopicActivity extends BaseActivity {
} }
} }
postsList = TopicParser.parseTopic(document, language); postsList = TopicParser.parseTopic(topic, language);
}
/* Parse method end */
}
//-------------------------------------TOPIC ASYNC TASK END-----------------------------------------
//----------------------------------------POPULATE UI METHOD----------------------------------------
/**
* This method runs on the main thread. It reads from the postsList and dynamically
* adds a card for each post to the ScrollView.
*/
private void populateLayout() {
recyclerView.swapAdapter(new TopicAdapter(getApplicationContext(), postsList), false);
//Set post focus
if (postFocus != NO_POST_FOCUS) {
for (int i = postsList.size() - 1; i >= 0; --i) {
int currentPostIndex = postsList.get(i).getPostIndex();
if (currentPostIndex == postFocus) {
layoutManager.scrollToPosition(i);
}
}
} }
replyFAB.setEnabled(true);
} }
//--------------------------------------POPULATE UI METHOD END--------------------------------------
//----------------------------------------REPETITIVE UPDATER----------------------------------------
/** /**
* This class is used to implement the repetitive incrementPageRequestValue/decrementPageRequestValue of page value * This class is used to implement the repetitive incrementPageRequestValue/decrementPageRequestValue
* when long pressing one of the page navigation buttons. * of page value when long pressing one of the page navigation buttons.
*/ */
class RepetitiveUpdater implements Runnable { class RepetitiveUpdater implements Runnable {
private final int step; private final int step;
/**
* @param step number of pages to add/subtract on each repetition
*/
RepetitiveUpdater(int step) { RepetitiveUpdater(int step) {
this.step = step; this.step = step;
} }
@ -488,76 +477,4 @@ public class TopicActivity extends BaseActivity {
} }
} }
} }
//--------------------------------------REPETITIVE UPDATER END--------------------------------------
//------------------------------METHODS FOR DOWNLOADING ATTACHED FILES------------------------------
/**
* Create a File
*/
static void downloadFileAsync(final String downloadUrl, final String fileName, final Context context) {
Request request = new Request.Builder().url(downloadUrl).build();
getClient().newCall(request).enqueue(new Callback() {
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) {
throw new IOException("Failed to download file: " + response);
}
File tmpFile = getOutputMediaFile(PACKAGE_NAME, fileName);
if (tmpFile == null) {
Report.d(TAG
, "Error creating media file, check storage permissions!");
} else {
FileOutputStream fos = new FileOutputStream(tmpFile);
fos.write(response.body().bytes());
fos.close();
String filePath = tmpFile.getAbsolutePath();
String extension = MimeTypeMap.getFileExtensionFromUrl(
filePath.substring(filePath.lastIndexOf("/")));
String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(tmpFile), mime);
intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
}
});
}
/**
* Create a File
*/
@Nullable
private static File getOutputMediaFile(String packageName, String fileName) {
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
+ "/Android/data/"
+ packageName
+ "/Downloads");
// This location works best if you want the created files to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(TAG, "problem!");
return null;
}
}
// Create a media file name
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator + fileName);
return mediaFile;
}
//----------------------------METHODS FOR DOWNLOADING ATTACHED FILES END----------------------------
} }

48
app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java

@ -7,6 +7,7 @@ import android.content.Intent;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
@ -19,6 +20,7 @@ import android.view.LayoutInflater;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.webkit.MimeTypeMap;
import android.webkit.WebResourceRequest; import android.webkit.WebResourceRequest;
import android.webkit.WebView; import android.webkit.WebView;
import android.webkit.WebViewClient; import android.webkit.WebViewClient;
@ -31,6 +33,8 @@ import android.widget.TextView;
import com.squareup.picasso.Picasso; import com.squareup.picasso.Picasso;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -39,13 +43,14 @@ import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.profile.ProfileActivity; import gr.thmmy.mthmmy.activities.profile.ProfileActivity;
import gr.thmmy.mthmmy.data.Post; import gr.thmmy.mthmmy.data.Post;
import gr.thmmy.mthmmy.utils.CircleTransform; import gr.thmmy.mthmmy.utils.CircleTransform;
import gr.thmmy.mthmmy.utils.FileManager.ThmmyFile;
import mthmmy.utils.Report; import mthmmy.utils.Report;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.EXTRAS_PROFILE_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.EXTRAS_PROFILE_URL;
import static gr.thmmy.mthmmy.activities.topic.TopicActivity.NO_POST_FOCUS; import static gr.thmmy.mthmmy.activities.topic.TopicActivity.NO_POST_FOCUS;
import static gr.thmmy.mthmmy.activities.topic.TopicActivity.PACKAGE_NAME;
import static gr.thmmy.mthmmy.activities.topic.TopicActivity.base_url; import static gr.thmmy.mthmmy.activities.topic.TopicActivity.base_url;
import static gr.thmmy.mthmmy.activities.topic.TopicActivity.downloadFileAsync;
import static gr.thmmy.mthmmy.activities.topic.TopicActivity.postFocus; import static gr.thmmy.mthmmy.activities.topic.TopicActivity.postFocus;
import static gr.thmmy.mthmmy.activities.topic.TopicActivity.toQuoteList; import static gr.thmmy.mthmmy.activities.topic.TopicActivity.toQuoteList;
@ -197,30 +202,28 @@ class TopicAdapter extends RecyclerView.Adapter<TopicAdapter.MyViewHolder> {
if (currentPost.getAttachedFiles().size() != 0) { if (currentPost.getAttachedFiles().size() != 0) {
holder.bodyFooterDivider.setVisibility(View.VISIBLE); holder.bodyFooterDivider.setVisibility(View.VISIBLE);
int filesTextColor = 0; int filesTextColor;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
filesTextColor = context.getResources().getColor(R.color.accent, null); filesTextColor = context.getResources().getColor(R.color.accent, null);
} else //noinspection deprecation } else //noinspection deprecation
filesTextColor = context.getResources().getColor(R.color.accent); filesTextColor = context.getResources().getColor(R.color.accent);
for (final String[] attachedFile : currentPost.getAttachedFiles()) { for (final ThmmyFile attachedFile : currentPost.getAttachedFiles()) {
final TextView attached = new TextView(context); final TextView attached = new TextView(context);
attached.setTextSize(10f); attached.setTextSize(10f);
attached.setClickable(true); attached.setClickable(true);
attached.setTypeface(Typeface.createFromAsset(context.getAssets() attached.setTypeface(Typeface.createFromAsset(context.getAssets()
, "fonts/fontawesome-webfont.ttf")); , "fonts/fontawesome-webfont.ttf"));
attached.setText(faIconFromExtension(attachedFile[1]) + " " + attachedFile[1] + attachedFile[2]); attached.setText(faIconFromExtension(attachedFile.getFilename()) + " "
+ attachedFile.getFilename() + attachedFile.getFileInfo());
attached.setTextColor(filesTextColor); attached.setTextColor(filesTextColor);
attached.setPadding(0, 3, 0, 3); attached.setPadding(0, 3, 0, 3);
attached.setOnClickListener(new View.OnClickListener() { attached.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
try { DownloadTask downloadTask = new DownloadTask();
downloadFileAsync(attachedFile[0], attachedFile[1], context); downloadTask.execute(attachedFile);
} catch (Exception e) {
e.printStackTrace();
}
} }
}); });
@ -578,4 +581,31 @@ class TopicAdapter extends RecyclerView.Adapter<TopicAdapter.MyViewHolder> {
return context.getResources().getString(R.string.fa_file); return context.getResources().getString(R.string.fa_file);
} }
private class DownloadTask extends AsyncTask<ThmmyFile, Void, Void> {
//Class variables
/**
* Debug Tag for logging debug output to LogCat
*/
private static final String TAG = "DownloadTask"; //Separate tag for AsyncTask
protected Void doInBackground(ThmmyFile... files) {
try {
File tmpFile = files[0].download(PACKAGE_NAME);
if (tmpFile != null) {
String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
files[0].getExtension());
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(tmpFile), mime);
intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
} catch (IOException e) {
Report.e(TAG, "Error while trying to download a file", e);
}
return null;
}
}
} }

43
app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java

@ -7,12 +7,16 @@ import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import gr.thmmy.mthmmy.data.Post; import gr.thmmy.mthmmy.data.Post;
import gr.thmmy.mthmmy.utils.FileManager.ThmmyFile;
import mthmmy.utils.Report;
/** /**
* Singleton used for parsing a topic. * Singleton used for parsing a topic.
@ -20,8 +24,7 @@ import gr.thmmy.mthmmy.data.Post;
* <li>{@link #parseCurrentPageIndex(Document, String)}</li> * <li>{@link #parseCurrentPageIndex(Document, String)}</li>
* <li>{@link #parseTopicNumberOfPages(Document, int, String)}</li> * <li>{@link #parseTopicNumberOfPages(Document, int, String)}</li>
* <li>{@link #parseTopic(Document, String)}</li> * <li>{@link #parseTopic(Document, String)}</li>
* <li>{@link #defineLanguage(Document)}</li> * <li>{@link #defineLanguage(Document)}</li></ul></p>
* <li>(private) {@link #colorPicker(String)}</li></ul></p>
*/ */
class TopicParser { class TopicParser {
//Languages supported //Languages supported
@ -165,7 +168,7 @@ class TopicParser {
p_specialRank, p_gender, p_personalText, p_numberOfPosts; p_specialRank, p_gender, p_personalText, p_numberOfPosts;
int p_postNum, p_postIndex, p_numberOfStars, p_userColor; int p_postNum, p_postIndex, p_numberOfStars, p_userColor;
boolean p_isDeleted = false; boolean p_isDeleted = false;
ArrayList<String[]> p_attachedFiles; ArrayList<ThmmyFile> p_attachedFiles;
//Initialize variables //Initialize variables
p_profileURL = null; p_profileURL = null;
@ -274,21 +277,26 @@ class TopicParser {
String postAttachmentsText = postAttachments.text(); String postAttachmentsText = postAttachments.text();
for (int i = 0; i < attachedFiles.size(); ++i) { for (int i = 0; i < attachedFiles.size(); ++i) {
String[] attachedArray = new String[3]; URL attachedUrl;
//Gets file's url and filename //Gets file's url and filename
Element tmpAttachedFileUrlAndName = attachedFiles.get(i); Element tmpAttachedFileUrlAndName = attachedFiles.get(i);
attachedArray[0] = tmpAttachedFileUrlAndName.attr("href"); try {
attachedArray[1] = tmpAttachedFileUrlAndName.text().substring(1); attachedUrl = new URL(tmpAttachedFileUrlAndName.attr("href"));
} catch (MalformedURLException e) {
Report.e(TAG,"Attached file malformed url", e);
break;
}
String attachedFileName = tmpAttachedFileUrlAndName.text().substring(1);
//Gets file's info (size and download count) //Gets file's info (size and download count)
String postAttachmentsTextSbstr = postAttachmentsText.substring( String postAttachmentsTextSbstr = postAttachmentsText.substring(
postAttachmentsText.indexOf(attachedArray[1])); postAttachmentsText.indexOf(attachedFileName));
attachedArray[2] = postAttachmentsTextSbstr.substring(attachedArray[1] String attachedFileInfo = postAttachmentsTextSbstr.substring(attachedFileName
.length(), postAttachmentsTextSbstr.indexOf("φορές.")) + "φορές.)"; .length(), postAttachmentsTextSbstr.indexOf("φορές.")) + "φορές.)";
p_attachedFiles.add(attachedArray); p_attachedFiles.add(new ThmmyFile(attachedUrl,attachedFileName,attachedFileInfo));
} }
} }
} else { } else {
@ -329,21 +337,26 @@ class TopicParser {
String postAttachmentsText = postAttachments.text(); String postAttachmentsText = postAttachments.text();
for (int i = 0; i < attachedFiles.size(); ++i) { for (int i = 0; i < attachedFiles.size(); ++i) {
String[] attachedArray = new String[3]; URL attachedUrl;
//Gets file's url and filename //Gets file's url and filename
Element tmpAttachedFileUrlAndName = attachedFiles.get(i); Element tmpAttachedFileUrlAndName = attachedFiles.get(i);
attachedArray[0] = tmpAttachedFileUrlAndName.attr("href"); try {
attachedArray[1] = tmpAttachedFileUrlAndName.text().substring(1); attachedUrl = new URL(tmpAttachedFileUrlAndName.attr("href"));
} catch (MalformedURLException e) {
Report.e(TAG,"Attached file malformed url", e);
break;
}
String attachedFileName = tmpAttachedFileUrlAndName.text().substring(1);
//Gets file's info (size and download count) //Gets file's info (size and download count)
String postAttachmentsTextSbstr = postAttachmentsText.substring( String postAttachmentsTextSbstr = postAttachmentsText.substring(
postAttachmentsText.indexOf(attachedArray[1])); postAttachmentsText.indexOf(attachedFileName));
attachedArray[2] = postAttachmentsTextSbstr.substring(attachedArray[1] String attachedFileInfo = postAttachmentsTextSbstr.substring(attachedFileName
.length(), postAttachmentsTextSbstr.indexOf("times.")) + "times.)"; .length(), postAttachmentsTextSbstr.indexOf("times.")) + "times.)";
p_attachedFiles.add(attachedArray); p_attachedFiles.add(new ThmmyFile(attachedUrl,attachedFileName,attachedFileInfo));
} }
} }
} }

10
app/src/main/java/gr/thmmy/mthmmy/data/Post.java

@ -2,6 +2,8 @@ package gr.thmmy.mthmmy.data;
import java.util.ArrayList; import java.util.ArrayList;
import gr.thmmy.mthmmy.utils.FileManager.ThmmyFile;
public class Post { public class Post {
//Standard info (exists in every post) //Standard info (exists in every post)
private final String thumbnailUrl; private final String thumbnailUrl;
@ -22,13 +24,13 @@ public class Post {
private final String personalText; private final String personalText;
private final int numberOfStars; private final int numberOfStars;
private final int userColor; private final int userColor;
private final ArrayList<String[]> attachedFiles; private final ArrayList<ThmmyFile> attachedFiles;
public Post(String thumbnailUrl, String author, String subject, String content public Post(String thumbnailUrl, String author, String subject, String content
, int postIndex, int postNumber, String postDate, String profileURl, String rank , int postIndex, int postNumber, String postDate, String profileURl, String rank
, String special_rank, String gender, String numberOfPosts , String special_rank, String gender, String numberOfPosts
, String personalText, int numberOfStars, int userColor , String personalText, int numberOfStars, int userColor
, ArrayList<String[]> attachedFiles) { , ArrayList<ThmmyFile> attachedFiles) {
this.thumbnailUrl = thumbnailUrl; this.thumbnailUrl = thumbnailUrl;
this.author = author; this.author = author;
this.subject = subject; this.subject = subject;
@ -50,7 +52,7 @@ public class Post {
public Post(String thumbnailUrl, String author, String subject, String content public Post(String thumbnailUrl, String author, String subject, String content
, int postIndex, int postNumber, String postDate, int userColor , int postIndex, int postNumber, String postDate, int userColor
, ArrayList<String[]> attachedFiles) { , ArrayList<ThmmyFile> attachedFiles) {
this.thumbnailUrl = thumbnailUrl; this.thumbnailUrl = thumbnailUrl;
this.author = author; this.author = author;
this.subject = subject; this.subject = subject;
@ -135,7 +137,7 @@ public class Post {
return userColor; return userColor;
} }
public ArrayList<String[]> getAttachedFiles() { public ArrayList<ThmmyFile> getAttachedFiles() {
return attachedFiles; return attachedFiles;
} }
} }

183
app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java

@ -0,0 +1,183 @@
package gr.thmmy.mthmmy.utils.FileManager;
import android.os.Environment;
import android.support.annotation.Nullable;
import android.webkit.MimeTypeMap;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Objects;
import mthmmy.utils.Report;
import okhttp3.Request;
import okhttp3.Response;
import static gr.thmmy.mthmmy.activities.base.BaseActivity.getClient;
/**
* Used for downloading and storing a file from the forum using {@link okhttp3}.
* <p>Class has one constructor: <ul><li>{@link #ThmmyFile(URL, String, String)}</li></ul>
* and the methods:<ul><li>getters</li>
* <li>{@link #download()}</li>
* <li>{@link #download(String)}</li></ul></p>
*/
public class ThmmyFile {
/**
* Debug Tag for logging debug output to LogCat
*/
private static final String TAG = "ThmmyFile";
/**
* Folder name used when downloading files without a package name.
*/
private static final String NO_PACKAGE_FOLDER_NAME = "Other";
private final URL fileUrl;
private final String filename, fileInfo;
private String extension, filePath;
private File file;
/**
* This constructor only creates a ThmmyFile object and <b>does not download</b> the file. To download
* the file use {@link #download(String)} or {@link #download()}!
*
* @param fileUrl {@link URL} object with file's url
* @param filename {@link String} with desired file name
* @param fileInfo {@link String} with any extra information (like number of downloads)
*/
public ThmmyFile(URL fileUrl, String filename, String fileInfo) {
this.fileUrl = fileUrl;
this.filename = filename;
this.fileInfo = fileInfo;
this.extension = null;
this.filePath = null;
this.file = null;
}
public URL getFileUrl() {
return fileUrl;
}
public String getFilename() {
return filename;
}
public String getFileInfo() {
return fileInfo;
}
/**
* This is null until {@link #download(String)} or {@link #download()} is called and has succeeded.
*
* @return String with file's extension or null
*/
@Nullable
public String getExtension() {
return extension;
}
/**
* This is null until {@link #download(String)} or {@link #download()} is called and has succeeded.
*
* @return String with file's path or null
*/
@Nullable
public String getFilePath() {
return filePath;
}
/**
* This is null until {@link #download(String)} or {@link #download()} is called and has succeeded.
*
* @return {@link File} or null
*/
@Nullable
public File getFile() {
return file;
}
private void setExtension(String extension) {
this.extension = extension;
}
private void setFilePath(String filePath) {
this.filePath = filePath;
}
/**
* Used to download the file. If download is successful file's extension and path will be assigned
* to object's fields and can be accessed using getter methods.
* <p>File is stored in sdcard1/Android/data/Downloads/{@link #NO_PACKAGE_FOLDER_NAME}</p>
*
* @return the {@link File} if successful, null otherwise
* @throws IOException
* @throws SecurityException
*/
@Nullable
public File download() throws IOException, SecurityException {
return download(NO_PACKAGE_FOLDER_NAME);
}
/**
* Used to download the file. If download is successful file's extension and path will be assigned
* to object's fields and can be accessed using getter methods.
* <p>File is stored in sdcard1/Android/data/Downloads/packageName</p>
*
* @param packageName package's name to use as folder name for file's path
* @return the {@link File} if successful, null otherwise
* @throws IOException if the request could not be executed due to cancellation, a connectivity
* problem or timeout. Because networks can fail during an exchange, it is possible that the
* remote server accepted the request before the failure.
* @throws SecurityException if the requested file is not hosted by the forum.
*/
@Nullable
public File download(final String packageName) throws IOException, SecurityException {
if (!Objects.equals(fileUrl.getHost(), "www.thmmy.gr"))
throw new SecurityException("Downloading files from other sources is not supported");
Request request = new Request.Builder().url(fileUrl).build();
Response response = getClient().newCall(request).execute();
if (!response.isSuccessful()) {
throw new IOException("Failed to download file: " + response);
}
file = getOutputMediaFile(packageName, filename);
if (file == null) {
Report.d(TAG, "Error creating media file, check storage permissions!");
} else {
FileOutputStream fos = new FileOutputStream(file);
fos.write(response.body().bytes());
fos.close();
filePath = file.getAbsolutePath();
extension = MimeTypeMap.getFileExtensionFromUrl(
filePath.substring(filePath.lastIndexOf("/")));
}
return file;
}
@Nullable
private static File getOutputMediaFile(String packageName, String fileName) {
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
+ "/Android/data/gr.thmmy.mthmmy/"
+ "Downloads/"
+ packageName);
// This location works best if you want the created files to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Report.d(TAG, "problem!");
return null;
}
}
// Create a media file name
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator + fileName);
return mediaFile;
}
}
Loading…
Cancel
Save