Browse Source

Fixes for file downloading, profile crashes, mixed views in topics, pageNav clicking.

pull/24/head
Apostolos Fanakis 8 years ago
parent
commit
846aefc46b
  1. 17
      app/src/main/AndroidManifest.xml
  2. 17
      app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java
  3. 131
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java
  4. 21
      app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java
  5. 29
      app/src/main/java/gr/thmmy/mthmmy/utils/FileManager/ThmmyFile.java
  6. 11
      app/src/main/res/xml/provider_paths.xml

17
app/src/main/AndroidManifest.xml

@ -15,6 +15,7 @@
android:label="@string/app_name" android:label="@string/app_name"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme"> android:theme="@style/AppTheme">
<activity <activity
android:name=".activities.main.MainActivity" android:name=".activities.main.MainActivity"
android:configChanges="orientation|screenSize" android:configChanges="orientation|screenSize"
@ -27,12 +28,14 @@
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter> </intent-filter>
</activity> </activity>
<activity <activity
android:name=".activities.LoginActivity" android:name=".activities.LoginActivity"
android:configChanges="orientation|screenSize" android:configChanges="orientation|screenSize"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@style/AppTheme.NoActionBar"> android:theme="@style/AppTheme.NoActionBar">
</activity> </activity>
<activity <activity
android:name=".activities.AboutActivity" android:name=".activities.AboutActivity"
android:parentActivityName=".activities.main.MainActivity" android:parentActivityName=".activities.main.MainActivity"
@ -41,6 +44,7 @@
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.main.MainActivity"/> android:value=".activities.main.MainActivity"/>
</activity> </activity>
<activity <activity
android:name=".activities.topic.TopicActivity" android:name=".activities.topic.TopicActivity"
android:configChanges="orientation|screenSize" android:configChanges="orientation|screenSize"
@ -50,10 +54,12 @@
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.main.MainActivity"/> android:value=".activities.main.MainActivity"/>
</activity> </activity>
<activity <activity
android:name=".activities.profile.ProfileActivity" android:name=".activities.profile.ProfileActivity"
android:theme="@style/AppTheme.NoActionBar"> android:theme="@style/AppTheme.NoActionBar">
</activity> </activity>
<activity <activity
android:name=".activities.board.BoardActivity" android:name=".activities.board.BoardActivity"
android:configChanges="orientation|screenSize" android:configChanges="orientation|screenSize"
@ -63,6 +69,7 @@
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.main.MainActivity"/> android:value=".activities.main.MainActivity"/>
</activity> </activity>
<activity <activity
android:name=".activities.downloads.DownloadsActivity" android:name=".activities.downloads.DownloadsActivity"
android:parentActivityName=".activities.main.MainActivity" android:parentActivityName=".activities.main.MainActivity"
@ -71,6 +78,16 @@
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.main.MainActivity"/> android:value=".activities.main.MainActivity"/>
</activity> </activity>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
</application> </application>
</manifest> </manifest>

17
app/src/main/java/gr/thmmy/mthmmy/activities/profile/summary/SummaryFragment.java

