Pick files from StartActivity

Also add another way to find the filename.
filtering
Floens 10 years ago
parent 72b016764a
commit 097425a0ba
  1. 2
      Clover/app/src/main/AndroidManifest.xml
  2. 44
      Clover/app/src/main/java/org/floens/chan/core/http/ReplyManager.java
  3. 7
      Clover/app/src/main/java/org/floens/chan/core/presenter/ReplyPresenter.java
  4. 16
      Clover/app/src/main/java/org/floens/chan/ui/activity/StartActivity.java
  5. 96
      Clover/app/src/main/java/org/floens/chan/ui/helper/ImagePickDelegate.java
  6. 7
      Clover/app/src/main/java/org/floens/chan/ui/layout/ReplyLayout.java

@ -76,8 +76,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<activity android:name=".test.TestActivity" /> <activity android:name=".test.TestActivity" />
<activity android:name=".ui.activity.ImagePickActivity" />
<service <service
android:name=".ui.service.WatchNotifier" android:name=".ui.service.WatchNotifier"
android:exported="false" /> android:exported="false" />

@ -18,7 +18,6 @@
package org.floens.chan.core.http; package org.floens.chan.core.http;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request; import com.squareup.okhttp.Request;
@ -26,7 +25,6 @@ import com.squareup.okhttp.Request;
import org.floens.chan.Chan; import org.floens.chan.Chan;
import org.floens.chan.core.model.Loadable; import org.floens.chan.core.model.Loadable;
import org.floens.chan.core.model.Reply; import org.floens.chan.core.model.Reply;
import org.floens.chan.ui.activity.ImagePickActivity;
import java.io.File; import java.io.File;
import java.util.HashMap; import java.util.HashMap;
@ -40,7 +38,6 @@ public class ReplyManager {
private static final int TIMEOUT = 30000; private static final int TIMEOUT = 30000;
private final Context context; private final Context context;
private FileListener fileListener;
private OkHttpClient client; private OkHttpClient client;
private Map<Loadable, Reply> drafts = new HashMap<>(); private Map<Loadable, Reply> drafts = new HashMap<>();
@ -77,51 +74,10 @@ public class ReplyManager {
drafts.put(loadable, reply); drafts.put(loadable, reply);
} }
/**
* Pick an file. Starts up the ImagePickActivity.
*
* @param listener FileListener to listen on.
*/
public void pickFile(FileListener listener) {
fileListener = listener;
Intent intent = new Intent(context, ImagePickActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
public File getPickFile() { public File getPickFile() {
return new File(context.getCacheDir(), "picked_file"); return new File(context.getCacheDir(), "picked_file");
} }
public void _onFilePickLoading() {
if (fileListener != null) {
fileListener.onFilePickLoading();
}
}
public void _onFilePicked(String name, File file) {
if (fileListener != null) {
fileListener.onFilePicked(name, file);
fileListener = null;
}
}
public void _onFilePickError(boolean cancelled) {
if (fileListener != null) {
fileListener.onFilePickError(cancelled);
fileListener = null;
}
}
public interface FileListener {
void onFilePickLoading();
void onFilePicked(String name, File file);
void onFilePickError(boolean cancelled);
}
public void makeHttpCall(HttpCall httpCall, HttpCallback<? extends HttpCall> callback) { public void makeHttpCall(HttpCall httpCall, HttpCallback<? extends HttpCall> callback) {
httpCall.setCallback(callback); httpCall.setCallback(callback);

@ -33,6 +33,7 @@ import org.floens.chan.core.model.Reply;
import org.floens.chan.core.model.SavedReply; import org.floens.chan.core.model.SavedReply;
import org.floens.chan.core.settings.ChanSettings; import org.floens.chan.core.settings.ChanSettings;
import org.floens.chan.database.DatabaseManager; import org.floens.chan.database.DatabaseManager;
import org.floens.chan.ui.helper.ImagePickDelegate;
import org.floens.chan.ui.layout.CaptchaLayout; import org.floens.chan.ui.layout.CaptchaLayout;
import java.io.File; import java.io.File;
@ -43,7 +44,7 @@ import static org.floens.chan.utils.AndroidUtils.getReadableFileSize;
import static org.floens.chan.utils.AndroidUtils.getRes; import static org.floens.chan.utils.AndroidUtils.getRes;
import static org.floens.chan.utils.AndroidUtils.getString; import static org.floens.chan.utils.AndroidUtils.getString;
public class ReplyPresenter implements ReplyManager.FileListener, ReplyManager.HttpCallback<ReplyHttpCall>, CaptchaLayout.CaptchaCallback { public class ReplyPresenter implements ReplyManager.HttpCallback<ReplyHttpCall>, CaptchaLayout.CaptchaCallback, ImagePickDelegate.ImagePickCallback {
public enum Page { public enum Page {
INPUT, INPUT,
CAPTCHA, CAPTCHA,
@ -160,7 +161,7 @@ public class ReplyPresenter implements ReplyManager.FileListener, ReplyManager.H
} }
previewOpen = false; previewOpen = false;
} else { } else {
Chan.getReplyManager().pickFile(this); callback.getImagePickDelegate().pick(this);
pickingFile = true; pickingFile = true;
} }
} }
@ -424,5 +425,7 @@ public class ReplyPresenter implements ReplyManager.FileListener, ReplyManager.H
void highlightPostNo(int no); void highlightPostNo(int no);
void showThread(Loadable loadable); void showThread(Loadable loadable);
ImagePickDelegate getImagePickDelegate();
} }
} }

