diff --git a/.gitignore b/.gitignore index c319d73b3..d230d5a47 100644 --- a/.gitignore +++ b/.gitignore @@ -62,3 +62,7 @@ seadroid-key /build .transifexrc +/app/release +/app/seeds.txt +/app/unused.txt +/app/proguardMapping.txt diff --git a/app/build.gradle b/app/build.gradle index d5352b311..f24121309 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,8 +7,8 @@ android { applicationId 'com.seafile.seadroid2' minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 129 - versionName "2.3.2" + versionCode 134 + versionName "2.3.3" multiDexEnabled true resValue "string", "authorities", applicationId + '.cameraupload.provider' resValue "string", "account_type", "com.seafile.seadroid2.account.api2" @@ -29,6 +29,12 @@ android { targetCompatibility JavaVersion.VERSION_1_8 } + sourceSets { + main { + jniLibs.srcDirs = ['libs'] + } + } + signingConfigs { debug { // def props = new Properties() @@ -108,7 +114,9 @@ android { } dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') - + implementation files('libs/library-markdown.aar') + implementation files('libs/library-emoji.aar') + //DO NOT upgrade this lib, unless the APP upgrade to AndroidX implementation 'com.blankj:utilcode:1.30.0' implementation 'com.jcodecraeer:xrecyclerview:1.6.0' @@ -116,7 +124,10 @@ android { implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}" implementation "com.android.support:design:${rootProject.ext.supportLibVersion}" implementation 'com.android.support.constraint:constraint-layout:1.1.3' - implementation 'com.github.JakeWharton:ViewPagerIndicator:2.4.1' + +// implementation 'com.github.JakeWharton:ViewPagerIndicator:2.4.1' + implementation 'me.relex:circleindicator:1.3.2' + implementation 'com.github.kevinsawicki:http-request:6.0' implementation 'commons-io:commons-io:2.11.0' implementation 'com.google.guava:guava:18.0' @@ -138,11 +149,25 @@ android { implementation 'com.yydcdut:markdown-processor:0.1.3' implementation 'ren.qinc.edit:lib:0.0.5'//editor undo redo - implementation 'com.github.tiagohm.MarkdownView:library:0.19.0' implementation 'org.greenrobot:eventbus:3.3.1' //glide implementation 'com.github.bumptech.glide:glide:4.9.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0' + + + // implementation 'com.github.tiagohm.MarkdownView:library:0.19.0' + //Markdown Flexmark + implementation 'com.vladsch.flexmark:flexmark:0.28.32' + implementation 'com.vladsch.flexmark:flexmark-ext-tables:0.28.32' + implementation 'com.vladsch.flexmark:flexmark-ext-gfm-strikethrough:0.28.32' + implementation 'com.vladsch.flexmark:flexmark-ext-gfm-tasklist:0.28.32' + implementation 'com.vladsch.flexmark:flexmark-ext-autolink:0.28.32' + implementation 'com.vladsch.flexmark:flexmark-ext-abbreviation:0.28.32' + implementation 'com.vladsch.flexmark:flexmark-ext-superscript:0.28.32' + implementation 'com.vladsch.flexmark:flexmark-ext-footnotes:0.28.32' + implementation 'com.vladsch.flexmark:flexmark-ext-attributes:0.28.32' + //Logger + implementation 'com.orhanobut:logger:1.15' } } diff --git a/app/libs/library-emoji.aar b/app/libs/library-emoji.aar new file mode 100644 index 000000000..05795bb59 Binary files /dev/null and b/app/libs/library-emoji.aar differ diff --git a/app/libs/library-markdown.aar b/app/libs/library-markdown.aar new file mode 100644 index 000000000..cd1e4fa34 Binary files /dev/null and b/app/libs/library-markdown.aar differ diff --git a/app/proguard-project.txt b/app/proguard-project.txt index 3553e9fde..2f37958d4 100644 --- a/app/proguard-project.txt +++ b/app/proguard-project.txt @@ -32,10 +32,20 @@ -dontusemixedcaseclassnames -dontskipnonpubliclibraryclasses --verbose -dontoptimize -dontpreverify +# +-verbose +-printmapping proguardMapping.txt +#输出apk包内所有的class的内部结构 +-dump dump.txt +#未混淆的类和成员 +-printseeds seeds.txt +#列出从apk中删除的代码 +-printusage unused.txt + + -keepattributes *Annotation* -keep public class com.google.vending.licensing.ILicensingService -keep public class com.android.vending.licensing.ILicensingService @@ -87,8 +97,7 @@ -keepattributes SourceFile,LineNumberTable,*Annotation* --printmapping map.txt --printseeds seed.txt + -keepnames class * diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 685af38be..85a42d4fb 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,83 +3,70 @@ xmlns:tools="http://schemas.android.com/tools" package="com.seafile.seadroid2"> - + - + - - + + - + - - + + - + - + - + + android:theme="@style/AppTheme"> + android:value="AppGlideModule" /> - - + - - + - - + - - + - - + - + @@ -88,34 +75,29 @@ + android:screenOrientation="portrait" /> - - + - - + - - + - + @@ -128,88 +110,72 @@ - + - - + - + - - + - - + - + - - - - + + - + - - + - + android:theme="@style/Theme.Fullscreen" /> - + android:theme="@style/AppTheme.Editor" /> + android:permission="android.permission.MANAGE_DOCUMENTS"> - - - + + + + + android:label="@string/sync_provider_camera_upload" + android:syncable="true" /> + android:resource="@xml/file_paths" /> - + - + - + - + + android:permission="android.permission.BIND_JOB_SERVICE" /> - + diff --git a/app/src/main/java/com/seafile/seadroid2/SeafConnection.java b/app/src/main/java/com/seafile/seadroid2/SeafConnection.java index 0e0d96557..3ddeed407 100644 --- a/app/src/main/java/com/seafile/seadroid2/SeafConnection.java +++ b/app/src/main/java/com/seafile/seadroid2/SeafConnection.java @@ -1525,6 +1525,9 @@ private void checkRequestResponseStatus(HttpRequest req, int expectedStatusCode) String result = new String(req.bytes(), "UTF-8"); if (result != null && Utils.parseJsonObject(result) != null) { JSONObject json = Utils.parseJsonObject(result); + if (json.has("detail")){ + throw new SeafException(req.code(), json.optString("detail")); + } throw new SeafException(req.code(), json.optString("error_msg")); } else { throw new SeafException(req.code(), req.message()); diff --git a/app/src/main/java/com/seafile/seadroid2/cameraupload/CameraSyncAdapter.java b/app/src/main/java/com/seafile/seadroid2/cameraupload/CameraSyncAdapter.java index a517e746c..c970af6fb 100644 --- a/app/src/main/java/com/seafile/seadroid2/cameraupload/CameraSyncAdapter.java +++ b/app/src/main/java/com/seafile/seadroid2/cameraupload/CameraSyncAdapter.java @@ -1,5 +1,7 @@ package com.seafile.seadroid2.cameraupload; +import static android.app.PendingIntent.FLAG_IMMUTABLE; + import android.app.NotificationManager; import android.app.PendingIntent; import android.content.AbstractThreadedSyncAdapter; @@ -131,15 +133,6 @@ private synchronized void startTransferService() { getContext().bindService(bIntent, mConnection, Context.BIND_AUTO_CREATE); } - @Override - public void onSyncCanceled() { - super.onSyncCanceled(); - // Log.d(DEBUG_TAG, "onPerformSync will be cancelled "); - synchronized (this) { - cancelled = true; - } - } - private boolean isCancelled() { synchronized (this) { return cancelled; @@ -196,8 +189,8 @@ private void createDirectories(DataManager dataManager) throws SeafException { * Create a directory, rename a file away if necessary, * * @param dataManager - * @param parent parent dir - * @param dir directory to create + * @param parent parent dir + * @param dir directory to create * @throws SeafException */ private void forceCreateDirectory(DataManager dataManager, String parent, String dir) throws SeafException { @@ -205,7 +198,7 @@ private void forceCreateDirectory(DataManager dataManager, String parent, String List dirs = dataManager.getDirentsFromServer(targetRepoId, parent); boolean found = false; for (SeafDirent dirent : dirs) { - if (dirent.name.equals(dir) && dirent.isDir()) { + if (dirent.name.equals(dir) && dirent.isDir()) { found = true; } else if (dirent.name.equals(dir) && !dirent.isDir()) { // there is already a file. move it away. @@ -220,11 +213,39 @@ private void forceCreateDirectory(DataManager dataManager, String parent, String dataManager.createNewDir(targetRepoId, Utils.pathJoin("/", parent), dir); } + @Override + public void onSecurityException(android.accounts.Account account, Bundle extras, String authority, SyncResult syncResult) { + super.onSecurityException(account, extras, authority, syncResult); + Log.e(DEBUG_TAG, syncResult.toString()); + } + + @Override + public boolean onUnsyncableAccount() { + Log.e(DEBUG_TAG, "onUnsyncableAccount"); + return super.onUnsyncableAccount(); + } + + @Override + public void onSyncCanceled(Thread thread) { + super.onSyncCanceled(thread); + Log.e(DEBUG_TAG, "onSyncCanceled ->" + thread.getName()); + } + + @Override + public void onSyncCanceled() { + super.onSyncCanceled(); + Log.e(DEBUG_TAG, "onSyncCanceled"); + synchronized (this) { + cancelled = true; + } + } + @Override public void onPerformSync(android.accounts.Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) { + Log.e(DEBUG_TAG, "onPerformSync!!!!!!!!!!"); synchronized (this) { cancelled = false; @@ -239,7 +260,7 @@ public void onPerformSync(android.accounts.Account account, Log.d(DEBUG_TAG, "Media buckets available on this system: ");*/ // for (GalleryBucketUtils.Bucket bucket: GalleryBucketUtils.getMediaBuckets(getContext())) { - // Log.d(DEBUG_TAG, "Bucket id="+bucket.id+" name="+bucket.name); + // Log.d(DEBUG_TAG, "Bucket id="+bucket.id+" name="+bucket.name); // } // resync all media @@ -265,7 +286,7 @@ public void onPerformSync(android.accounts.Account account, * account signs out. */ if (!seafileAccount.hasValidToken()) { - // Log.d(DEBUG_TAG, "This account has no auth token. Disable camera upload."); + Log.d(DEBUG_TAG, "This account has no auth token. Disable camera upload."); syncResult.stats.numAuthExceptions++; // we're logged out on this account. disable camera upload. @@ -407,7 +428,7 @@ private void uploadImages(SyncResult syncResult, DataManager dataManager) throws try { if (cursor == null) { Log.e(DEBUG_TAG, "ContentResolver query failed!"); - Utils.utilsLogInfo(true,"===ContentResolver query failed!"); + Utils.utilsLogInfo(true, "===ContentResolver query failed!"); return; } // Log.d(DEBUG_TAG, "i see " + cursor.getCount() + " new images."); @@ -428,7 +449,7 @@ private void uploadImages(SyncResult syncResult, DataManager dataManager) throws } private void uploadVideos(SyncResult syncResult, DataManager dataManager) throws SeafException, InterruptedException { - Utils.utilsLogInfo(true,"Starting to upload videos..."); + Utils.utilsLogInfo(true, "Starting to upload videos..."); // Log.d(DEBUG_TAG, "Starting to upload videos..."); if (isCancelled()) @@ -466,11 +487,11 @@ private void uploadVideos(SyncResult syncResult, DataManager dataManager) throws try { if (cursor == null) { Log.e(DEBUG_TAG, "ContentResolver query failed!"); - Utils.utilsLogInfo(true,"====ContentResolver query failed!"); + Utils.utilsLogInfo(true, "====ContentResolver query failed!"); return; } // Log.d(DEBUG_TAG, "i see " + cursor.getCount() + " new videos."); - Utils.utilsLogInfo(true,"=====i see " + cursor.getCount() + " videos."); + Utils.utilsLogInfo(true, "=====i see " + cursor.getCount() + " videos."); if (cursor.getCount() > 0) { // create directories for media buckets createDirectories(dataManager); @@ -561,21 +582,22 @@ private void iterateCursor(SyncResult syncResult, DataManager dataManager, Curso uploadFile(dataManager, file, bucketName); } - Utils.utilsLogInfo(true,"=======waitForUploads==="); + Utils.utilsLogInfo(true, "=======waitForUploads==="); waitForUploads(); checkUploadResult(syncResult); } private void waitForUploads() throws InterruptedException { // Log.d(DEBUG_TAG, "wait for transfer service to finish our tasks"); - WAITLOOP: while (!isCancelled()) { + WAITLOOP: + while (!isCancelled()) { Thread.sleep(100); // wait - for (int id: tasksInProgress) { + for (int id : tasksInProgress) { UploadTaskInfo info = txService.getUploadTaskInfo(id); if (info.state == TaskState.INIT || info.state == TaskState.TRANSFERRING) { // there is still at least one task pending - continue WAITLOOP; + continue WAITLOOP; } } break; @@ -589,7 +611,7 @@ private void waitForUploads() throws InterruptedException { * @throws SeafException */ private void checkUploadResult(SyncResult syncResult) throws SeafException { - for (int id: tasksInProgress) { + for (int id : tasksInProgress) { UploadTaskInfo info = txService.getUploadTaskInfo(id); if (info.err != null) { throw info.err; @@ -615,11 +637,11 @@ private void checkUploadResult(SyncResult syncResult) throws SeafException { private void uploadFile(DataManager dataManager, File file, String bucketName) throws SeafException { String serverPath = Utils.pathJoin(BASE_DIR, bucketName); - Utils.utilsLogInfo(true,"=======uploadFile==="); + Utils.utilsLogInfo(true, "=======uploadFile==="); List list = dataManager.getCachedDirents(targetRepoId, serverPath); if (list == null) { Log.e(DEBUG_TAG, "Seadroid dirent cache is empty in uploadFile. Should not happen, aborting."); - Utils.utilsLogInfo(true,"=======Seadroid dirent cache is empty in uploadFile. Should not happen, aborting."); + Utils.utilsLogInfo(true, "=======Seadroid dirent cache is empty in uploadFile. Should not happen, aborting."); // the dirents were supposed to be refreshed in createDirectories() // something changed, abort. throw SeafException.unknownException; @@ -638,14 +660,14 @@ private void uploadFile(DataManager dataManager, File file, String bucketName) t for (SeafDirent dirent : list) { if (pattern.matcher(dirent.name).matches() && dirent.size == file.length()) { // Log.d(DEBUG_TAG, "File " + file.getName() + " in bucket " + bucketName + " already exists on the server. Skipping."); - Utils.utilsLogInfo(true,"====File " + file.getName() + " in bucket " + bucketName + " already exists on the server. Skipping."); + Utils.utilsLogInfo(true, "====File " + file.getName() + " in bucket " + bucketName + " already exists on the server. Skipping."); dbHelper.markAsUploaded(file); return; } } // Log.d(DEBUG_TAG, "uploading file " + file.getName() + " to " + serverPath); - Utils.utilsLogInfo(true,"====uploading file " + file.getName() + " to " + serverPath); + Utils.utilsLogInfo(true, "====uploading file " + file.getName() + " to " + serverPath); int taskID = txService.addCameraUploadTask(dataManager.getAccount(), targetRepoId, targetRepoName, serverPath, file.getAbsolutePath(), false, false); tasksInProgress.add(taskID); @@ -702,13 +724,10 @@ private void showNotificationRepoError() { resultIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent dPendingIntent = PendingIntent.getActivity(getContext(), - (int) System.currentTimeMillis(), - resultIntent, - 0); + (int) System.currentTimeMillis(), resultIntent, FLAG_IMMUTABLE); mBuilder.setContentIntent(dPendingIntent); - NotificationManager mNotificationManager = - (NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE); + NotificationManager mNotificationManager = (NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE); mNotificationManager.notify(0, mBuilder.build()); } diff --git a/app/src/main/java/com/seafile/seadroid2/cameraupload/CameraSyncService.java b/app/src/main/java/com/seafile/seadroid2/cameraupload/CameraSyncService.java index 797d8ff59..3750c27c1 100644 --- a/app/src/main/java/com/seafile/seadroid2/cameraupload/CameraSyncService.java +++ b/app/src/main/java/com/seafile/seadroid2/cameraupload/CameraSyncService.java @@ -3,10 +3,16 @@ import android.app.Service; import android.content.Intent; import android.os.IBinder; +import android.util.Log; + +import com.blankj.utilcode.util.TimeUtils; + +import java.util.Timer; +import java.util.TimerTask; /** * Camera Sync Service. - * + *

* This service is started and stopped by the Android System. */ public class CameraSyncService extends Service { @@ -16,6 +22,7 @@ public class CameraSyncService extends Service { @Override public void onCreate() { + Log.e(CameraSyncService.class.getName(), "CameraSyncService onCreate"); synchronized (sSyncAdapterLock) { if (sSyncAdapter == null) { sSyncAdapter = new CameraSyncAdapter(getApplicationContext()); @@ -23,9 +30,15 @@ public void onCreate() { } } + @Override + public void onDestroy() { + Log.e(CameraSyncService.class.getName(), "CameraSyncService onDestroy"); + super.onDestroy(); + } + @Override public IBinder onBind(Intent intent) { + Log.e(CameraSyncService.class.getName(), "CameraSyncService onBind"); return sSyncAdapter.getSyncAdapterBinder(); } - } diff --git a/app/src/main/java/com/seafile/seadroid2/cameraupload/CameraUploadConfigActivity.java b/app/src/main/java/com/seafile/seadroid2/cameraupload/CameraUploadConfigActivity.java index e077b6e74..42343f13d 100644 --- a/app/src/main/java/com/seafile/seadroid2/cameraupload/CameraUploadConfigActivity.java +++ b/app/src/main/java/com/seafile/seadroid2/cameraupload/CameraUploadConfigActivity.java @@ -17,10 +17,11 @@ import com.seafile.seadroid2.ui.activity.SeafilePathChooserActivity; import com.seafile.seadroid2.ui.fragment.SettingsFragment; import com.seafile.seadroid2.util.SystemSwitchUtils; -import com.viewpagerindicator.LinePageIndicator; import java.util.List; +import me.relex.circleindicator.CircleIndicator; + /** * Camera upload configuration helper @@ -29,7 +30,8 @@ public class CameraUploadConfigActivity extends BaseActivity { public String DEBUG_TAG = "CameraUploadConfigActivity"; private ViewPager mViewPager; - private LinePageIndicator mIndicator; + + private CircleIndicator magicIndicator; private BucketsFragment mBucketsFragment; private CloudLibraryFragment mCloudLibFragment; private WhatToUploadFragment whatToUploadFragment; @@ -63,15 +65,15 @@ public void onCreate(Bundle savedInstanceState) { FragmentManager fm = getSupportFragmentManager(); mViewPager.setAdapter(new CameraUploadConfigAdapter(fm)); mViewPager.setOffscreenPageLimit(6); + mViewPager.addOnPageChangeListener(pageChangeListener); - mIndicator = (LinePageIndicator) findViewById(R.id.cuc_indicator); - mIndicator.setViewPager(mViewPager); - mIndicator.setOnPageChangeListener(pageChangeListener); + magicIndicator = findViewById(R.id.cuc_indicator); + magicIndicator.setViewPager(mViewPager); sm = SettingsManager.instance(); if (isChooseLibPage || isChooseDirPage) { - mIndicator.setVisibility(View.GONE); + magicIndicator.setVisibility(View.GONE); } } @@ -132,7 +134,7 @@ public void onBackPressed() { } else { // navigate to previous page when press back button mCurrentPosition -= 1; - mIndicator.setCurrentItem(mCurrentPosition); + mViewPager.setCurrentItem(mCurrentPosition); } } diff --git a/app/src/main/java/com/seafile/seadroid2/cameraupload/CameraUploadManager.java b/app/src/main/java/com/seafile/seadroid2/cameraupload/CameraUploadManager.java index 1d7da46f5..52c82ccf9 100644 --- a/app/src/main/java/com/seafile/seadroid2/cameraupload/CameraUploadManager.java +++ b/app/src/main/java/com/seafile/seadroid2/cameraupload/CameraUploadManager.java @@ -3,6 +3,7 @@ import android.content.ContentResolver; import android.content.Context; import android.os.Bundle; +import android.util.Log; import com.seafile.seadroid2.BuildConfig; import com.seafile.seadroid2.account.Account; @@ -67,6 +68,7 @@ public void performSync() { public void performFullSync() { Bundle b = new Bundle(); b.putBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, true); + Log.d(CameraUploadManager.class.getName(),"performFullSync()~"); Account cameraAccount = getCameraAccount(); if (cameraAccount != null) diff --git a/app/src/main/java/com/seafile/seadroid2/cameraupload/MediaObserverService.java b/app/src/main/java/com/seafile/seadroid2/cameraupload/MediaObserverService.java index 9d12ea37c..20fd32270 100644 --- a/app/src/main/java/com/seafile/seadroid2/cameraupload/MediaObserverService.java +++ b/app/src/main/java/com/seafile/seadroid2/cameraupload/MediaObserverService.java @@ -7,6 +7,7 @@ import android.net.Uri; import android.os.IBinder; import android.provider.MediaStore; +import android.util.Log; import com.seafile.seadroid2.SettingsManager; @@ -102,19 +103,19 @@ private void registerContentObservers() { mediaObserver = new MediaObserver(); getApplicationContext().getContentResolver().registerContentObserver( - MediaStore.Images.Media.EXTERNAL_CONTENT_URI, false, mediaObserver); + MediaStore.Images.Media.EXTERNAL_CONTENT_URI, true, mediaObserver); -// getApplicationContext().getContentResolver().registerContentObserver -// (MediaStore.Video.Media.EXTERNAL_CONTENT_URI, false, mediaObserver); + getApplicationContext().getContentResolver().registerContentObserver + (MediaStore.Video.Media.EXTERNAL_CONTENT_URI, true, mediaObserver); - // Log.i(DEBUG_TAG, "Started watchting for new media content."); + Log.i(DEBUG_TAG, "Started watchting for new media content."); } private void unregisterContentObservers() { this.getApplicationContext().getContentResolver() .unregisterContentObserver(mediaObserver); - // Log.i(DEBUG_TAG, "Stopped watchting for new media content."); + Log.i(DEBUG_TAG, "Stopped watchting for new media content."); } private class MediaObserver extends ContentObserver { @@ -131,7 +132,7 @@ public void onChange(boolean selfChange) { public void onChange(boolean selfChange, Uri changeUri) { if (cameraManager.isCameraUploadEnabled()) { - // Log.d(DEBUG_TAG, "Noticed a change in the media provider, scheduling sync."); + Log.d(DEBUG_TAG, "Noticed a change in the media provider, scheduling sync."); cameraManager.performSync(); } } diff --git a/app/src/main/java/com/seafile/seadroid2/cameraupload/MediaSchedulerService.java b/app/src/main/java/com/seafile/seadroid2/cameraupload/MediaSchedulerService.java index e36ad8d0f..c679d1e88 100644 --- a/app/src/main/java/com/seafile/seadroid2/cameraupload/MediaSchedulerService.java +++ b/app/src/main/java/com/seafile/seadroid2/cameraupload/MediaSchedulerService.java @@ -6,13 +6,13 @@ import android.content.SharedPreferences; import android.os.Build; import android.support.annotation.RequiresApi; +import android.util.Log; import com.seafile.seadroid2.SettingsManager; /** * This service monitors the media provider content provider for new images/videos. */ -@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public class MediaSchedulerService extends JobService { private SettingsManager mSettingsManager; private CameraUploadManager mCameraManager; @@ -20,6 +20,7 @@ public class MediaSchedulerService extends JobService { @Override public boolean onStartJob(JobParameters jobParameters) { + Log.i(MediaSchedulerService.class.getName(),"MediaSchedulerService exec job"); mSettingsManager = SettingsManager.instance(); mSettingsManager.registerSharedPreferencesListener(settingsListener); mCameraManager = new CameraUploadManager(getApplicationContext()); diff --git a/app/src/main/java/com/seafile/seadroid2/config/GlideLoadConfig.java b/app/src/main/java/com/seafile/seadroid2/config/GlideLoadConfig.java index b8db37935..939a680ec 100644 --- a/app/src/main/java/com/seafile/seadroid2/config/GlideLoadConfig.java +++ b/app/src/main/java/com/seafile/seadroid2/config/GlideLoadConfig.java @@ -11,6 +11,10 @@ public class GlideLoadConfig { public static GlideUrl getGlideUrl(String url) { + if (SupportAccountManager.getInstance().getCurrentAccount() == null) { + return new GlideUrl(url, new LazyHeaders.Builder().build()); + } + String token = SupportAccountManager.getInstance().getCurrentAccount().token; GlideUrl glideUrl = new GlideUrl(url, new LazyHeaders.Builder() diff --git a/app/src/main/java/com/seafile/seadroid2/notification/DownloadNotificationProvider.java b/app/src/main/java/com/seafile/seadroid2/notification/DownloadNotificationProvider.java index 7f1c5ca47..9adfafd8c 100644 --- a/app/src/main/java/com/seafile/seadroid2/notification/DownloadNotificationProvider.java +++ b/app/src/main/java/com/seafile/seadroid2/notification/DownloadNotificationProvider.java @@ -105,7 +105,7 @@ public void notifyStarted() { PendingIntent dPendingIntent = PendingIntent.getActivity(SeadroidApplication.getAppContext(), (int) System.currentTimeMillis(), dIntent, - 0); + PendingIntent.FLAG_IMMUTABLE); mNotifBuilder = CustomNotificationBuilder.getNotificationBuilder(SeadroidApplication.getAppContext(), CustomNotificationBuilder.CHANNEL_ID_DOWNLOAD) .setSmallIcon(R.drawable.icon) diff --git a/app/src/main/java/com/seafile/seadroid2/notification/UploadNotificationProvider.java b/app/src/main/java/com/seafile/seadroid2/notification/UploadNotificationProvider.java index 74500d4d5..b6dd8e8af 100644 --- a/app/src/main/java/com/seafile/seadroid2/notification/UploadNotificationProvider.java +++ b/app/src/main/java/com/seafile/seadroid2/notification/UploadNotificationProvider.java @@ -1,5 +1,7 @@ package com.seafile.seadroid2.notification; +import static android.app.PendingIntent.FLAG_IMMUTABLE; + import android.app.PendingIntent; import android.content.Intent; import com.seafile.seadroid2.R; @@ -64,9 +66,7 @@ protected void notifyStarted() { dIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent uPendingIntent = PendingIntent.getActivity(SeadroidApplication.getAppContext(), - (int) System.currentTimeMillis(), - dIntent, - 0); + (int) System.currentTimeMillis(), dIntent, FLAG_IMMUTABLE); mNotifBuilder = CustomNotificationBuilder.getNotificationBuilder(SeadroidApplication.getAppContext(), CustomNotificationBuilder.CHANNEL_ID_UPLOAD) .setSmallIcon(R.drawable.icon) diff --git a/app/src/main/java/com/seafile/seadroid2/ui/WidgetUtils.java b/app/src/main/java/com/seafile/seadroid2/ui/WidgetUtils.java index 0e0d66c45..0492a8a77 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/WidgetUtils.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/WidgetUtils.java @@ -13,6 +13,7 @@ import com.seafile.seadroid2.R; import com.seafile.seadroid2.SeadroidApplication; +import com.seafile.seadroid2.SeafException; import com.seafile.seadroid2.account.Account; import com.seafile.seadroid2.ui.activity.BaseActivity; import com.seafile.seadroid2.ui.activity.BrowserActivity; @@ -25,6 +26,7 @@ import com.seafile.seadroid2.util.Utils; import java.io.File; +import java.net.HttpURLConnection; import java.util.List; /** @@ -67,6 +69,17 @@ public void onTaskSuccess() { // clipboard.setPrimaryClip(clip); Toast.makeText(activity, R.string.link_ready_to_be_pasted, Toast.LENGTH_SHORT).show(); } + + @Override + public void onTaskFailed(SeafException e) { + super.onTaskFailed(e); + gdialog.dismiss(); + if (e.getCode() == HttpURLConnection.HTTP_FORBIDDEN) { + Toast.makeText(activity, R.string.share_link_no_permission, Toast.LENGTH_LONG).show(); + } else { + Toast.makeText(activity, e.getMessage(), Toast.LENGTH_LONG).show(); + } + } }); gdialog.show(activity.getSupportFragmentManager(), "DialogFragment"); } @@ -78,7 +91,7 @@ public void onAppSelected(ResolveInfo appInfo) { shareIntent.setClassName(packageName, className); final GetShareLinkDialog gdialog = new GetShareLinkDialog(); - gdialog.init(repoID, path, isdir, account,password, days); + gdialog.init(repoID, path, isdir, account, password, days); gdialog.setTaskDialogLisenter(new TaskDialog.TaskDialogListener() { @Override public void onTaskSuccess() { @@ -97,17 +110,17 @@ public static void inputSharePassword(final BaseActivity activity, final String repoID, final String path, final boolean isdir, - final Account account){ + final Account account) { final GetShareLinkEncryptDialog dialog = new GetShareLinkEncryptDialog(); dialog.setTaskDialogLisenter(new TaskDialog.TaskDialogListener() { @Override public void onTaskSuccess() { String password = dialog.getPassword(); String days = dialog.getDays(); - chooseShareApp(activity,repoID,path,isdir,account,password,days); + chooseShareApp(activity, repoID, path, isdir, account, password, days); } }); - dialog.show(activity.getSupportFragmentManager(),BrowserActivity.CHARE_LINK_PASSWORD_FRAGMENT_TAG); + dialog.show(activity.getSupportFragmentManager(), BrowserActivity.CHARE_LINK_PASSWORD_FRAGMENT_TAG); } diff --git a/app/src/main/java/com/seafile/seadroid2/ui/activity/BrowserActivity.java b/app/src/main/java/com/seafile/seadroid2/ui/activity/BrowserActivity.java index 267936621..d67935ae4 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/activity/BrowserActivity.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/activity/BrowserActivity.java @@ -1,8 +1,11 @@ package com.seafile.seadroid2.ui.activity; +import static com.seafile.seadroid2.cameraupload.CameraUploadManager.AUTHORITY; + import android.Manifest; import android.content.BroadcastReceiver; import android.content.ComponentName; +import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -47,8 +50,7 @@ import com.seafile.seadroid2.SettingsManager; import com.seafile.seadroid2.account.Account; import com.seafile.seadroid2.account.AccountManager; -import com.seafile.seadroid2.folderbackup.FolderBackupService; -import com.seafile.seadroid2.folderbackup.FolderBackupService.FileBackupBinder; +import com.seafile.seadroid2.cameraupload.CameraSyncService; import com.seafile.seadroid2.cameraupload.CameraUploadManager; import com.seafile.seadroid2.cameraupload.MediaObserverService; import com.seafile.seadroid2.data.CheckUploadServiceEvent; @@ -60,6 +62,8 @@ import com.seafile.seadroid2.data.ServerInfo; import com.seafile.seadroid2.data.StorageManager; import com.seafile.seadroid2.fileschooser.MultiFileChooserActivity; +import com.seafile.seadroid2.folderbackup.FolderBackupService; +import com.seafile.seadroid2.folderbackup.FolderBackupService.FileBackupBinder; import com.seafile.seadroid2.monitor.FileMonitorService; import com.seafile.seadroid2.notification.DownloadNotificationProvider; import com.seafile.seadroid2.notification.UploadNotificationProvider; @@ -99,7 +103,6 @@ import com.seafile.seadroid2.util.ConcurrentAsyncTask; import com.seafile.seadroid2.util.Utils; import com.seafile.seadroid2.util.UtilsJellyBean; -import com.viewpagerindicator.IconPagerAdapter; import org.apache.commons.io.IOUtils; import org.greenrobot.eventbus.EventBus; @@ -697,7 +700,7 @@ private boolean checkSearchEnabled() { return serverInfo.isSearchEnabled(); } - private class SeafileTabsAdapter extends FragmentPagerAdapter implements IconPagerAdapter { + private class SeafileTabsAdapter extends FragmentPagerAdapter { public SeafileTabsAdapter(FragmentManager fm) { super(fm); } @@ -754,10 +757,10 @@ public CharSequence getPageTitle(int position) { } } - @Override - public int getIconResId(int index) { - return ICONS[index]; - } +// @Override +// public int getIconResId(int index) { +// return ICONS[index]; +// } @Override public int getCount() { @@ -2478,6 +2481,7 @@ public void onEvent(CheckUploadServiceEvent result) { } else { Log.d(DEBUG_TAG, "onEvent============true "); } + if (!Utils.isServiceRunning(BrowserActivity.this, "com.seafile.seadroid2.monitor.FileMonitorService")) { monitorIntent = new Intent(this, FileMonitorService.class); startService(monitorIntent); @@ -2489,6 +2493,5 @@ public void onEvent(CheckUploadServiceEvent result) { startService(monitorIntent); Log.d(DEBUG_TAG, "FolderBackupService============false "); } - } } diff --git a/app/src/main/java/com/seafile/seadroid2/ui/activity/FileActivity.java b/app/src/main/java/com/seafile/seadroid2/ui/activity/FileActivity.java index d4ac69781..b8034439f 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/activity/FileActivity.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/activity/FileActivity.java @@ -76,7 +76,7 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent intent = getIntent(); - mAccount = intent.getParcelableExtra("account"); + mAccount = intent.getParcelableExtra("account"); mRepoName = intent.getStringExtra("repoName"); mRepoID = intent.getStringExtra("repoID"); mFilePath = intent.getStringExtra("filePath"); @@ -117,11 +117,11 @@ protected void onDestroy() { } private void initWidgets() { - mFileNameText = (TextView)findViewById(R.id.file_name); - mFileIcon = (ImageView)findViewById(R.id.file_icon); - mButtonCancel = (Button)findViewById(R.id.op_cancel); - mProgressBar = (ProgressBar)findViewById(R.id.progress_bar); - mProgressText = (TextView)findViewById(R.id.progress_text); + mFileNameText = (TextView) findViewById(R.id.file_name); + mFileIcon = (ImageView) findViewById(R.id.file_icon); + mButtonCancel = (Button) findViewById(R.id.op_cancel); + mProgressBar = (ProgressBar) findViewById(R.id.progress_bar); + mProgressText = (TextView) findViewById(R.id.progress_text); String fileName = Utils.fileNameFromPath(mFilePath); mFileNameText.setText(fileName); @@ -181,7 +181,7 @@ private void onFileDownloadProgress(DownloadTaskInfo info) { if (fileSize == 0) { percent = 100; } else { - percent = (int)(finished * 100 / fileSize); + percent = (int) (finished * 100 / fileSize); } mProgressBar.setProgress(percent); @@ -211,8 +211,7 @@ private void onFileDownloaded() { result.putExtra("path", file.getAbsolutePath()); result.putExtra("is_open_with", isOpenWith); setResult(RESULT_OK, result); - } - else { + } else { setResult(RESULT_CANCELED); } stopTimer(); @@ -292,7 +291,7 @@ else if (downloadTaskInfo.state == TaskState.FINISHED) else if (downloadTaskInfo.state == TaskState.CANCELLED) // do nothing when cancelled - Log.d(DEBUG_TAG, "timer post refresh signal " + System.currentTimeMillis()); + Log.d(DEBUG_TAG, "timer post refresh signal " + System.currentTimeMillis()); mTimer.postDelayed(this, 1 * 1000); } }, 1 * 1000); diff --git a/app/src/main/java/com/seafile/seadroid2/ui/activity/MarkdownActivity.java b/app/src/main/java/com/seafile/seadroid2/ui/activity/MarkdownActivity.java index 1cc690fc1..2c66347d6 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/activity/MarkdownActivity.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/activity/MarkdownActivity.java @@ -100,13 +100,8 @@ private void edit() { // First try to find an activity who can handle markdown edit Intent editAsMarkDown = new Intent(Intent.ACTION_EDIT); - Uri uri; - if (android.os.Build.VERSION.SDK_INT > 23) { - uri = FileProvider.getUriForFile(this, getPackageName() , new File(path)); - editAsMarkDown.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); - } else { - uri = Uri.parse(path); - } + Uri uri = FileProvider.getUriForFile(this, getPackageName(), new File(path)); + editAsMarkDown.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); String mime = FileMimeUtils.getMimeType(new File(path)); editAsMarkDown.setDataAndType(uri, mime); diff --git a/app/src/main/java/com/seafile/seadroid2/ui/fragment/SettingsFragment.java b/app/src/main/java/com/seafile/seadroid2/ui/fragment/SettingsFragment.java index 649359d96..1c101528e 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/fragment/SettingsFragment.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/fragment/SettingsFragment.java @@ -24,6 +24,7 @@ import com.google.common.collect.Maps; import com.google.gson.Gson; import com.hjq.permissions.OnPermissionCallback; +import com.hjq.permissions.Permission; import com.hjq.permissions.XXPermissions; import com.seafile.seadroid2.R; import com.seafile.seadroid2.SeadroidApplication; @@ -319,7 +320,8 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { cFolderBackupCategory.removePreference(cBackupFolderState); SettingsManager.instance().saveFolderAutomaticBackup(false); } else { - XXPermissions.with(getActivity()).permission("android.permission.MANAGE_EXTERNAL_STORAGE").request(new OnPermissionCallback() { + + XXPermissions.with(getActivity()).permission(Permission.MANAGE_EXTERNAL_STORAGE).request(new OnPermissionCallback() { @Override public void onGranted(List permissions, boolean all) { @@ -382,6 +384,7 @@ public boolean onPreferenceClick(Preference preference) { return true; } }); + // Change backup folder cBackupFolderMode = findPreference(SettingsManager.FOLDER_BACKUP_MODE); cBackupFolderRepo = findPreference(SettingsManager.FOLDER_BACKUP_LIBRARY_KEY); diff --git a/app/src/main/java/com/seafile/seadroid2/util/Utils.java b/app/src/main/java/com/seafile/seadroid2/util/Utils.java index 56540b341..8d7c5108f 100644 --- a/app/src/main/java/com/seafile/seadroid2/util/Utils.java +++ b/app/src/main/java/com/seafile/seadroid2/util/Utils.java @@ -717,16 +717,13 @@ public static String cleanServerURL(String serverURL) throws MalformedURLExcepti public static ResolveInfo getWeChatIntent(Intent intent) { PackageManager pm = SeadroidApplication.getAppContext().getPackageManager(); List infos = pm.queryIntentActivities(intent, 0); - - ResolveInfo info = null; - Iterator iter = infos.iterator(); - while (iter.hasNext()) { - info = iter.next(); + for (ResolveInfo info : infos) { if (info.activityInfo.packageName.equals("com.tencent.mm")) { - break; + return info; } } - return info; + + return null; } @@ -917,8 +914,11 @@ public static boolean isServiceRunning(Context context, String ServiceName) { public static void startCameraSyncJob(Context context) { JobScheduler mJobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); JobInfo.Builder builder = new JobInfo.Builder(JOB_ID, new ComponentName(context.getPackageName(), MediaSchedulerService.class.getName())); - builder.setMinimumLatency(15 * 60 * 1000);// Set to execute after at least 15 minutes delay - builder.setOverrideDeadline(20 * 60 * 1000);// The setting is delayed by 20 minutes, + builder.setMinimumLatency(5 * 1000);// Set to execute after at least 15 minutes delay + builder.setOverrideDeadline(60 * 60 * 1000);// The setting is delayed by 20 minutes, + builder.setRequiresCharging(false); + builder.setRequiresDeviceIdle(false); + builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); builder.setPersisted(true); mJobScheduler.schedule(builder.build()); } diff --git a/app/src/main/res/drawable/indicator_drawable.xml b/app/src/main/res/drawable/indicator_drawable.xml new file mode 100644 index 000000000..fa55bc439 --- /dev/null +++ b/app/src/main/res/drawable/indicator_drawable.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/indicator_drawable_2.xml b/app/src/main/res/drawable/indicator_drawable_2.xml new file mode 100644 index 000000000..5df9eb433 --- /dev/null +++ b/app/src/main/res/drawable/indicator_drawable_2.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/cuc_activity_layout.xml b/app/src/main/res/layout/cuc_activity_layout.xml index 7bafb8d6d..f9ef0b3e3 100644 --- a/app/src/main/res/layout/cuc_activity_layout.xml +++ b/app/src/main/res/layout/cuc_activity_layout.xml @@ -1,25 +1,25 @@ - + + android:id="@+id/cuc_pager" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:paddingBottom="16dp" /> - - - + + diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index eb4021fa5..7131501bb 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -180,6 +180,7 @@ 无下载任务 注意:服务器地址应该包含端口号。比如www.example.com:8000 复制链接 + 你没有权限进行此次操作 分享此文件的链接 分享此文件夹的链接 请输入分享密码 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 78802a5fc..a1b8c245e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -195,6 +195,7 @@ No download tasks yet Note: Server address should contain the port. For example, www.example.com:8000 Copy link + You do not have permission to perform this action. Share a link to this file Share a link to this folder input share password diff --git a/build.gradle b/build.gradle index 967486405..c4f13fe44 100644 --- a/build.gradle +++ b/build.gradle @@ -2,9 +2,11 @@ buildscript { repositories { - jcenter() google() mavenCentral() + maven { url 'https://jitpack.io' } + maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } + maven { url "https://maven.aliyun.com/repository/public" } } dependencies { classpath 'com.android.tools.build:gradle:7.1.2' @@ -17,9 +19,10 @@ buildscript { allprojects { repositories { google() // https://stackoverflow.com/a/50563942/5923915 - jcenter() mavenCentral() maven { url 'https://jitpack.io' } + maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } + maven { url "https://maven.aliyun.com/repository/public" } } } @@ -27,6 +30,6 @@ ext { compileSdkVersion = 29 supportLibVersion = '27.1.1' // variable that can be referenced to keep support libs consistent minSdkVersion = 26 - targetSdkVersion = 30 + targetSdkVersion = 31 buildToolsVersion = '27.0.3' }