mirror of
https://github.com/TwidereProject/Twidere-Android
synced 2025-02-17 04:00:48 +01:00
using file provider to share files
changed all classes ended with Trojan 'cause some anti-virus apps indicates this a virus, LMFAO
This commit is contained in:
parent
e1f1e5299b
commit
54a1bcdc9c
@ -24,7 +24,7 @@ import java.lang.reflect.Type;
|
||||
/**
|
||||
* Created by mariotaku on 15/12/13.
|
||||
*/
|
||||
public class ParameterizedTypeTrojan {
|
||||
public class ParameterizedTypeAccessor {
|
||||
|
||||
public static <T> ParameterizedType<T> create(Type type) {
|
||||
return new ParameterizedType.ConcreteParameterizedType<>(type);
|
@ -67,6 +67,8 @@ public interface TwidereConstants extends SharedPreferenceConstants, IntentConst
|
||||
String PROTOCOL_CONTENT = SCHEME_CONTENT + "://";
|
||||
String PROTOCOL_TWIDERE = SCHEME_TWIDERE + "://";
|
||||
|
||||
String AUTHORITY_TWIDERE_FILE = "twidere.file";
|
||||
|
||||
String AUTHORITY_USER = "user";
|
||||
String AUTHORITY_HOME = "home";
|
||||
String AUTHORITY_MENTIONS = "mentions";
|
||||
|
@ -23,7 +23,7 @@ import android.support.v4.util.SimpleArrayMap;
|
||||
|
||||
import com.bluelinelabs.logansquare.LoganSquare;
|
||||
import com.bluelinelabs.logansquare.ParameterizedType;
|
||||
import com.bluelinelabs.logansquare.ParameterizedTypeTrojan;
|
||||
import com.bluelinelabs.logansquare.ParameterizedTypeAccessor;
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
|
||||
import org.mariotaku.restfu.Converter;
|
||||
@ -69,7 +69,7 @@ public class TwitterConverter implements Converter {
|
||||
|
||||
private static <T> T parseOrThrow(RestHttpResponse resp, InputStream stream, Type type) throws IOException, TwitterException {
|
||||
try {
|
||||
final ParameterizedType<T> parameterizedType = ParameterizedTypeTrojan.create(type);
|
||||
final ParameterizedType<T> parameterizedType = ParameterizedTypeAccessor.create(type);
|
||||
final T parse = LoganSquare.parse(stream, parameterizedType);
|
||||
if (TwitterException.class == type && parse == null) {
|
||||
throw new TwitterException();
|
||||
|
@ -114,6 +114,7 @@ dependencies {
|
||||
compile fileTree(dir: 'libs/main', include: ['*.jar'])
|
||||
provided 'javax.annotation:jsr250-api:1.0'
|
||||
// googleCompile fileTree(dir: 'libs/google', include: ['*.jar'])
|
||||
compile 'com.google.android.gms:play-services-appindexing:8.1.0'
|
||||
}
|
||||
|
||||
task svgToDrawable(type: SvgDrawableTask) {
|
||||
|
@ -526,6 +526,15 @@
|
||||
android:name=".provider.RecentSearchProvider"
|
||||
android:authorities="org.mariotaku.twidere.provider.SearchRecentSuggestions"
|
||||
tools:ignore="ExportedContentProvider"/>
|
||||
<provider
|
||||
android:name="android.support.v4.content.FileProvider"
|
||||
android:authorities="twidere.file"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_paths"/>
|
||||
</provider>
|
||||
|
||||
<receiver android:name=".receiver.ConnectivityStateReceiver">
|
||||
<intent-filter>
|
||||
@ -558,6 +567,11 @@
|
||||
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<!-- ATTENTION: This was auto-generated to add Google Play services to your project for
|
||||
App Indexing. See https://g.co/AppIndexing/AndroidStudio for more information. -->
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.version"
|
||||
android:value="@integer/google_play_services_version"/>
|
||||
|
||||
</application>
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
package android.support.v4.app;
|
||||
|
||||
public class BackStackEntryTrojan {
|
||||
public class BackStackEntryAccessor {
|
||||
|
||||
public static Fragment getFragmentInBackStackRecord(final FragmentManager.BackStackEntry entry) {
|
||||
if (entry instanceof BackStackRecord) return ((BackStackRecord) entry).mHead.fragment;
|
@ -2,7 +2,7 @@ package android.support.v4.app;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
public class FragmentTrojan {
|
||||
public class FragmentAccessor {
|
||||
|
||||
public static Bundle getSavedFragmentState(final Fragment f) {
|
||||
return f.mSavedFragmentState;
|
@ -2,7 +2,7 @@ package android.support.v4.app;
|
||||
|
||||
import android.support.v4.view.LayoutInflaterFactory;
|
||||
|
||||
public class FragmentManagerTrojan {
|
||||
public class FragmentManagerAccessor {
|
||||
|
||||
public static boolean isStateSaved(final FragmentManager fm) {
|
||||
if (fm instanceof FragmentManagerImpl) return ((FragmentManagerImpl) fm).mStateSaved;
|
@ -22,7 +22,7 @@ package android.support.v4.content;
|
||||
/**
|
||||
* Created by mariotaku on 15/7/5.
|
||||
*/
|
||||
public class LoaderTrojan {
|
||||
public class LoaderAccessor {
|
||||
public static <T> boolean isContentChanged(final Loader<T> loader) {
|
||||
return loader.mContentChanged;
|
||||
}
|
@ -24,7 +24,7 @@ import android.view.View;
|
||||
/**
|
||||
* Created by mariotaku on 15/7/18.
|
||||
*/
|
||||
public class DrawerLayoutTrojan {
|
||||
public class DrawerLayoutAccessor {
|
||||
|
||||
public static View findDrawerWithGravity(DrawerLayout layout, int gravity) {
|
||||
return layout.findDrawerWithGravity(gravity);
|
@ -24,7 +24,7 @@ import android.support.annotation.Nullable;
|
||||
/**
|
||||
* Created by mariotaku on 15/4/27.
|
||||
*/
|
||||
public class AppCompatDelegateTrojan {
|
||||
public class AppCompatDelegateAccessor {
|
||||
|
||||
@Nullable
|
||||
public static ActionBar peekActionBar(@Nullable AppCompatDelegate delegate) {
|
@ -24,7 +24,7 @@ import android.support.v7.widget.RecyclerView.ViewHolder;
|
||||
/**
|
||||
* Created by mariotaku on 14/12/6.
|
||||
*/
|
||||
public class ViewHolderTrojan {
|
||||
public class ViewHolderAccessor {
|
||||
|
||||
public static boolean isRemoved(ViewHolder holder) {
|
||||
return holder.isRemoved();
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.activity.iface;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/12/28.
|
||||
*/
|
||||
public interface IExtendedActivity {
|
||||
|
||||
void executeAfterFragmentResumed(Action action);
|
||||
|
||||
interface Action {
|
||||
void execute(IExtendedActivity activity);
|
||||
}
|
||||
}
|
@ -31,6 +31,7 @@ import com.squareup.otto.Bus;
|
||||
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.activity.iface.IControlBarActivity;
|
||||
import org.mariotaku.twidere.activity.iface.IExtendedActivity;
|
||||
import org.mariotaku.twidere.app.TwidereApplication;
|
||||
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback;
|
||||
import org.mariotaku.twidere.util.ActivityTracker;
|
||||
@ -46,13 +47,15 @@ import org.mariotaku.twidere.util.dagger.DaggerGeneralComponent;
|
||||
import org.mariotaku.twidere.view.iface.IExtendedView.OnFitSystemWindowsListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@SuppressLint("Registered")
|
||||
public class BaseAppCompatActivity extends ThemedAppCompatActivity implements Constants,
|
||||
OnFitSystemWindowsListener, SystemWindowsInsetsCallback, IControlBarActivity,
|
||||
KeyboardShortcutCallback {
|
||||
KeyboardShortcutCallback, IExtendedActivity {
|
||||
|
||||
// Utility classes
|
||||
@Inject
|
||||
@ -78,6 +81,8 @@ public class BaseAppCompatActivity extends ThemedAppCompatActivity implements Co
|
||||
private boolean mIsVisible;
|
||||
private Rect mSystemWindowsInsets;
|
||||
private int mKeyMetaState;
|
||||
private boolean mFragmentResumed;
|
||||
private Queue<Action> mActionQueue = new LinkedList<>();
|
||||
|
||||
@Override
|
||||
public boolean getSystemWindowsInsets(Rect insets) {
|
||||
@ -183,6 +188,7 @@ public class BaseAppCompatActivity extends ThemedAppCompatActivity implements Co
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
mFragmentResumed = false;
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@ -250,4 +256,24 @@ public class BaseAppCompatActivity extends ThemedAppCompatActivity implements Co
|
||||
return mKeyMetaState;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResumeFragments() {
|
||||
super.onResumeFragments();
|
||||
mFragmentResumed = true;
|
||||
executePending();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeAfterFragmentResumed(Action action) {
|
||||
mActionQueue.add(action);
|
||||
executePending();
|
||||
}
|
||||
|
||||
private void executePending() {
|
||||
if (!mFragmentResumed) return;
|
||||
Action action;
|
||||
while ((action = mActionQueue.poll()) != null) {
|
||||
action.execute(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ import android.support.v4.view.ViewCompat;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v4.view.ViewPager.OnPageChangeListener;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.support.v4.widget.DrawerLayoutTrojan;
|
||||
import android.support.v4.widget.DrawerLayoutAccessor;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
@ -257,7 +257,7 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen
|
||||
switch (action) {
|
||||
case ACTION_NAVIGATION_PREVIOUS_TAB: {
|
||||
final int previous = mViewPager.getCurrentItem() - 1;
|
||||
if (previous < 0 && DrawerLayoutTrojan.findDrawerWithGravity(mDrawerLayout, Gravity.START) != null) {
|
||||
if (previous < 0 && DrawerLayoutAccessor.findDrawerWithGravity(mDrawerLayout, Gravity.START) != null) {
|
||||
mDrawerLayout.openDrawer(GravityCompat.START);
|
||||
setControlBarVisibleAnimate(true);
|
||||
} else if (previous < mPagerAdapter.getCount()) {
|
||||
@ -271,7 +271,7 @@ public class HomeActivity extends BaseAppCompatActivity implements OnClickListen
|
||||
}
|
||||
case ACTION_NAVIGATION_NEXT_TAB: {
|
||||
final int next = mViewPager.getCurrentItem() + 1;
|
||||
if (next >= mPagerAdapter.getCount() && DrawerLayoutTrojan.findDrawerWithGravity(mDrawerLayout, Gravity.END) != null) {
|
||||
if (next >= mPagerAdapter.getCount() && DrawerLayoutAccessor.findDrawerWithGravity(mDrawerLayout, Gravity.END) != null) {
|
||||
mDrawerLayout.openDrawer(GravityCompat.END);
|
||||
setControlBarVisibleAnimate(true);
|
||||
} else if (next >= 0) {
|
||||
|
@ -110,7 +110,7 @@ public class LinkHandlerActivity extends BaseAppCompatActivity implements System
|
||||
|
||||
@Override
|
||||
public int getThemeResourceId() {
|
||||
return ThemeUtils.getDialogWhenLargeThemeResource(this);
|
||||
return ThemeUtils.getNoActionBarThemeResource(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -17,6 +17,9 @@
|
||||
package org.mariotaku.twidere.activity.support;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.DialogFragment;
|
||||
import android.app.FragmentManager;
|
||||
import android.content.Intent;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaPlayer;
|
||||
@ -32,8 +35,10 @@ import android.os.Handler;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||
import android.support.v4.content.FileProvider;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.support.v4.view.ViewPager;
|
||||
@ -58,15 +63,15 @@ import android.widget.Toast;
|
||||
|
||||
import com.davemorrissey.labs.subscaleview.ImageSource;
|
||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;
|
||||
import com.desmond.asyncmanager.AsyncManager;
|
||||
import com.desmond.asyncmanager.TaskRunnable;
|
||||
import com.pnikosis.materialishprogress.ProgressWheel;
|
||||
import com.sprylab.android.widget.TextureVideoView;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.iface.IExtendedActivity;
|
||||
import org.mariotaku.twidere.adapter.support.SupportFixedFragmentStatePagerAdapter;
|
||||
import org.mariotaku.twidere.fragment.ProgressDialogFragment;
|
||||
import org.mariotaku.twidere.fragment.support.BaseSupportFragment;
|
||||
import org.mariotaku.twidere.fragment.support.ViewStatusDialogFragment;
|
||||
import org.mariotaku.twidere.loader.support.TileImageLoader;
|
||||
@ -75,11 +80,13 @@ import org.mariotaku.twidere.loader.support.TileImageLoader.Result;
|
||||
import org.mariotaku.twidere.model.ParcelableMedia;
|
||||
import org.mariotaku.twidere.model.ParcelableMedia.VideoInfo.Variant;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.task.ProgressSaveFileTask;
|
||||
import org.mariotaku.twidere.task.SaveFileTask;
|
||||
import org.mariotaku.twidere.task.SaveImageToGalleryTask;
|
||||
import org.mariotaku.twidere.util.AsyncTaskUtils;
|
||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
|
||||
import org.mariotaku.twidere.util.MenuUtils;
|
||||
import org.mariotaku.twidere.util.PermissionUtils;
|
||||
import org.mariotaku.twidere.util.SaveFileTask;
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.VideoLoader.VideoLoadingListener;
|
||||
@ -258,6 +265,8 @@ public final class MediaViewerActivity extends BaseAppCompatActivity implements
|
||||
public static class BaseImagePageFragment extends AbsMediaPageFragment
|
||||
implements DownloadListener, LoaderCallbacks<Result>, OnClickListener {
|
||||
|
||||
private static final int REQUEST_SHARE_IMAGE = 201;
|
||||
|
||||
private SubsamplingScaleImageView mImageView;
|
||||
private ProgressWheel mProgressBar;
|
||||
private boolean mLoaderInitialized;
|
||||
@ -265,6 +274,7 @@ public final class MediaViewerActivity extends BaseAppCompatActivity implements
|
||||
private SaveFileTask mSaveFileTask;
|
||||
|
||||
private File mImageFile;
|
||||
private File mShareImageFile;
|
||||
|
||||
@Override
|
||||
public void onBaseViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
@ -394,7 +404,7 @@ public final class MediaViewerActivity extends BaseAppCompatActivity implements
|
||||
final File file = mImageFile;
|
||||
final boolean hasImage = file != null && file.exists();
|
||||
if (!hasImage) return;
|
||||
mSaveFileTask = SaveFileTask.saveImage(getActivity(), file);
|
||||
mSaveFileTask = SaveImageToGalleryTask.create(getActivity(), file);
|
||||
AsyncTaskUtils.executeTask(mSaveFileTask);
|
||||
}
|
||||
|
||||
@ -402,44 +412,10 @@ public final class MediaViewerActivity extends BaseAppCompatActivity implements
|
||||
public void onPrepareOptionsMenu(Menu menu) {
|
||||
super.onPrepareOptionsMenu(menu);
|
||||
final boolean isLoading = getLoaderManager().hasRunningLoaders();
|
||||
final TaskRunnable<File, Pair<Boolean, Intent>, Pair<Fragment, Menu>> checkState
|
||||
= new TaskRunnable<File, Pair<Boolean, Intent>, Pair<Fragment, Menu>>() {
|
||||
@Override
|
||||
public Pair<Boolean, Intent> doLongOperation(File file) throws InterruptedException {
|
||||
final boolean hasImage = file != null && file.exists();
|
||||
if (!hasImage) {
|
||||
return Pair.create(false, null);
|
||||
}
|
||||
final Intent intent = new Intent(Intent.ACTION_SEND);
|
||||
final Uri fileUri = Uri.fromFile(file);
|
||||
final String imageMimeType = Utils.getImageMimeType(file);
|
||||
intent.setDataAndType(fileUri, imageMimeType);
|
||||
intent.putExtra(Intent.EXTRA_STREAM, fileUri);
|
||||
final MediaViewerActivity activity = (MediaViewerActivity) getActivity();
|
||||
if (activity.hasStatus()) {
|
||||
final ParcelableStatus status = activity.getStatus();
|
||||
intent.putExtra(Intent.EXTRA_TEXT, Utils.getStatusShareText(activity, status));
|
||||
intent.putExtra(Intent.EXTRA_SUBJECT, Utils.getStatusShareSubject(activity, status));
|
||||
}
|
||||
return Pair.create(true, intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void callback(Pair<Fragment, Menu> callback, Pair<Boolean, Intent> result) {
|
||||
if (callback.first.isDetached() || callback.first.getActivity() == null) return;
|
||||
final Menu menu = callback.second;
|
||||
final boolean hasImage = result.first;
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.refresh, !hasImage && !isLoading);
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.share, hasImage && !isLoading);
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.save, hasImage && !isLoading);
|
||||
if (!hasImage) return;
|
||||
final MenuItem shareItem = menu.findItem(R.id.share);
|
||||
shareItem.setIntent(Intent.createChooser(result.second, callback.first.getString(R.string.share)));
|
||||
}
|
||||
};
|
||||
checkState.setParams(mImageFile);
|
||||
checkState.setResultHandler(Pair.<Fragment, Menu>create(this, menu));
|
||||
AsyncManager.runBackgroundTask(checkState);
|
||||
final boolean hasImage = mImageFile != null;
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.refresh, !hasImage && !isLoading);
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.share, hasImage && !isLoading);
|
||||
MenuUtils.setMenuItemAvailability(menu, R.id.save, hasImage && !isLoading);
|
||||
}
|
||||
|
||||
|
||||
@ -464,6 +440,65 @@ public final class MediaViewerActivity extends BaseAppCompatActivity implements
|
||||
loadImage();
|
||||
return true;
|
||||
}
|
||||
case R.id.share: {
|
||||
final FragmentActivity activity = getActivity();
|
||||
final File destination = new File(activity.getCacheDir(), "shared_files");
|
||||
final SaveFileTask task = new SaveFileTask(activity, mImageFile, destination,
|
||||
new SaveImageToGalleryTask.ImageMimeTypeCallback()) {
|
||||
private static final String PROGRESS_FRAGMENT_TAG = "progress";
|
||||
|
||||
protected void dismissProgress() {
|
||||
final MediaViewerActivity activity = (MediaViewerActivity) getActivity();
|
||||
if (activity == null) return;
|
||||
activity.executeAfterFragmentResumed(new IExtendedActivity.Action() {
|
||||
@Override
|
||||
public void execute(IExtendedActivity activity) {
|
||||
final FragmentManager fm = ((Activity) activity).getFragmentManager();
|
||||
final DialogFragment fragment = (DialogFragment) fm.findFragmentByTag(PROGRESS_FRAGMENT_TAG);
|
||||
if (fragment != null) {
|
||||
fragment.dismiss();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void showProgress() {
|
||||
final MediaViewerActivity activity = (MediaViewerActivity) getActivity();
|
||||
if (activity == null) return;
|
||||
activity.executeAfterFragmentResumed(new IExtendedActivity.Action() {
|
||||
@Override
|
||||
public void execute(IExtendedActivity activity) {
|
||||
final DialogFragment fragment = new ProgressDialogFragment();
|
||||
fragment.setCancelable(false);
|
||||
fragment.show(((Activity) activity).getFragmentManager(), PROGRESS_FRAGMENT_TAG);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void onFileSaved(File savedFile, String mimeType) {
|
||||
final MediaViewerActivity activity = (MediaViewerActivity) getActivity();
|
||||
if (activity == null) return;
|
||||
|
||||
final Uri fileUri = FileProvider.getUriForFile(activity,
|
||||
AUTHORITY_TWIDERE_FILE, savedFile);
|
||||
|
||||
final Intent intent = new Intent(Intent.ACTION_SEND);
|
||||
intent.setDataAndType(fileUri, mimeType);
|
||||
intent.putExtra(Intent.EXTRA_STREAM, fileUri);
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
if (activity.hasStatus()) {
|
||||
final ParcelableStatus status = activity.getStatus();
|
||||
intent.putExtra(Intent.EXTRA_TEXT, Utils.getStatusShareText(activity, status));
|
||||
intent.putExtra(Intent.EXTRA_SUBJECT, Utils.getStatusShareSubject(activity, status));
|
||||
}
|
||||
startActivityForResult(Intent.createChooser(intent, activity.getString(R.string.share)),
|
||||
REQUEST_SHARE_IMAGE);
|
||||
}
|
||||
|
||||
};
|
||||
task.execute();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
@ -484,7 +519,18 @@ public final class MediaViewerActivity extends BaseAppCompatActivity implements
|
||||
loadImage();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
|
||||
switch (requestCode) {
|
||||
case REQUEST_SHARE_IMAGE: {
|
||||
if (mShareImageFile != null) {
|
||||
mShareImageFile.delete();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
}
|
||||
|
||||
public static final class ImagePageFragment extends BaseImagePageFragment
|
||||
@ -840,7 +886,13 @@ public final class MediaViewerActivity extends BaseAppCompatActivity implements
|
||||
if (extension == null) return;
|
||||
final File pubDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
|
||||
final File saveDir = new File(pubDir, "Twidere");
|
||||
mSaveFileTask = AsyncTaskUtils.executeTask(new SaveFileTask(getActivity(), file, mimeType, saveDir));
|
||||
mSaveFileTask = AsyncTaskUtils.executeTask(new ProgressSaveFileTask(getActivity(), file, saveDir,
|
||||
new SaveFileTask.StringMimeTypeCallback(mimeType)) {
|
||||
@Override
|
||||
protected void onFileSaved(File savedFile, String mimeType) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -938,6 +990,7 @@ public final class MediaViewerActivity extends BaseAppCompatActivity implements
|
||||
final Intent intent = new Intent(Intent.ACTION_SEND);
|
||||
final Uri fileUri = Uri.fromFile(file);
|
||||
intent.setDataAndType(fileUri, linkAndType.second);
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
intent.putExtra(Intent.EXTRA_STREAM, fileUri);
|
||||
final MediaViewerActivity activity = (MediaViewerActivity) getActivity();
|
||||
if (activity.hasStatus()) {
|
||||
|
@ -23,7 +23,7 @@ import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentStatePagerAdapter;
|
||||
import android.support.v4.app.FragmentTrojan;
|
||||
import android.support.v4.app.FragmentAccessor;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
public abstract class SupportFixedFragmentStatePagerAdapter extends FragmentStatePagerAdapter {
|
||||
@ -35,7 +35,7 @@ public abstract class SupportFixedFragmentStatePagerAdapter extends FragmentStat
|
||||
@Override
|
||||
public Object instantiateItem(final ViewGroup container, final int position) {
|
||||
final Fragment f = (Fragment) super.instantiateItem(container, position);
|
||||
final Bundle savedFragmentState = f != null ? FragmentTrojan.getSavedFragmentState(f) : null;
|
||||
final Bundle savedFragmentState = f != null ? FragmentAccessor.getSavedFragmentState(f) : null;
|
||||
if (savedFragmentState != null) {
|
||||
savedFragmentState.setClassLoader(f.getClass().getClassLoader());
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentManagerTrojan;
|
||||
import android.support.v4.app.FragmentManagerAccessor;
|
||||
import android.support.v4.view.LayoutInflaterCompat;
|
||||
import android.support.v4.view.LayoutInflaterFactory;
|
||||
import android.view.LayoutInflater;
|
||||
@ -193,7 +193,7 @@ public class BaseSupportFragment extends Fragment implements IBaseFragment, Cons
|
||||
}
|
||||
final LayoutInflater inflater = activity.getLayoutInflater().cloneInContext(getThemedContext());
|
||||
getChildFragmentManager(); // Init if needed; use raw implementation below.
|
||||
final LayoutInflaterFactory delegate = FragmentManagerTrojan.getLayoutInflaterFactory(getChildFragmentManager());
|
||||
final LayoutInflaterFactory delegate = FragmentManagerAccessor.getLayoutInflaterFactory(getChildFragmentManager());
|
||||
LayoutInflaterCompat.setFactory(inflater, new ThemedLayoutInflaterFactory((IThemedActivity) activity, delegate));
|
||||
return inflater;
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentManagerTrojan;
|
||||
import android.support.v4.app.FragmentManagerAccessor;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||
import android.support.v4.content.AsyncTaskLoader;
|
||||
@ -1167,7 +1167,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
|
||||
}
|
||||
final Fragment cardFragment = TwitterCardUtils.createCardFragment(status);
|
||||
final FragmentManager fm = fragment.getChildFragmentManager();
|
||||
if (cardFragment != null && !FragmentManagerTrojan.isStateSaved(fm)) {
|
||||
if (cardFragment != null && !FragmentManagerAccessor.isStateSaved(fm)) {
|
||||
final FragmentTransaction ft = fm.beginTransaction();
|
||||
ft.replace(R.id.twitter_card, cardFragment);
|
||||
ft.commit();
|
||||
|
@ -24,7 +24,7 @@ import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.content.AsyncTaskLoader;
|
||||
import android.support.v4.content.LoaderTrojan;
|
||||
import android.support.v4.content.LoaderAccessor;
|
||||
|
||||
import org.mariotaku.library.objectcursor.ObjectCursor;
|
||||
|
||||
@ -247,7 +247,7 @@ public class ObjectCursorLoader<T> extends AsyncTaskLoader<List<T>> {
|
||||
writer.println(mObjects);
|
||||
writer.print(prefix);
|
||||
writer.print("mContentChanged=");
|
||||
writer.println(LoaderTrojan.isContentChanged(this));
|
||||
writer.println(LoaderAccessor.isContentChanged(this));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.task;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.DialogFragment;
|
||||
import android.app.FragmentManager;
|
||||
import android.content.Context;
|
||||
|
||||
import org.mariotaku.twidere.activity.iface.IExtendedActivity;
|
||||
import org.mariotaku.twidere.fragment.ProgressDialogFragment;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/12/28.
|
||||
*/
|
||||
public abstract class ProgressSaveFileTask extends SaveFileTask {
|
||||
private static final String PROGRESS_FRAGMENT_TAG = "progress";
|
||||
|
||||
public ProgressSaveFileTask(Context context, File source, File destination, MimeTypeCallback getMimeType) {
|
||||
super(context, source, destination, getMimeType);
|
||||
}
|
||||
|
||||
protected void showProgress() {
|
||||
final Context context = getContext();
|
||||
if (context == null) return;
|
||||
((IExtendedActivity) context).executeAfterFragmentResumed(new IExtendedActivity.Action() {
|
||||
@Override
|
||||
public void execute(IExtendedActivity activity) {
|
||||
final DialogFragment fragment = new ProgressDialogFragment();
|
||||
fragment.setCancelable(false);
|
||||
fragment.show(((Activity) activity).getFragmentManager(), PROGRESS_FRAGMENT_TAG);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void dismissProgress() {
|
||||
final Context context = getContext();
|
||||
if (context == null) return;
|
||||
((IExtendedActivity) context).executeAfterFragmentResumed(new IExtendedActivity.Action() {
|
||||
@Override
|
||||
public void execute(IExtendedActivity activity) {
|
||||
final FragmentManager fm = ((Activity) activity).getFragmentManager();
|
||||
final DialogFragment fragment = (DialogFragment) fm.findFragmentByTag(PROGRESS_FRAGMENT_TAG);
|
||||
if (fragment != null) {
|
||||
fragment.dismiss();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.task;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
import android.webkit.MimeTypeMap;
|
||||
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import okio.BufferedSink;
|
||||
import okio.Okio;
|
||||
import okio.Source;
|
||||
|
||||
import static android.text.TextUtils.isEmpty;
|
||||
|
||||
public abstract class SaveFileTask extends AsyncTask<Object, Object, SaveFileTask.SaveFileResult> implements Constants {
|
||||
|
||||
private final WeakReference<Context> contextRef;
|
||||
|
||||
@NonNull
|
||||
private final File source, destination;
|
||||
@NonNull
|
||||
private final MimeTypeCallback getMimeType;
|
||||
|
||||
public SaveFileTask(@NonNull final Context context, @NonNull final File source,
|
||||
@NonNull final File destination, @NonNull final MimeTypeCallback getMimeType) {
|
||||
this.contextRef = new WeakReference<>(context);
|
||||
this.source = source;
|
||||
this.getMimeType = getMimeType;
|
||||
this.destination = destination;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static SaveFileResult saveFile(@NonNull final Context context, @NonNull final File source,
|
||||
@NonNull final MimeTypeCallback mimeTypeCallback,
|
||||
@NonNull final File destinationDir) {
|
||||
Source ioSrc = null;
|
||||
BufferedSink sink = null;
|
||||
try {
|
||||
final String name = source.getName();
|
||||
if (isEmpty(name)) return null;
|
||||
final String mimeType = mimeTypeCallback.getMimeType(source);
|
||||
final String extension = mimeTypeCallback.getExtension(mimeType);
|
||||
if (extension == null) return null;
|
||||
final String nameToSave = getFileNameWithExtension(name, extension);
|
||||
if (!destinationDir.isDirectory() && !destinationDir.mkdirs()) return null;
|
||||
final File saveFile = new File(destinationDir, nameToSave);
|
||||
ioSrc = Okio.source(source);
|
||||
sink = Okio.buffer(Okio.sink(saveFile));
|
||||
sink.writeAll(ioSrc);
|
||||
sink.flush();
|
||||
return new SaveFileResult(saveFile, mimeType);
|
||||
} catch (final IOException e) {
|
||||
Log.w(LOGTAG, "Failed to save file", e);
|
||||
return null;
|
||||
} finally {
|
||||
Utils.closeSilently(sink);
|
||||
Utils.closeSilently(ioSrc);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final SaveFileResult doInBackground(final Object... args) {
|
||||
final Context context = contextRef.get();
|
||||
if (context == null) return null;
|
||||
return saveFile(context, source, getMimeType, destination);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCancelled() {
|
||||
dismissProgress();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void onPreExecute() {
|
||||
showProgress();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void onPostExecute(@Nullable final SaveFileResult result) {
|
||||
dismissProgress();
|
||||
if (result != null) {
|
||||
onFileSaved(result.savedFile, result.mimeType);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void onFileSaved(File savedFile, String mimeType);
|
||||
|
||||
protected abstract void showProgress();
|
||||
|
||||
protected abstract void dismissProgress();
|
||||
|
||||
|
||||
protected final Context getContext() {
|
||||
return contextRef.get();
|
||||
}
|
||||
|
||||
private static String getFileNameWithExtension(String name, String extension) {
|
||||
int lastDotIdx = name.lastIndexOf('.');
|
||||
if (lastDotIdx < 0) return name + "." + extension;
|
||||
return name.substring(0, lastDotIdx) + "." + extension;
|
||||
}
|
||||
|
||||
public interface MimeTypeCallback {
|
||||
String getMimeType(File source);
|
||||
|
||||
String getExtension(String mimeType);
|
||||
}
|
||||
|
||||
public static final class SaveFileResult {
|
||||
File savedFile;
|
||||
String mimeType;
|
||||
|
||||
public SaveFileResult(File savedFile, String mimeType) {
|
||||
this.savedFile = savedFile;
|
||||
this.mimeType = mimeType;
|
||||
}
|
||||
|
||||
public File getSavedFile() {
|
||||
return savedFile;
|
||||
}
|
||||
|
||||
public String getMimeType() {
|
||||
return mimeType;
|
||||
}
|
||||
}
|
||||
|
||||
public static class StringMimeTypeCallback implements MimeTypeCallback {
|
||||
private final String mimeType;
|
||||
|
||||
public StringMimeTypeCallback(String mimeType) {
|
||||
this.mimeType = mimeType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMimeType(File source) {
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExtension(String mimeType) {
|
||||
return MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.task;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.os.Environment;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/12/28.
|
||||
*/
|
||||
public class SaveImageToGalleryTask extends ProgressSaveFileTask {
|
||||
|
||||
public SaveImageToGalleryTask(@NonNull Activity activity, @NonNull File source, @NonNull File destination) {
|
||||
super(activity, source, destination, new ImageMimeTypeCallback());
|
||||
}
|
||||
|
||||
public static SaveFileTask create(final Activity activity, final File source) {
|
||||
final File pubDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
|
||||
final File saveDir = new File(pubDir, "Twidere");
|
||||
return new SaveImageToGalleryTask(activity, source, saveDir);
|
||||
}
|
||||
|
||||
protected void onFileSaved(File savedFile, String mimeType) {
|
||||
final Context context = getContext();
|
||||
if (context == null) return;
|
||||
if (savedFile != null && savedFile.exists()) {
|
||||
MediaScannerConnection.scanFile(context, new String[]{savedFile.getPath()},
|
||||
new String[]{mimeType}, null);
|
||||
Toast.makeText(context, R.string.saved_to_gallery, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(context, R.string.error_occurred, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
public static final class ImageMimeTypeCallback implements MimeTypeCallback {
|
||||
@Override
|
||||
public String getMimeType(File source) {
|
||||
return Utils.getImageMimeType(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExtension(String mimeType) {
|
||||
return MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,151 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.util;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.DialogFragment;
|
||||
import android.app.FragmentManager;
|
||||
import android.content.Context;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Environment;
|
||||
import android.system.ErrnoException;
|
||||
import android.system.OsConstants;
|
||||
import android.util.Log;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.fragment.ProgressDialogFragment;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import okio.BufferedSink;
|
||||
import okio.Okio;
|
||||
import okio.Source;
|
||||
|
||||
import static android.text.TextUtils.isEmpty;
|
||||
|
||||
public class SaveFileTask extends AsyncTask<Object, Object, File> implements Constants {
|
||||
|
||||
private static final String PROGRESS_FRAGMENT_TAG = "progress";
|
||||
|
||||
private final File source, destination;
|
||||
private final Activity activity;
|
||||
private final String mimeType;
|
||||
|
||||
public SaveFileTask(final Activity activity, final File source, final String mimeType, final File destination) {
|
||||
this.activity = activity;
|
||||
this.source = source;
|
||||
this.mimeType = mimeType;
|
||||
this.destination = destination;
|
||||
}
|
||||
|
||||
public static SaveFileTask saveImage(final Activity activity, final File source) {
|
||||
final String mimeType = Utils.getImageMimeType(source);
|
||||
final MimeTypeMap map = MimeTypeMap.getSingleton();
|
||||
final String extension = map.getExtensionFromMimeType(mimeType);
|
||||
if (extension == null) return null;
|
||||
final File pubDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
|
||||
final File saveDir = new File(pubDir, "Twidere");
|
||||
return new SaveFileTask(activity, source, mimeType, saveDir);
|
||||
}
|
||||
|
||||
public static File saveFile(final Context context, final File source, final String mimeType, final File destination) {
|
||||
if (context == null && source == null) return null;
|
||||
Source ioSrc = null;
|
||||
BufferedSink sink = null;
|
||||
try {
|
||||
final String name = source.getName();
|
||||
if (isEmpty(name)) return null;
|
||||
final MimeTypeMap map = MimeTypeMap.getSingleton();
|
||||
final String extension = map.getExtensionFromMimeType(mimeType);
|
||||
if (extension == null) return null;
|
||||
final String nameToSave = getFileNameWithExtension(name, extension);
|
||||
if (!destination.isDirectory() && !destination.mkdirs()) return null;
|
||||
final File saveFile = new File(destination, nameToSave);
|
||||
ioSrc = Okio.source(source);
|
||||
sink = Okio.buffer(Okio.sink(saveFile));
|
||||
sink.writeAll(ioSrc);
|
||||
sink.flush();
|
||||
if (mimeType != null) {
|
||||
MediaScannerConnection.scanFile(context, new String[]{saveFile.getPath()},
|
||||
new String[]{mimeType}, null);
|
||||
}
|
||||
return saveFile;
|
||||
} catch (final IOException e) {
|
||||
final int errno = Utils.getErrorNo(e.getCause());
|
||||
Log.w(LOGTAG, "Failed to save file", e);
|
||||
return null;
|
||||
} finally {
|
||||
Utils.closeSilently(sink);
|
||||
Utils.closeSilently(ioSrc);
|
||||
}
|
||||
}
|
||||
|
||||
private static String getFileNameWithExtension(String name, String extension) {
|
||||
int lastDotIdx = name.lastIndexOf('.');
|
||||
if (lastDotIdx < 0) return name + "." + extension;
|
||||
return name.substring(0, lastDotIdx) + "." + extension;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected File doInBackground(final Object... args) {
|
||||
if (source == null) return null;
|
||||
return saveFile(activity, source, mimeType, destination);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCancelled() {
|
||||
final FragmentManager fm = activity.getFragmentManager();
|
||||
final DialogFragment fragment = (DialogFragment) fm.findFragmentByTag(PROGRESS_FRAGMENT_TAG);
|
||||
if (fragment != null && fragment.isVisible()) {
|
||||
fragment.dismiss();
|
||||
}
|
||||
super.onCancelled();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final File result) {
|
||||
final FragmentManager fm = activity.getFragmentManager();
|
||||
final DialogFragment fragment = (DialogFragment) fm.findFragmentByTag(PROGRESS_FRAGMENT_TAG);
|
||||
if (fragment != null) {
|
||||
fragment.dismiss();
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
if (result != null && result.exists()) {
|
||||
Toast.makeText(activity, R.string.saved_to_gallery, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(activity, R.string.error_occurred, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
final DialogFragment fragment = new ProgressDialogFragment();
|
||||
fragment.setCancelable(false);
|
||||
fragment.show(activity.getFragmentManager(), PROGRESS_FRAGMENT_TAG);
|
||||
super.onPreExecute();
|
||||
}
|
||||
|
||||
}
|
@ -34,7 +34,7 @@ import android.support.v4.view.ViewCompat;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.app.AppCompatDelegate;
|
||||
import android.support.v7.app.AppCompatDelegateTrojan;
|
||||
import android.support.v7.app.AppCompatDelegateAccessor;
|
||||
import android.support.v7.view.ContextThemeWrapper;
|
||||
import android.support.v7.widget.TwidereToolbar;
|
||||
import android.util.AttributeSet;
|
||||
@ -257,13 +257,13 @@ public class ThemedLayoutInflaterFactory implements LayoutInflaterFactory {
|
||||
Context actionBarContext = null;
|
||||
if (activity instanceof AppCompatActivity) {
|
||||
final AppCompatDelegate delegate = ((AppCompatActivity) activity).getDelegate();
|
||||
final ActionBar actionBar = AppCompatDelegateTrojan.peekActionBar(delegate);
|
||||
final ActionBar actionBar = AppCompatDelegateAccessor.peekActionBar(delegate);
|
||||
if (actionBar != null) {
|
||||
actionBarContext = actionBar.getThemedContext();
|
||||
}
|
||||
} else if (activity instanceof AppCompatPreferenceActivity) {
|
||||
final AppCompatDelegate delegate = ((AppCompatPreferenceActivity) activity).getDelegate();
|
||||
final ActionBar actionBar = AppCompatDelegateTrojan.peekActionBar(delegate);
|
||||
final ActionBar actionBar = AppCompatDelegateAccessor.peekActionBar(delegate);
|
||||
if (actionBar != null) {
|
||||
actionBarContext = actionBar.getThemedContext();
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
<resources>
|
||||
|
||||
<bool name="shadow_slidable">false</bool>
|
||||
<bool name="is_large_screen">true</bool>
|
||||
<bool name="relative_behind_width">false</bool>
|
||||
|
||||
</resources>
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
<bool name="default_display_tab_label">false</bool>
|
||||
<bool name="home_display_icon">false</bool>
|
||||
<bool name="is_large_screen">false</bool>
|
||||
<bool name="default_shadow_slidable">true</bool>
|
||||
<bool name="shadow_slidable">true</bool>
|
||||
<bool name="has_font_family">false</bool>
|
||||
|
25
twidere/src/main/res/xml/file_paths.xml
Normal file
25
twidere/src/main/res/xml/file_paths.xml
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Twidere - Twitter client for Android
|
||||
~
|
||||
~ Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
~
|
||||
~ This program is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU General Public License as published by
|
||||
~ the Free Software Foundation, either version 3 of the License, or
|
||||
~ (at your option) any later version.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
~ GNU General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License
|
||||
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<paths>
|
||||
<cache-path
|
||||
name="shares"
|
||||
path="shared_files/"/>
|
||||
</paths>
|
Loading…
x
Reference in New Issue
Block a user