@ -37,6 +37,7 @@ import org.floens.chan.core.settings.ChanSettings;
import org.floens.chan.ui.controller.BrowseController; import org.floens.chan.ui.controller.BrowseController;
import org.floens.chan.ui.controller.RootNavigationController; import org.floens.chan.ui.controller.RootNavigationController;
import org.floens.chan.ui.controller.ViewThreadController; import org.floens.chan.ui.controller.ViewThreadController;
import org.floens.chan.ui.helper.ImagePickDelegate;
import org.floens.chan.ui.state.ChanState; import org.floens.chan.ui.state.ChanState;
import org.floens.chan.ui.theme.ThemeHelper; import org.floens.chan.ui.theme.ThemeHelper;
import org.floens.chan.utils.Logger; import org.floens.chan.utils.Logger;
@ -56,6 +57,8 @@ public class StartActivity extends AppCompatActivity {
private RootNavigationController rootNavigationController; private RootNavigationController rootNavigationController;
private BrowseController browseController; private BrowseController browseController;
private ImagePickDelegate imagePickDelegate;
public StartActivity() { public StartActivity() {
boardManager = Chan.getBoardManager(); boardManager = Chan.getBoardManager();
} }
@ -66,6 +69,8 @@ public class StartActivity extends AppCompatActivity {
ThemeHelper.getInstance().setupContext(this); ThemeHelper.getInstance().setupContext(this);
imagePickDelegate = new ImagePickDelegate(this);
contentView = (ViewGroup) findViewById(android.R.id.content); contentView = (ViewGroup) findViewById(android.R.id.content);
rootNavigationController = new RootNavigationController(this); rootNavigationController = new RootNavigationController(this);
@ -180,6 +185,10 @@ public class StartActivity extends AppCompatActivity {
return contentView; return contentView;
} }
public ImagePickDelegate getImagePickDelegate() {
return imagePickDelegate;
}
@Override @Override
public void onConfigurationChanged(Configuration newConfig) { public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig); super.onConfigurationChanged(newConfig);
@ -233,6 +242,13 @@ public class StartActivity extends AppCompatActivity {
Chan.getInstance().activityEnteredBackground(); Chan.getInstance().activityEnteredBackground();
} }
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
imagePickDelegate.onActivityResult(requestCode, resultCode, data);
}
private Controller stackTop() { private Controller stackTop() {
return stack.get(stack.size() - 1); return stack.get(stack.size() - 1);
} }

