diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a2dfc7ee..67bf2e68 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,11 +1,11 @@ + package="gr.thmmy.mthmmy"> - - - - + + + + - + - + - + android:windowSoftInputMode="adjustPan"> + android:value=".activities.main.MainActivity" /> + android:value=".activities.main.MainActivity" /> - + android:theme="@style/AppTheme.NoActionBar"> + android:value=".activities.main.MainActivity" /> + android:value=".activities.main.MainActivity" /> + android:value=".activities.main.MainActivity" /> + android:resource="@xml/provider_paths" /> + + \ No newline at end of file diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java index 6c670797..043a5a6c 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java @@ -1,11 +1,8 @@ package gr.thmmy.mthmmy.activities.topic; -import android.Manifest; -import android.content.pm.PackageManager; import android.graphics.Rect; import android.net.Uri; import android.os.AsyncTask; -import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.support.design.widget.FloatingActionButton; @@ -59,7 +56,6 @@ public class TopicActivity extends BaseActivity { * The key to use when putting topic's title String to {@link TopicActivity}'s Bundle. */ public static final String BUNDLE_TOPIC_TITLE = "TOPIC_TITLE"; - private static final int PERMISSIONS_REQUEST_CODE = 69; private static TopicTask topicTask; //About posts private TopicAdapter topicAdapter; @@ -101,7 +97,6 @@ public class TopicActivity extends BaseActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_topic); - requestPerms(); Bundle extras = getIntent().getExtras(); topicTitle = extras.getString(BUNDLE_TOPIC_TITLE); @@ -135,7 +130,7 @@ public class TopicActivity extends BaseActivity { recyclerView.setHasFixedSize(true); LinearLayoutManager layoutManager = new LinearLayoutManager(getApplicationContext()); recyclerView.setLayoutManager(layoutManager); - topicAdapter = new TopicAdapter(getApplicationContext(), progressBar, postsList, + topicAdapter = new TopicAdapter(this, progressBar, postsList, topicTask); recyclerView.setAdapter(topicAdapter); @@ -213,30 +208,6 @@ public class TopicActivity extends BaseActivity { topicTask.cancel(true); } - /*@Override - public void onRequestPermissionsResult(int permsRequestCode, @NonNull String[] permissions - , @NonNull int[] grantResults) { - switch (permsRequestCode) { - case PERMISSIONS_REQUEST_CODE: - readWriteAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED; - break; - } - }*/ - - boolean requestPerms() { //Runtime permissions request for devices with API >= 23 - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) { - String[] PERMISSIONS_STORAGE = { - Manifest.permission.READ_EXTERNAL_STORAGE, - Manifest.permission.WRITE_EXTERNAL_STORAGE}; - - if (checkSelfPermission(PERMISSIONS_STORAGE[0]) == PackageManager.PERMISSION_DENIED || - checkSelfPermission(PERMISSIONS_STORAGE[1]) == PackageManager.PERMISSION_DENIED) { - requestPermissions(PERMISSIONS_STORAGE, PERMISSIONS_REQUEST_CODE); - return false; - } else return true; - } else return true; - } - //--------------------------------------BOTTOM NAV BAR METHODS---------------------------------- /** diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java index ceb363f5..dd9cee02 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java @@ -43,6 +43,7 @@ import java.util.Objects; import gr.thmmy.mthmmy.R; import gr.thmmy.mthmmy.activities.board.BoardActivity; import gr.thmmy.mthmmy.activities.profile.ProfileActivity; +import gr.thmmy.mthmmy.base.BaseActivity; import gr.thmmy.mthmmy.model.Post; import gr.thmmy.mthmmy.model.ThmmyPage; import gr.thmmy.mthmmy.utils.CircleTransform; @@ -56,7 +57,6 @@ import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_THUMBNAIL_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_USERNAME; -import static gr.thmmy.mthmmy.activities.topic.TopicActivity.base_url; import static gr.thmmy.mthmmy.activities.topic.TopicActivity.toQuoteList; /** @@ -245,12 +245,7 @@ class TopicAdapter extends RecyclerView.Adapter { attached.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - //if (((BaseApplication) context).requestPerms()) { - downloadTask = new DownloadTask(); - downloadTask.execute(attachedFile); - //} else - // Toast.makeText(context, "Persmissions missing!", Toast.LENGTH_SHORT) - // .show(); + ((BaseActivity) context).launchDownloadService(attachedFile); } }); diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java index 1d323135..de2b5a7e 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -1,13 +1,16 @@ package gr.thmmy.mthmmy.base; +import android.Manifest; import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; @@ -38,7 +41,9 @@ import gr.thmmy.mthmmy.activities.downloads.DownloadsActivity; import gr.thmmy.mthmmy.activities.main.MainActivity; import gr.thmmy.mthmmy.activities.profile.ProfileActivity; import gr.thmmy.mthmmy.model.Bookmark; +import gr.thmmy.mthmmy.services.DownloadService; import gr.thmmy.mthmmy.session.SessionManager; +import gr.thmmy.mthmmy.utils.FileManager.ThmmyFile; import gr.thmmy.mthmmy.utils.ObjectSerializer; import okhttp3.OkHttpClient; @@ -48,6 +53,8 @@ import static gr.thmmy.mthmmy.activities.downloads.DownloadsActivity.BUNDLE_DOWN import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_THUMBNAIL_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_USERNAME; +import static gr.thmmy.mthmmy.services.DownloadService.ACTION_DOWNLOAD; +import static gr.thmmy.mthmmy.services.DownloadService.EXTRA_DOWNLOAD_URL; public abstract class BaseActivity extends AppCompatActivity { // Client & Cookies @@ -79,6 +86,7 @@ public abstract class BaseActivity extends AppCompatActivity { if (sessionManager == null) sessionManager = BaseApplication.getInstance().getSessionManager(); + if (sessionManager.isLoggedIn()) { if (bookmarked == null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { @@ -538,4 +546,72 @@ public abstract class BaseActivity extends AppCompatActivity { return -1; } //-------------------------------------------BOOKMARKS END------------------------------------------ + + //-------PERMS--------- + private static final int PERMISSIONS_REQUEST_CODE = 69; + + //True if permissions are OK + private boolean checkPerms() { + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) { + String[] PERMISSIONS_STORAGE = { + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE}; + + return !(checkSelfPermission(PERMISSIONS_STORAGE[0]) == PackageManager.PERMISSION_DENIED || + checkSelfPermission(PERMISSIONS_STORAGE[1]) == PackageManager.PERMISSION_DENIED); + } + return true; + } + + //Display popup gor user to grant permission + public void requestPerms() { //Runtime permissions request for devices with API >= 23 + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) { + String[] PERMISSIONS_STORAGE = { + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE}; + + requestPermissions(PERMISSIONS_STORAGE, PERMISSIONS_REQUEST_CODE); + } + } + + + @Override + public void onRequestPermissionsResult(int permsRequestCode, @NonNull String[] permissions + , @NonNull int[] grantResults) { + switch (permsRequestCode) { + case PERMISSIONS_REQUEST_CODE: + launchDownloadService(); + break; + } + } + + + //----------------------------------DOWNLOAD------------------ + private ThmmyFile tempThmmyFile; + public void launchDownloadService(ThmmyFile thmmyFile) { + if(checkPerms()) + { + Intent i = new Intent(this, DownloadService.class); + i.setAction(ACTION_DOWNLOAD); + i.putExtra(EXTRA_DOWNLOAD_URL, thmmyFile.getFileUrl().toString()); + startService(i); + } + else + { + tempThmmyFile = thmmyFile; + requestPerms(); + } + } + + //Uses temp file - called after permission grant + public void launchDownloadService() { + if(checkPerms()) + { + Intent i = new Intent(this, DownloadService.class); + i.setAction(ACTION_DOWNLOAD); + i.putExtra(EXTRA_DOWNLOAD_URL, tempThmmyFile.getFileUrl().toString()); + startService(i); + } + } + } diff --git a/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java b/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java new file mode 100644 index 00000000..97d05b53 --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java @@ -0,0 +1,100 @@ +package gr.thmmy.mthmmy.services; + +import android.app.IntentService; +import android.content.Context; +import android.content.Intent; +import android.os.Environment; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; + +import gr.thmmy.mthmmy.base.BaseApplication; +import mthmmy.utils.Report; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okio.BufferedSink; +import okio.Okio; + +/** + * An {@link IntentService} subclass for handling asynchronous task requests in + * a service on a separate handler thread. + */ +public class DownloadService extends IntentService { + private static final String TAG = "DownloadService"; + + public static final String ACTION_DOWNLOAD = "gr.thmmy.mthmmy.services.action.DOWNLOAD"; + public static final String EXTRA_DOWNLOAD_URL = "gr.thmmy.mthmmy.services.extra.DOWNLOAD_URL"; + + public DownloadService() { + super("DownloadService"); + } + + /** + * Starts this service to perform action Download with the given parameters. If + * the service is already performing a task this action will be queued. + * + * @see IntentService + */ + public static void startActionDownload(Context context, String downloadUrl) { + Intent intent = new Intent(context, DownloadService.class); + intent.setAction(ACTION_DOWNLOAD); + intent.putExtra(EXTRA_DOWNLOAD_URL, downloadUrl); + context.startService(intent); + } + + @Override + protected void onHandleIntent(Intent intent) { + if (intent != null) { + final String action = intent.getAction(); + if (ACTION_DOWNLOAD.equals(action)) { + final String downloadLink = intent.getStringExtra(EXTRA_DOWNLOAD_URL); + handleActionDownload(downloadLink); + } + } + } + + /** + * Handle action Foo in the provided background thread with the provided + * parameters. + */ + private void handleActionDownload(String downloadLink) { + OkHttpClient client = BaseApplication.getInstance().getClient(); + BufferedSink sink = null; + try { + Request request = new Request.Builder().url(downloadLink).build(); + Response response = client.newCall(request).execute(); + + String filename = response.headers("Content-Disposition").toString().split("\"")[1]; + + File dirPath = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "mthmmy"); + if(!dirPath.isDirectory()) + dirPath.mkdirs(); + + File file = new File(dirPath, filename); + + sink = Okio.buffer(Okio.sink(file)); + sink.writeAll(response.body().source()); + sink.flush(); + Report.i(TAG, "Download OK!"); + } + catch (FileNotFoundException e){ + Report.e(TAG, "FileNotFound", e); + Report.i(TAG, "Download failed..."); + } + catch (IOException e){ + Report.e(TAG, "IOException", e); + Report.i(TAG, "Download failed..."); + } finally { + if (sink!= null) { + try { + sink.close(); + } catch (IOException e) { + // Ignore - Significant errors should already have been reported + } + } + } + } + +}