package io.filepicker;
import android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
import android.content.ActivityNotFoundException;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import de.greenrobot.event.EventBus;
import io.filepicker.events.ApiErrorEvent;
import io.filepicker.events.FileExportedEvent;
import io.filepicker.events.FpFilesReceivedEvent;
import io.filepicker.events.GotContentEvent;
import io.filepicker.events.SignedOutEvent;
import io.filepicker.events.UploadFileErrorEvent;
import io.filepicker.models.DisplayedNode;
import io.filepicker.models.FPFile;
import io.filepicker.models.Folder;
import io.filepicker.models.Node;
import io.filepicker.services.ContentService;
import io.filepicker.utils.Constants;
import io.filepicker.utils.PreferencesUtils;
import io.filepicker.utils.SessionUtils;
import io.filepicker.utils.Utils;
public class Filepicker extends Activity implements AuthFragment.Contract, NodesFragment.Contract, ExportFragment.Contract {
private static final String LOG_TAG = Filepicker.class.getSimpleName();
private static final String AUTH_FRAGMENT_TAG = "authFragment";
public static final String NODE_EXTRA = "node";
public static final String FPFILES_EXTRA = "fpfile";
// We call this extra 'services' just because users are more used to this name
private static final String SELECTED_PROVIDERS_EXTRA = "services";
private static final String MULTIPLE_EXTRA = "multiple";
private static final String MIMETYPE_EXTRA = "mimetype";
private static final String LOCATION_EXTRA = "location";
private static final String PATH_EXTRA = "path";
private static final String CONTAINER_EXTRA = "container";
private static final String ACCESS_EXTRA = "access";
private static final String MAX_FILES_EXTRA = "maxFiles";
private static final String MAX_SIZE_EXTRA = "maxSize";
private static final String SHOW_ERROR_TOAST_EXTRA = "showErrorToast";
// Security extras
private static final String SECRET_EXTRA = "app_secret";
private static final String POLICY_CALLS_EXTRA = "policy_calls";
private static final String POLICY_HANDLE_EXTRA = "policy_handle";
private static final String POLICY_EXPIRY_EXTRA = "policy_expiry";
private static final String POLICY_MAX_SIZE_EXTRA = "policy_max_size";
private static final String POLICY_MIN_SIZE_EXTRA = "policy_min_size";
private static final String POLICY_PATH_EXTRA = "policy_path";
private static final String POLICY_CONTAINER_EXTRA = "policy_container";
private static final String API_KEY_STATE = "api_key_state";
private static final String IMAGE_URI_STATE = "image_uri_state";
private static final String LOADING_STATE = "loading_state";
private static final String DISPLAYED_NODES_LIST_STATE = "nodes_list_state";
private static final String CURRENT_DISPLAYED_NODE_STATE = "current_displayed_node_state";
private static final String NODE_CONTENT_STATE = "node_content_state";
private static final String IS_USER_AUTHORIZED_STATE = "is_user_authorized_state";
private static final String FOLDER_CLIENT_CODE_STATE = "folder_client_code_state";
public static final int REQUEST_CODE_GETFILE = 601;
public static final int REQUEST_CODE_TAKE_PICTURE = 602;
public static final int REQUEST_CODE_GET_LOCAL_FILE = 603;
public static final int REQUEST_CODE_EXPORT_FILE = 604;
public static final int REQUEST_CODE_VIDEO = 605;
// Action used by clients to indicate they want to export file
public static final String ACTION_EXPORT_FILE = "export_file";
private boolean mIsLoading = false;
private boolean mIsWaitingForContent = false;
private static String apiKey = "";
private static String appName = "";
// List which will be traversed while the user goes in the folders tree
private ArrayList<DisplayedNode> mDisplayedNodesList;
private DisplayedNode mCurrentDisplayedNode;
// True is user is authorized to the current node
private boolean mIsUserAuthorized;
// The code of the folder's client returned from API
private String mFolderClientCode;
private ArrayList<Node> mProviders;
private ArrayList<Node> mNodeContentList;
// Needed for camera request
private Uri imageUri;
private ProgressBar mProgressBar;
private static Uri mFileToExport;
private static FilepickerCallbackHandler sFilepickerCallbackHandler = new FilepickerCallbackHandler();
static boolean mExport = false;
private boolean allowMultiple = false;
public static void setKey(String apiKey) {
if (Filepicker.apiKey.isEmpty()) {
Filepicker.apiKey = apiKey;
}
}
public static String getApiKey() {
return apiKey;
}
public static void setAppName(String appName) {
Filepicker.appName = appName;
}
public static String getAppName() {
return appName;
}
public static void uploadLocalFile(Uri uri, Context context) {
ContentService.uploadFile(context, uri);
}
public static void uploadLocalFile(Uri uri, Context context, FilepickerCallback filepickerCallback) {
if (uri == null || context == null) {
return;
}
if (filepickerCallback != null) {
sFilepickerCallbackHandler.addCallback(uri, filepickerCallback);
}
uploadLocalFile(uri, context);
}
public static void cancelLocalFileUploading() {
ContentService.cancelAll();
}
public static void unregistedLocalFileUploadCallbacks() {
sFilepickerCallbackHandler.unregister();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_filepicker);
mProgressBar = (ProgressBar) findViewById(R.id.fpProgressBar);
initSavedState(savedInstanceState);
if (mDisplayedNodesList == null) {
mDisplayedNodesList = new ArrayList<>();
}
if (mNodeContentList == null) {
mNodeContentList = new ArrayList<>();
}
final ActionBar actionBar = getActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
validateApiKey();
initOptions();
// Shows provider's folders and files
if (mDisplayedNodesList.isEmpty()) {
// Go straight to the only 1 user-specified provider
if (mProviders.size() == 1) {
handleSingleProviderScenario();
} else {
setTitle(appName);
showProvidersList();
}
} else {
setTitle(mCurrentDisplayedNode.node.displayName);
if (!mIsUserAuthorized) {
showAuthFragment();
} else {
refreshFragment(false);
}
}
}
private void handleSingleProviderScenario() {
Node providerNode = mProviders.get(0);
if (providerNode.isCamera()) {
openCamera();
} else if (providerNode.isGallery()) {
openGallery(allowMultiple);
} else {
showNextNode(providerNode);
}
}
private void initSavedState(Bundle savedInstanceState) {
if (savedInstanceState != null) {
setKey(savedInstanceState.getString(API_KEY_STATE));
if (savedInstanceState.getString(IMAGE_URI_STATE) != null) {
imageUri = Uri.parse(savedInstanceState.getString(IMAGE_URI_STATE));
}
mIsLoading = savedInstanceState.getBoolean(LOADING_STATE);
mDisplayedNodesList = savedInstanceState.getParcelableArrayList(DISPLAYED_NODES_LIST_STATE);
mCurrentDisplayedNode = savedInstanceState.getParcelable(CURRENT_DISPLAYED_NODE_STATE);
mNodeContentList = savedInstanceState.getParcelableArrayList(NODE_CONTENT_STATE);
mIsUserAuthorized = savedInstanceState.getBoolean(IS_USER_AUTHORIZED_STATE);
mFolderClientCode = savedInstanceState.getString(FOLDER_CLIENT_CODE_STATE);
}
}
private void initOptions() {
Intent intent = getIntent();
PreferencesUtils prefs = PreferencesUtils.newInstance(this);
// Init Multiple option
if (intent.hasExtra(MULTIPLE_EXTRA)) {
allowMultiple = intent.getBooleanExtra(MULTIPLE_EXTRA, false);
prefs.setMultiple(allowMultiple);
} else {
prefs.clearMultiple();
}
// Init choosing mimetypes
if (intent.hasExtra(MIMETYPE_EXTRA)) {
String[] mimetypes = intent.getStringArrayExtra(MIMETYPE_EXTRA);
prefs.setMimetypes(mimetypes);
} else {
prefs.clearMimetypes();
}
// Init location
String location = intent.getStringExtra(LOCATION_EXTRA);
if (location != null) {
prefs.setLocation(location);
}
// Init path
String path = intent.getStringExtra(PATH_EXTRA);
if (path != null) {
prefs.setPath(path);
}
// Init container
String container = intent.getStringExtra(CONTAINER_EXTRA);
if (container != null) {
prefs.setContainer(container);
}
// Init access
String access = intent.getStringExtra(ACCESS_EXTRA);
if (access != null) {
prefs.setAccess(access);
}
// Init export
if (isValidExportRequest()) {
mExport = true;
mFileToExport = intent.getData();
} else {
mExport = false;
mFileToExport = null;
}
// Init Max Files option
if (intent.hasExtra(MAX_FILES_EXTRA)) {
prefs.setMaxFiles(intent.getIntExtra(MAX_FILES_EXTRA, -1));
} else {
prefs.clearMaxFiles();
}
// Init Max Size option
if (intent.hasExtra(MAX_SIZE_EXTRA)) {
prefs.setMaxSize(intent.getIntExtra(MAX_SIZE_EXTRA, -1));
} else {
prefs.clearMaxSize();
}
// Init providers
String[] selectedProviders = null;
if (getIntent().hasExtra(SELECTED_PROVIDERS_EXTRA)) {
selectedProviders = getIntent().getStringArrayExtra(SELECTED_PROVIDERS_EXTRA);
}
mProviders = Utils.getProvidersNodes(this, selectedProviders, mExport);
boolean showShowErrorToast = intent.getBooleanExtra(SHOW_ERROR_TOAST_EXTRA, true);
prefs.setShowErrorToast(showShowErrorToast);
prefs.setSecret(intent.getStringExtra(SECRET_EXTRA));
prefs.setPolicyCalls(intent.getStringArrayExtra(POLICY_CALLS_EXTRA));
prefs.setPolicyHandle(intent.getStringExtra(POLICY_HANDLE_EXTRA));
prefs.setPolicyExpiry(intent.getIntExtra(POLICY_EXPIRY_EXTRA, 0));
prefs.setPolicyMaxSize(intent.getIntExtra(POLICY_MAX_SIZE_EXTRA, 0));
prefs.setPolicyMinSize(intent.getIntExtra(POLICY_MIN_SIZE_EXTRA, 0));
prefs.setPolicyPath(intent.getStringExtra(POLICY_PATH_EXTRA));
prefs.setPolicyContainer(intent.getStringExtra(POLICY_CONTAINER_EXTRA));
}
@Override
protected void onSaveInstanceState(Bundle outState) {
// Save api key in case the activity was destroyed
outState.putString(API_KEY_STATE, getApiKey());
outState.putBoolean(LOADING_STATE, mIsLoading);
outState.putParcelableArrayList(DISPLAYED_NODES_LIST_STATE, mDisplayedNodesList);
outState.putParcelable(CURRENT_DISPLAYED_NODE_STATE, mCurrentDisplayedNode);
outState.putParcelableArrayList(NODE_CONTENT_STATE, mNodeContentList);
outState.putString(FOLDER_CLIENT_CODE_STATE, mFolderClientCode);
outState.putBoolean(IS_USER_AUTHORIZED_STATE, mIsUserAuthorized);
if (imageUri != null) {
outState.putString(IMAGE_URI_STATE, imageUri.toString());
}
super.onSaveInstanceState(outState);
}
@Override
protected void onResume() {
super.onResume();
EventBus.getDefault().register(this);
}
@Override
protected void onPause() {
EventBus.getDefault().unregister(this);
super.onPause();
}
@Override
public void onBackPressed() {
// In case content is being loaded, we are not waiting for it
mIsWaitingForContent = false;
if (mDisplayedNodesList != null && !mDisplayedNodesList.isEmpty()) {
removeLastNode();
if (!mDisplayedNodesList.isEmpty()) {
mCurrentDisplayedNode = mDisplayedNodesList.get(mDisplayedNodesList.size() - 1);
setTitle(mCurrentDisplayedNode.node.displayName);
Log.d(LOG_TAG, "Get cached data from " + mCurrentDisplayedNode.node.linkPath);
File currentFile = Utils.getCacheFile(this, mCurrentDisplayedNode.node.deslashedPath());
if (currentFile.exists()) {
showCachedNode(currentFile);
} else {
refreshCurrentlyDisplayedNode(mCurrentDisplayedNode, true);
}
} else if (mProviders.size() == 1) {
super.onBackPressed();
} else {
setTitle(getAppName());
showProvidersList();
}
} else {
super.onBackPressed();
}
}
@Override
protected void onDestroy() {
clearCachedFiles();
super.onDestroy();
}
public void getContent(Node node, boolean backPressed) {
mIsWaitingForContent = true;
showLoading();
ContentService.getContent(this, node, backPressed);
}
private void showFolderContent(Folder folder, boolean backPressed) {
mCurrentDisplayedNode.viewType = folder.view;
mNodeContentList = new ArrayList<>(Arrays.asList(folder.nodes));
// Cache items
new CacheGotItemsTask(this, mCurrentDisplayedNode.node).execute(mNodeContentList);
refreshFragment(backPressed);
}
private void refreshFragment(boolean backPressed) {
final Context context = getApplicationContext();
if (context != null) {
new Handler(context.getMainLooper()).post(new Runnable() {
@Override
public void run() {
hideLoading();
}
});
}
getFragmentManager().beginTransaction()
.replace(android.R.id.content, getContentFragment())
.commit();
}
private Fragment getContentFragment() {
if (mExport) {
return ExportFragment.newInstance(mCurrentDisplayedNode.node, mNodeContentList, mCurrentDisplayedNode.viewType);
} else {
return NodesFragment.newInstance(mCurrentDisplayedNode.node, mNodeContentList, mCurrentDisplayedNode.viewType);
}
}
private void showProvidersList() {
getFragmentManager().beginTransaction()
.replace(android.R.id.content, getProvidersFragment())
.commit();
}
private Fragment getProvidersFragment() {
if (mExport) {
return ExportFragment.newInstance(null, mProviders, Constants.LIST_VIEW);
} else {
return NodesFragment.newInstance(null, mProviders, Constants.LIST_VIEW);
}
}
@SuppressWarnings("unused")
public void onEvent(GotContentEvent event) {
if (!mIsWaitingForContent) {
return;
}
Folder folder = event.folder;
mIsUserAuthorized = folder.auth;
mFolderClientCode = event.folder.client;
if (mIsUserAuthorized) {
showFolderContent(folder, event.backPressed);
} else {
showAuthFragment();
}
}
private void showAuthFragment() {
final Context context = getApplicationContext();
if (context != null) {
new Handler(context.getMainLooper()).post(new Runnable() {
@Override
public void run() {
Toast.makeText(context,
"Connecting to " + mCurrentDisplayedNode.node.displayName + " ...",
Toast.LENGTH_SHORT).show();
}
});
}
getFragmentManager().beginTransaction()
.replace(android.R.id.content, AuthFragment.newInstance(mFolderClientCode), AUTH_FRAGMENT_TAG)
.commit();
}
@SuppressWarnings("unused")
public void onEvent(FpFilesReceivedEvent event) {
ArrayList<FPFile> fpFiles = event.fpFiles;
Intent resultIntent = new Intent();
resultIntent.putParcelableArrayListExtra(FPFILES_EXTRA, fpFiles);
setResult(RESULT_OK, resultIntent);
finish();
}
@SuppressWarnings("unused")
public void onEvent(ApiErrorEvent event) {
PreferencesUtils prefs = PreferencesUtils.newInstance(this);
if (prefs.shouldShowErrorToast()) {
showErrorMessage(event.error);
}
if (event instanceof UploadFileErrorEvent) {
Intent data = new Intent();
data.setData(((UploadFileErrorEvent)event).getUri());
setResult(RESULT_CANCELED, data);
}
finish();
}
private void showErrorMessage(ApiErrorEvent.ErrorType errorType) {
int errorMessage = R.string.error_unexpected;
switch (errorType) {
case NETWORK:
errorMessage = R.string.error_connection;
break;
case UNAUTHORIZED:
errorMessage = R.string.error_authorization;
break;
case INVALID_FILE:
errorMessage = R.string.error_invalid_file;
break;
}
Utils.showQuickToast(this, errorMessage);
}
@SuppressWarnings("unused")
public void onEvent(SignedOutEvent event) {
clearSession(this);
showProvidersList();
}
@SuppressWarnings("unused")
public void onEvent(FileExportedEvent event) {
String message = "File " + event.fpFile.getFilename() + " was exported to " + event.path.split("/")[0];
Utils.showQuickToast(this, message);
Intent resultIntent = new Intent();
ArrayList<FPFile> result = new ArrayList<>();
result.add(event.fpFile);
resultIntent.putParcelableArrayListExtra(FPFILES_EXTRA, result);
setResult(RESULT_OK, resultIntent);
finish();
}
public void proceedAfterAuth() {
// Try getting content again
getContent(mCurrentDisplayedNode.node, false);
}
private void validateApiKey() {
if (apiKey.isEmpty() || !apiKey.startsWith("A") || !apiKey.endsWith("z") || apiKey.length() != 22) {
Toast.makeText(this, R.string.apikey_missing, Toast.LENGTH_SHORT).show();
setResult(RESULT_CANCELED);
finish();
}
}
@Override
public void pickFiles(ArrayList<Node> pickedFiles) {
showLoading();
ContentService.pickFiles(this, pickedFiles);
}
// Removes currently last node's cached file and the node itself from the list
private void removeLastNode() {
File file = Utils.getCacheFile(this, mCurrentDisplayedNode.node.deslashedPath());
if (file.exists()) {
file.delete();
}
mDisplayedNodesList.remove(mCurrentDisplayedNode);
}
@Override
public void showNextNode(Node newNode) {
mCurrentDisplayedNode = new DisplayedNode(newNode, Constants.LIST_VIEW); // Default view is listview
mDisplayedNodesList.add(mCurrentDisplayedNode);
refreshCurrentlyDisplayedNode(mCurrentDisplayedNode, false);
}
private void refreshCurrentlyDisplayedNode(DisplayedNode displayedNode, boolean isBackPressed) {
setTitle(displayedNode.node.displayName);
getContent(displayedNode.node, isBackPressed);
}
private void setTitle(String title) {
if (getActionBar() != null) {
getActionBar().setTitle(title);
}
}
@Override
public void exportFile(String filename) {
showLoading();
ContentService.exportFile(this, mCurrentDisplayedNode.node, mFileToExport, filename);
}
@Override
public Uri getFileToExport() {
return mFileToExport;
}
@Override
public void logoutUser() {
Filepicker.clearSession(this);
}
@Override
public void openCamera() {
if (isOnlyVideoCamera()) {
recordVideo();
} else {
takePhoto();
}
}
private void recordVideo() {
Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
if (takeVideoIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takeVideoIntent, REQUEST_CODE_VIDEO);
}
}
private void takePhoto() {
setCameraImageUri();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
try {
startActivityForResult(intent, REQUEST_CODE_TAKE_PICTURE);
} catch(ActivityNotFoundException e) {
Utils.showQuickToast(this, R.string.camera_not_found);
}
}
@Override
public void openGallery(boolean allowMultiple) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(isOnlyVideoCamera() ? Constants.MIMETYPE_VIDEO : Constants.MIMETYPE_IMAGE);
intent.addCategory(Intent.CATEGORY_OPENABLE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, allowMultiple);
}
startActivityForResult(intent, REQUEST_CODE_GET_LOCAL_FILE);
}
private void uploadLocalFile(Uri uri) {
showLoading();
uploadLocalFile(uri, this);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
// For Camera and Gallery
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_CANCELED) {
finish();
return;
}
switch (requestCode) {
case REQUEST_CODE_GETFILE:
if (resultCode == RESULT_OK) {
setResult(RESULT_OK, data);
finish();
}
break;
case REQUEST_CODE_EXPORT_FILE:
if (resultCode == RESULT_OK) {
setResult(RESULT_OK, data);
finish();
}
break;
case REQUEST_CODE_GET_LOCAL_FILE:
case REQUEST_CODE_VIDEO:
if (resultCode == RESULT_OK) {
Utils.showQuickToast(this, R.string.uploading_image);
showLoading();
uploadLocalFile(data.getData());
}
break;
case REQUEST_CODE_TAKE_PICTURE:
if (resultCode == RESULT_OK) {
Utils.showQuickToast(this, R.string.uploading_image);
uploadLocalFile(imageUri);
}
break;
}
}
private void showLoading() {
mIsLoading = true;
updateLoadingView();
}
private void hideLoading() {
mIsLoading = false;
updateLoadingView();
}
private void updateLoadingView() {
mProgressBar.setVisibility(mIsLoading ? View.VISIBLE : View.GONE);
Fragment frag = getFragmentManager().findFragmentById(android.R.id.content);
if (frag != null && frag.getView() != null) {
frag.getView().setEnabled(!mIsLoading);
frag.getView().setAlpha(mIsLoading ? 0.2f : 1f);
}
}
private void setCameraImageUri() {
String fileName = "" + System.currentTimeMillis() + ".jpg";
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, fileName);
values.put(MediaStore.Images.Media.DESCRIPTION, "Image captured by camera");
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
imageUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
}
// Checks if intent has action ACTION_EXPORT_FILE and data
private boolean isValidExportRequest() {
Intent intent = getIntent();
return intent.getAction() != null &&
intent.getAction().equals(ACTION_EXPORT_FILE) &&
intent.getData() != null;
}
private void showCachedNode(File nodeCachedData) {
new AsyncTask<File, Void, Void>() {
@Override
protected Void doInBackground(File... params) {
mNodeContentList = new ArrayList<>();
File nodeCachedData = params[0];
try {
Log.d(LOG_TAG, "Reading from file " + nodeCachedData.getAbsolutePath());
BufferedReader br = new BufferedReader(new FileReader(nodeCachedData));
String line;
while ((line = br.readLine()) != null) {
for (Node node : new Gson().fromJson(line, Node[].class)) {
mNodeContentList.add(node);
}
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void param) {
refreshFragment(true);
}
}.execute(nodeCachedData);
}
private void clearCachedFiles() {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
Utils.clearCachedFiles(Filepicker.this);
return null;
}
}.execute();
}
private static class CacheGotItemsTask extends AsyncTask<ArrayList<Node>, Void, Void> {
private final Context mContext;
private final Node mLastNode;
public CacheGotItemsTask(Context context, Node lastNode) {
this.mContext = context;
this.mLastNode = lastNode;
}
@Override
protected Void doInBackground(ArrayList<Node>... params) {
final ArrayList<Node> nodes = params[0];
if (nodes != null && !nodes.isEmpty() && mLastNode != null) {
Gson gson = new Gson();
JsonElement jsonElement = new JsonParser().parse(gson.toJson(nodes));
String result = gson.toJson(jsonElement);
File file = Utils.getCacheFile(mContext, mLastNode.deslashedPath());
try {
Log.d(LOG_TAG, "Writing to file " + file.getAbsolutePath());
FileOutputStream output = new FileOutputStream(file);
output.write(result.getBytes());
output.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}
public static void clearSession(Context context) {
SessionUtils.clearSessionCookies(context);
}
private boolean isOnlyVideoCamera() {
PreferencesUtils prefs = PreferencesUtils.newInstance(this);
return prefs.isMimetypeSet("video") && !prefs.isMimetypeSet("image");
}
}