@ -15,13 +15,12 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.floens.chan.ui.activity; package org.floens.chan.ui.helper;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.database.Cursor; import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.provider.OpenableColumns; import android.provider.OpenableColumns;
@ -37,45 +36,60 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
public class ImagePickActivity extends Activity implements Runnable { import static org.floens.chan.utils.AndroidUtils.runOnUiThread;
public class ImagePickDelegate implements Runnable {
private static final String TAG = "ImagePickActivity"; private static final String TAG = "ImagePickActivity";
private static final int IMAGE_RESULT = 1; private static final int IMAGE_PICK_RESULT = 2;
private static final long MAX_FILE_SIZE = 15 * 1024 * 1024; private static final long MAX_FILE_SIZE = 15 * 1024 * 1024;
private static final String DEFAULT_FILE_NAME = "file";
private ReplyManager replyManager; private ReplyManager replyManager;
private Activity activity;
private ImagePickCallback callback;
private Uri uri; private Uri uri;
private String fileName = "file"; private String fileName;
private boolean success = false; private boolean success = false;
private File cacheFile; private File cacheFile;
@Override public ImagePickDelegate(Activity activity) {
public void onCreate(Bundle savedInstanceState) { this.activity = activity;
super.onCreate(savedInstanceState);
replyManager = Chan.getReplyManager(); replyManager = Chan.getReplyManager();
}
Intent intent = new Intent(Intent.ACTION_GET_CONTENT); public boolean pick(ImagePickCallback callback) {
intent.addCategory(Intent.CATEGORY_OPENABLE); if (this.callback != null) {
intent.setType("*/*"); return false;
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, IMAGE_RESULT);
} else { } else {
Logger.e(TAG, "No activity found to get file with"); this.callback = callback;
replyManager._onFilePickError(false);
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
if (intent.resolveActivity(activity.getPackageManager()) != null) {
activity.startActivityForResult(intent, IMAGE_PICK_RESULT);
return true;
} else {
Logger.e(TAG, "No activity found to get file with");
callback.onFilePickError(false);
reset();
return false;
}
} }
} }
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
boolean ok = false; boolean ok = false;
boolean cancelled = false; boolean cancelled = false;
if (requestCode == IMAGE_RESULT) { if (requestCode == IMAGE_PICK_RESULT) {
if (resultCode == RESULT_OK && data != null) { if (resultCode == Activity.RESULT_OK && data != null) {
uri = data.getData(); uri = data.getData();
Cursor returnCursor = getContentResolver().query(uri, null, null, null, null); Cursor returnCursor = activity.getContentResolver().query(uri, null, null, null, null);
if (returnCursor != null) { if (returnCursor != null) {
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
returnCursor.moveToFirst(); returnCursor.moveToFirst();
@ -86,20 +100,29 @@ public class ImagePickActivity extends Activity implements Runnable {
returnCursor.close(); returnCursor.close();
} }
replyManager._onFilePickLoading(); if (fileName == null) {
// As per the comment on OpenableColumns.DISPLAY_NAME:
// If this is not provided then the name should default to the last segment of the file's URI.
fileName = uri.getLastPathSegment();
}
if (fileName == null) {
fileName = DEFAULT_FILE_NAME;
}
callback.onFilePickLoading();
new Thread(this).start(); new Thread(this).start();
ok = true; ok = true;
} else if (resultCode == RESULT_CANCELED) { } else if (resultCode == Activity.RESULT_CANCELED) {
cancelled = true; cancelled = true;
} }
} }
if (!ok) { if (!ok) {
replyManager._onFilePickError(cancelled); callback.onFilePickError(cancelled);
reset();
} }
finish();
} }
@Override @Override
@ -110,7 +133,7 @@ public class ImagePickActivity extends Activity implements Runnable {
InputStream is = null; InputStream is = null;
OutputStream os = null; OutputStream os = null;
try { try {
fileDescriptor = getContentResolver().openFileDescriptor(uri, "r"); fileDescriptor = activity.getContentResolver().openFileDescriptor(uri, "r");
is = new FileInputStream(fileDescriptor.getFileDescriptor()); is = new FileInputStream(fileDescriptor.getFileDescriptor());
os = new FileOutputStream(cacheFile); os = new FileOutputStream(cacheFile);
boolean fullyCopied = IOUtils.copy(is, os, MAX_FILE_SIZE); boolean fullyCopied = IOUtils.copy(is, os, MAX_FILE_SIZE);
@ -135,11 +158,28 @@ public class ImagePickActivity extends Activity implements Runnable {
@Override @Override
public void run() { public void run() {
if (success) { if (success) {
replyManager._onFilePicked(fileName, cacheFile); callback.onFilePicked(fileName, cacheFile);
} else { } else {
replyManager._onFilePickError(false); callback.onFilePickError(false);
} }
reset();
} }
}); });
} }
private void reset() {
callback = null;
cacheFile = null;
success = false;
fileName = null;
uri = null;
}
public interface ImagePickCallback {
void onFilePickLoading();
void onFilePicked(String fileName, File file);
void onFilePickError(boolean cancelled);
}
} }

@ -38,6 +38,8 @@ import org.floens.chan.core.model.Loadable;
import org.floens.chan.core.model.Reply; import org.floens.chan.core.model.Reply;
import org.floens.chan.core.presenter.ReplyPresenter; import org.floens.chan.core.presenter.ReplyPresenter;
import org.floens.chan.core.settings.ChanSettings; import org.floens.chan.core.settings.ChanSettings;
import org.floens.chan.ui.helper.ImagePickDelegate;
import org.floens.chan.ui.activity.StartActivity;
import org.floens.chan.ui.drawable.DropdownArrowDrawable; import org.floens.chan.ui.drawable.DropdownArrowDrawable;
import org.floens.chan.ui.theme.ThemeHelper; import org.floens.chan.ui.theme.ThemeHelper;
import org.floens.chan.ui.view.LoadView; import org.floens.chan.ui.view.LoadView;
@ -396,6 +398,11 @@ public class ReplyLayout extends LoadView implements View.OnClickListener, Anima
callback.showThread(loadable); callback.showThread(loadable);
} }
@Override
public ImagePickDelegate getImagePickDelegate() {
return ((StartActivity) getContext()).getImagePickDelegate();
}
public interface ReplyLayoutCallback { public interface ReplyLayoutCallback {
void highlightPostNo(int no); void highlightPostNo(int no);

Loading…
Cancel
Save