@ -82,7 +82,7 @@ public class SummaryFragment extends Fragment {
Bundle savedInstanceState) { Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_summary, container, false); final View rootView = inflater.inflate(R.layout.fragment_summary, container, false);
mainContent = (LinearLayout) rootView.findViewById(R.id.profile_activity_content); mainContent = (LinearLayout) rootView.findViewById(R.id.profile_activity_content);
if (!parsedProfileSummaryData.isEmpty()) if (!parsedProfileSummaryData.isEmpty() && isAdded())
populateLayout(); populateLayout();
return rootView; return rootView;
} }
@ -126,7 +126,7 @@ public class SummaryFragment extends Fragment {
} }
protected void onPostExecute(Void result) { protected void onPostExecute(Void result) {
populateLayout(); if (isAdded()) populateLayout();
} }
/** /**
@ -187,13 +187,12 @@ public class SummaryFragment extends Fragment {
} }
TextView entry = new TextView(this.getContext()); TextView entry = new TextView(this.getContext());
if (isAdded()) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) entry.setTextColor(getResources().getColor(R.color.primary_text, null));
entry.setTextColor(getResources().getColor(R.color.primary_text, null)); else
else //noinspection deprecation
//noinspection deprecation entry.setTextColor(getResources().getColor(R.color.primary_text));
entry.setTextColor(getResources().getColor(R.color.primary_text));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
entry.setText(Html.fromHtml(profileSummaryRow, Html.FROM_HTML_MODE_LEGACY)); entry.setText(Html.fromHtml(profileSummaryRow, Html.FROM_HTML_MODE_LEGACY));
} else { } else {

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

@ -1,16 +1,14 @@
package gr.thmmy.mthmmy.activities.topic; package gr.thmmy.mthmmy.activities.topic;
import android.Manifest; import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; 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;
import android.support.design.widget.FloatingActionButton; import android.support.design.widget.FloatingActionButton;
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;
@ -30,7 +28,6 @@ import java.util.ArrayList;
import java.util.Objects; import java.util.Objects;
import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.R;
import gr.thmmy.mthmmy.activities.LoginActivity;
import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.base.BaseActivity;
import gr.thmmy.mthmmy.model.LinkTarget; import gr.thmmy.mthmmy.model.LinkTarget;
import gr.thmmy.mthmmy.model.Post; import gr.thmmy.mthmmy.model.Post;
@ -237,6 +234,33 @@ public class TopicActivity extends BaseActivity {
} }
//--------------------------------------BOTTOM NAV BAR METHODS---------------------------------- //--------------------------------------BOTTOM NAV BAR METHODS----------------------------------
/**
* This class is used to implement the repetitive incrementPageRequestValue/decrementPageRequestValue
* of page value when long pressing one of the page navigation buttons.
*/
class RepetitiveUpdater implements Runnable {
private final int step;
/**
* @param step number of pages to add/subtract on each repetition
*/
RepetitiveUpdater(int step) {
this.step = step;
}
public void run() {
long REPEAT_DELAY = 250;
if (autoIncrement) {
incrementPageRequestValue(step);
repeatUpdateHandler.postDelayed(new RepetitiveUpdater(step), REPEAT_DELAY);
} else if (autoDecrement) {
decrementPageRequestValue(step);
repeatUpdateHandler.postDelayed(new RepetitiveUpdater(step), REPEAT_DELAY);
}
}
}
private void paginationEnabled(boolean enabled) { private void paginationEnabled(boolean enabled) {
firstPage.setEnabled(enabled); firstPage.setEnabled(enabled);
previousPage.setEnabled(enabled); previousPage.setEnabled(enabled);
@ -244,18 +268,38 @@ public class TopicActivity extends BaseActivity {
lastPage.setEnabled(enabled); lastPage.setEnabled(enabled);
} }
private void paginationEnabledExcept(boolean enabled, View exception) {
if (exception == firstPage) {
previousPage.setEnabled(enabled);
nextPage.setEnabled(enabled);
lastPage.setEnabled(enabled);
} else if (exception == previousPage) {
firstPage.setEnabled(enabled);
nextPage.setEnabled(enabled);
lastPage.setEnabled(enabled);
} else if (exception == nextPage) {
firstPage.setEnabled(enabled);
previousPage.setEnabled(enabled);
lastPage.setEnabled(enabled);
} else if (exception == lastPage) {
firstPage.setEnabled(enabled);
previousPage.setEnabled(enabled);
nextPage.setEnabled(enabled);
} else {
paginationEnabled(enabled);
}
}
private void initIncrementButton(ImageButton increment, final int step) { private void initIncrementButton(ImageButton increment, final int step) {
// Increment once for a click // Increment once for a click
increment.setOnClickListener(new View.OnClickListener() { increment.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { public void onClick(View v) {
if (!autoIncrement && step == LARGE_STEP) { //If just clicked go to last page if (!autoIncrement && step == LARGE_STEP) {
changePage(numberOfPages - 1); changePage(numberOfPages - 1);
return; } else if (!autoIncrement) {
incrementPageRequestValue(step);
changePage(pageRequestValue - 1);
} }
//Clicked and holden
autoIncrement = false; //Stop incrementing
incrementPageRequestValue(step);
changePage(pageRequestValue - 1);
} }
}); });
@ -263,6 +307,7 @@ public class TopicActivity extends BaseActivity {
increment.setOnLongClickListener( increment.setOnLongClickListener(
new View.OnLongClickListener() { new View.OnLongClickListener() {
public boolean onLongClick(View arg0) { public boolean onLongClick(View arg0) {
paginationEnabledExcept(false, arg0);
autoIncrement = true; autoIncrement = true;
repeatUpdateHandler.postDelayed(new RepetitiveUpdater(step), INITIAL_DELAY); repeatUpdateHandler.postDelayed(new RepetitiveUpdater(step), INITIAL_DELAY);
return false; return false;
@ -272,9 +317,21 @@ public class TopicActivity extends BaseActivity {
// When the button is released // When the button is released
increment.setOnTouchListener(new View.OnTouchListener() { increment.setOnTouchListener(new View.OnTouchListener() {
private Rect rect;
public boolean onTouch(View v, MotionEvent event) { public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP && autoIncrement) { if (event.getAction() == MotionEvent.ACTION_DOWN) {
rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
} else if (event.getAction() == MotionEvent.ACTION_UP && autoIncrement) {
autoIncrement = false;
paginationEnabled(true);
changePage(pageRequestValue - 1); changePage(pageRequestValue - 1);
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())) {
autoIncrement = false;
decrementPageRequestValue(pageRequestValue - thisPage);
paginationEnabled(true);
}
} }
return false; return false;
} }
@ -285,22 +342,20 @@ public class TopicActivity extends BaseActivity {
// Decrement once for a click // Decrement once for a click
decrement.setOnClickListener(new View.OnClickListener() { decrement.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { public void onClick(View v) {
if (!autoDecrement && step == LARGE_STEP) { //If just clicked go to first page if (!autoDecrement && step == LARGE_STEP) {
changePage(0); changePage(0);
return; } else if (!autoDecrement) {
decrementPageRequestValue(step);
changePage(pageRequestValue - 1);
} }
//Clicked and hold
autoDecrement = false; //Stop decrementing
decrementPageRequestValue(step);
changePage(pageRequestValue - 1);
} }
}); });
// Auto decrement for a long click // Auto decrement for a long click
decrement.setOnLongClickListener( decrement.setOnLongClickListener(
new View.OnLongClickListener() { new View.OnLongClickListener() {
public boolean onLongClick(View arg0) { public boolean onLongClick(View arg0) {
paginationEnabledExcept(false, arg0);
autoDecrement = true; autoDecrement = true;
repeatUpdateHandler.postDelayed(new RepetitiveUpdater(step), INITIAL_DELAY); repeatUpdateHandler.postDelayed(new RepetitiveUpdater(step), INITIAL_DELAY);
return false; return false;
@ -310,9 +365,21 @@ public class TopicActivity extends BaseActivity {
// When the button is released // When the button is released
decrement.setOnTouchListener(new View.OnTouchListener() { decrement.setOnTouchListener(new View.OnTouchListener() {
private Rect rect;
public boolean onTouch(View v, MotionEvent event) { public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP && autoDecrement) { if (event.getAction() == MotionEvent.ACTION_DOWN) {
rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
} else if (event.getAction() == MotionEvent.ACTION_UP && autoDecrement) {
autoDecrement = false;
paginationEnabled(true);
changePage(pageRequestValue - 1); changePage(pageRequestValue - 1);
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())) {
autoIncrement = false;
incrementPageRequestValue(thisPage - pageRequestValue);
paginationEnabled(true);
}
} }
return false; return false;
} }
@ -496,30 +563,4 @@ public class TopicActivity extends BaseActivity {
//postsList = TopicParser.parseTopic(topic, language); //postsList = TopicParser.parseTopic(topic, language);
} }
} }
/**
* This class is used to implement the repetitive incrementPageRequestValue/decrementPageRequestValue
* of page value when long pressing one of the page navigation buttons.
*/
class RepetitiveUpdater implements Runnable {
private final int step;
/**
* @param step number of pages to add/subtract on each repetition
*/
RepetitiveUpdater(int step) {
this.step = step;
}
public void run() {
long REPEAT_DELAY = 250;
if (autoIncrement) {
incrementPageRequestValue(step);
repeatUpdateHandler.postDelayed(new RepetitiveUpdater(step), REPEAT_DELAY);
} else if (autoDecrement) {
decrementPageRequestValue(step);
repeatUpdateHandler.postDelayed(new RepetitiveUpdater(step), REPEAT_DELAY);
}
}
}
} }

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

@ -11,6 +11,7 @@ import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v4.content.FileProvider;
import android.support.v4.content.res.ResourcesCompat; import android.support.v4.content.res.ResourcesCompat;
import android.support.v7.widget.CardView; import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
@ -229,6 +230,7 @@ class TopicAdapter extends RecyclerView.Adapter<TopicAdapter.MyViewHolder> {
} else //noinspection deprecation } else //noinspection deprecation
filesTextColor = context.getResources().getColor(R.color.accent); filesTextColor = context.getResources().getColor(R.color.accent);
holder.postFooter.removeAllViews();
for (final ThmmyFile 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);
@ -243,12 +245,12 @@ class TopicAdapter extends RecyclerView.Adapter<TopicAdapter.MyViewHolder> {
attached.setOnClickListener(new View.OnClickListener() { attached.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
if (((TopicActivity) context).requestPerms()) { //if (((BaseApplication) context).requestPerms()) {
downloadTask = new DownloadTask(); downloadTask = new DownloadTask();
downloadTask.execute(attachedFile); downloadTask.execute(attachedFile);
} else //} else
Toast.makeText(context, "Persmissions missing!", Toast.LENGTH_SHORT) // Toast.makeText(context, "Persmissions missing!", Toast.LENGTH_SHORT)
.show(); // .show();
} }
}); });
@ -658,7 +660,12 @@ class TopicAdapter extends RecyclerView.Adapter<TopicAdapter.MyViewHolder> {
Intent intent = new Intent(); Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW); intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(tempFile), mime); //intent.setDataAndType(Uri.fromFile(tempFile), mime);
intent.setDataAndType(FileProvider.getUriForFile(context, context.
getApplicationContext()
.getPackageName() + ".provider", tempFile), mime);
intent.setFlags(FLAG_ACTIVITY_NEW_TASK); intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent); context.startActivity(intent);
} }

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

@ -10,7 +10,6 @@ import android.os.Environment;
import android.os.StatFs; import android.os.StatFs;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.util.Log;
import android.webkit.MimeTypeMap; import android.webkit.MimeTypeMap;
import android.widget.Toast; import android.widget.Toast;
@ -25,6 +24,7 @@ import mthmmy.utils.Report;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
import static android.content.Context.MODE_PRIVATE;
import static gr.thmmy.mthmmy.base.BaseActivity.getClient; import static gr.thmmy.mthmmy.base.BaseActivity.getClient;
/** /**
@ -41,6 +41,7 @@ public class ThmmyFile {
private final String filename, fileInfo; private final String filename, fileInfo;
private String extension, filePath; private String extension, filePath;
private File file; private File file;
private boolean isInternal;
/** /**
* This constructor only creates a empty ThmmyFile object and <b>does not download</b> the file. To download * This constructor only creates a empty ThmmyFile object and <b>does not download</b> the file. To download
@ -53,6 +54,7 @@ public class ThmmyFile {
this.extension = null; this.extension = null;
this.filePath = null; this.filePath = null;
this.file = null; this.file = null;
this.isInternal = false;
} }
/** /**
@ -70,6 +72,7 @@ public class ThmmyFile {
this.extension = null; this.extension = null;
this.filePath = null; this.filePath = null;
this.file = null; this.file = null;
this.isInternal = false;
} }
public URL getFileUrl() { public URL getFileUrl() {
@ -122,6 +125,10 @@ public class ThmmyFile {
this.filePath = filePath; this.filePath = filePath;
} }
public boolean isInternal() {
return isInternal;
}
/** /**
* Used to download the file. If download is successful file's extension and path will be assigned * 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. * to object's fields and can be accessed using getter methods.
@ -143,12 +150,13 @@ public class ThmmyFile {
else if (filename == null || Objects.equals(filename, "")) else if (filename == null || Objects.equals(filename, ""))
throw new IllegalStateException("Internal error!\nNo filename was provided."); throw new IllegalStateException("Internal error!\nNo filename was provided.");
try { return downloadWithoutManager(context, fileUrl);
/*try {
downloadWithManager(context, fileUrl); downloadWithManager(context, fileUrl);
} catch (IllegalStateException e) { } catch (IllegalStateException e) {
return downloadWithoutManager(context, fileUrl); return downloadWithoutManager(context, fileUrl);
} }*/
return null; //return null;
} }
private void downloadWithManager(Context context, @NonNull URL pFileUrl) throws IllegalStateException, IOException { private void downloadWithManager(Context context, @NonNull URL pFileUrl) throws IllegalStateException, IOException {
@ -191,7 +199,11 @@ public class ThmmyFile {
if (file == null) { if (file == null) {
Report.d(TAG, "Error creating media file, check storage permissions!"); Report.d(TAG, "Error creating media file, check storage permissions!");
} else { } else {
FileOutputStream fos = new FileOutputStream(file); FileOutputStream fos;
if (isInternal)
fos = context.openFileOutput(filename, MODE_PRIVATE);
else
fos = new FileOutputStream(file);
fos.write(response.body().bytes()); fos.write(response.body().bytes());
fos.close(); fos.close();
@ -209,11 +221,11 @@ public class ThmmyFile {
String extState = Environment.getExternalStorageState(); String extState = Environment.getExternalStorageState();
if (Environment.isExternalStorageRemovable() && if (Environment.isExternalStorageRemovable() &&
Objects.equals(extState, Environment.MEDIA_MOUNTED)) { Objects.equals(extState, Environment.MEDIA_MOUNTED)) {
mediaStorageDir = new File(Environment.getExternalStorageDirectory() mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment
+ "/Android/data/gr.thmmy.mthmmy/" .DIRECTORY_DOWNLOADS), fileName);
+ "Downloads/");
} else { } else {
mediaStorageDir = new File(context.getFilesDir(), "Downloads"); mediaStorageDir = new File(context.getFilesDir(), "Downloads");
isInternal = true;
} }
//Creates the storage directory if it does not exist //Creates the storage directory if it does not exist
@ -224,7 +236,6 @@ public class ThmmyFile {
} }
} }
if (fileInfo != null) { if (fileInfo != null) {
if (fileInfo.contains("KB")) { if (fileInfo.contains("KB")) {
float fileSize = Float.parseFloat(fileInfo float fileSize = Float.parseFloat(fileInfo

11
app/src/main/res/xml/provider_paths.xml

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="my_downloads"
path="Downloads/"/>
<files-path
name="my_downloads"
path="Downloads/"/>
</paths>
Loading…
Cancel
Save