mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-29 13:53:54 +01:00
Upgrade to SDK 34 (#5790)
* change the overridden method signature as per API 34 * add version check condition to compare with API 23 before adding flag * refactor: add final keywords, fix typo, and remove redundant spaces For optimized code only * upgrade: migrate to SDK 34 and upgrade APG Additionally, add Jetpack Compose to the project * AndroidManifest: add new permission for API 34 DescriptionActivity should not be exposed * refactor: permission should not be check on onCreate for some cases * add method to get correct storage permission and check partial access Additionally, add final keywords to reduce compiler warnings * refactor: prevent app from crashing for SDKs >= 34 * add new UI component to allows user to manage partially access photos Implement using composeView * change the overridden method signature as per API 34 * add version check condition to compare with API 23 before adding flag * refactor: add final keywords, fix typo, and remove redundant spaces For optimized code only * upgrade: migrate to SDK 34 and upgrade APG Additionally, add Jetpack Compose to the project * AndroidManifest: add new permission for API 34 DescriptionActivity should not be exposed * refactor: permission should not be check on onCreate for some cases * add method to get correct storage permission and check partial access Additionally, add final keywords to reduce compiler warnings * refactor: prevent app from crashing for SDKs >= 34 * add new UI component to allows user to manage partially access photos Implement using composeView * replace deprecated circular progress bar with material progress bar * remove redundant appcompat dependency * add condition to check for partial access on API >= 34 It prevents invoking photo picker on UploadActivity. * UploadWorker: add foreground service type * fix typos in UploadWorker.kt * add permission to access media location
This commit is contained in:
parent
eb027b74ce
commit
3e915f9848
17 changed files with 433 additions and 200 deletions
|
|
@ -9,10 +9,9 @@ import android.graphics.Bitmap;
|
|||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.facebook.common.executors.CallerThreadExecutor;
|
||||
import com.facebook.common.references.CloseableReference;
|
||||
import com.facebook.datasource.DataSource;
|
||||
|
|
@ -22,10 +21,8 @@ import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
|
|||
import com.facebook.imagepipeline.image.CloseableImage;
|
||||
import com.facebook.imagepipeline.request.ImageRequest;
|
||||
import com.facebook.imagepipeline.request.ImageRequestBuilder;
|
||||
|
||||
import fr.free.nrw.commons.media.MediaClient;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.contributions.MainActivity;
|
||||
import fr.free.nrw.commons.di.ApplicationlessInjection;
|
||||
|
|
@ -41,17 +38,28 @@ import static android.content.Intent.ACTION_VIEW;
|
|||
*/
|
||||
public class PicOfDayAppWidget extends AppWidgetProvider {
|
||||
|
||||
private CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||
private final CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||
|
||||
@Inject
|
||||
MediaClient mediaClient;
|
||||
|
||||
void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
|
||||
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.pic_of_day_app_widget);
|
||||
void updateAppWidget(
|
||||
final Context context,
|
||||
final AppWidgetManager appWidgetManager,
|
||||
final int appWidgetId
|
||||
) {
|
||||
final RemoteViews views = new RemoteViews(
|
||||
context.getPackageName(), R.layout.pic_of_day_app_widget);
|
||||
|
||||
// Launch App on Button Click
|
||||
Intent viewIntent = new Intent(context, MainActivity.class);
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, viewIntent, PendingIntent.FLAG_IMMUTABLE);
|
||||
final Intent viewIntent = new Intent(context, MainActivity.class);
|
||||
int flags = PendingIntent.FLAG_UPDATE_CURRENT;
|
||||
if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.M) {
|
||||
flags |= PendingIntent.FLAG_IMMUTABLE;
|
||||
}
|
||||
final PendingIntent pendingIntent = PendingIntent.getActivity(
|
||||
context, 0, viewIntent, flags);
|
||||
|
||||
views.setOnClickPendingIntent(R.id.camera_button, pendingIntent);
|
||||
appWidgetManager.updateAppWidget(appWidgetId, views);
|
||||
|
||||
|
|
@ -60,61 +68,76 @@ public class PicOfDayAppWidget extends AppWidgetProvider {
|
|||
|
||||
/**
|
||||
* Loads the picture of the day using media wiki API
|
||||
* @param context
|
||||
* @param views
|
||||
* @param appWidgetManager
|
||||
* @param appWidgetId
|
||||
* @param context The application context.
|
||||
* @param views The RemoteViews object used to update the App Widget UI.
|
||||
* @param appWidgetManager The AppWidgetManager instance for managing the widget.
|
||||
* @param appWidgetId he ID of the App Widget to update.
|
||||
*/
|
||||
private void loadPictureOfTheDay(Context context,
|
||||
RemoteViews views,
|
||||
AppWidgetManager appWidgetManager,
|
||||
int appWidgetId) {
|
||||
private void loadPictureOfTheDay(
|
||||
final Context context,
|
||||
final RemoteViews views,
|
||||
final AppWidgetManager appWidgetManager,
|
||||
final int appWidgetId
|
||||
) {
|
||||
compositeDisposable.add(mediaClient.getPictureOfTheDay()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
response -> {
|
||||
if (response != null) {
|
||||
views.setTextViewText(R.id.appwidget_title, response.getDisplayTitle());
|
||||
response -> {
|
||||
if (response != null) {
|
||||
views.setTextViewText(R.id.appwidget_title, response.getDisplayTitle());
|
||||
|
||||
// View in browser
|
||||
Intent viewIntent = new Intent();
|
||||
viewIntent.setAction(ACTION_VIEW);
|
||||
viewIntent.setData(Uri.parse(response.getPageTitle().getMobileUri()));
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, viewIntent, PendingIntent.FLAG_IMMUTABLE);
|
||||
views.setOnClickPendingIntent(R.id.appwidget_image, pendingIntent);
|
||||
// View in browser
|
||||
final Intent viewIntent = new Intent();
|
||||
viewIntent.setAction(ACTION_VIEW);
|
||||
viewIntent.setData(Uri.parse(response.getPageTitle().getMobileUri()));
|
||||
|
||||
loadImageFromUrl(response.getThumbUrl(), context, views, appWidgetManager, appWidgetId);
|
||||
int flags = PendingIntent.FLAG_UPDATE_CURRENT;
|
||||
if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.M) {
|
||||
flags |= PendingIntent.FLAG_IMMUTABLE;
|
||||
}
|
||||
},
|
||||
t -> Timber.e(t, "Fetching picture of the day failed")
|
||||
final PendingIntent pendingIntent = PendingIntent.getActivity(
|
||||
context, 0, viewIntent, flags);
|
||||
|
||||
views.setOnClickPendingIntent(R.id.appwidget_image, pendingIntent);
|
||||
loadImageFromUrl(response.getThumbUrl(),
|
||||
context, views, appWidgetManager, appWidgetId);
|
||||
}
|
||||
},
|
||||
t -> Timber.e(t, "Fetching picture of the day failed")
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses Fresco to load an image from Url
|
||||
* @param imageUrl
|
||||
* @param context
|
||||
* @param views
|
||||
* @param appWidgetManager
|
||||
* @param appWidgetId
|
||||
* @param imageUrl The URL of the image to load.
|
||||
* @param context The application context.
|
||||
* @param views The RemoteViews object used to update the App Widget UI.
|
||||
* @param appWidgetManager The AppWidgetManager instance for managing the widget.
|
||||
* @param appWidgetId he ID of the App Widget to update.
|
||||
*/
|
||||
private void loadImageFromUrl(String imageUrl,
|
||||
Context context,
|
||||
RemoteViews views,
|
||||
AppWidgetManager appWidgetManager,
|
||||
int appWidgetId) {
|
||||
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(Uri.parse(imageUrl)).build();
|
||||
ImagePipeline imagePipeline = Fresco.getImagePipeline();
|
||||
DataSource<CloseableReference<CloseableImage>> dataSource
|
||||
= imagePipeline.fetchDecodedImage(request, context);
|
||||
private void loadImageFromUrl(
|
||||
final String imageUrl,
|
||||
final Context context,
|
||||
final RemoteViews views,
|
||||
final AppWidgetManager appWidgetManager,
|
||||
final int appWidgetId
|
||||
) {
|
||||
final ImageRequest request = ImageRequestBuilder
|
||||
.newBuilderWithSource(Uri.parse(imageUrl)).build();
|
||||
final ImagePipeline imagePipeline = Fresco.getImagePipeline();
|
||||
final DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline
|
||||
.fetchDecodedImage(request, context);
|
||||
|
||||
dataSource.subscribe(new BaseBitmapDataSubscriber() {
|
||||
@Override
|
||||
protected void onNewResultImpl(@Nullable Bitmap tempBitmap) {
|
||||
protected void onNewResultImpl(@Nullable final Bitmap tempBitmap) {
|
||||
Bitmap bitmap = null;
|
||||
if (tempBitmap != null) {
|
||||
bitmap = Bitmap.createBitmap(tempBitmap.getWidth(), tempBitmap.getHeight(), Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
bitmap = Bitmap.createBitmap(
|
||||
tempBitmap.getWidth(), tempBitmap.getHeight(), Bitmap.Config.ARGB_8888
|
||||
);
|
||||
final Canvas canvas = new Canvas(bitmap);
|
||||
canvas.drawBitmap(tempBitmap, 0f, 0f, new Paint());
|
||||
}
|
||||
views.setImageViewBitmap(R.id.appwidget_image, bitmap);
|
||||
|
|
@ -122,32 +145,37 @@ public class PicOfDayAppWidget extends AppWidgetProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void onFailureImpl(DataSource<CloseableReference<CloseableImage>> dataSource) {
|
||||
protected void onFailureImpl(
|
||||
final DataSource<CloseableReference<CloseableImage>> dataSource
|
||||
) {
|
||||
// Ignore failure for now.
|
||||
}
|
||||
}, CallerThreadExecutor.getInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
|
||||
public void onUpdate(
|
||||
final Context context,
|
||||
final AppWidgetManager appWidgetManager,
|
||||
final int[] appWidgetIds
|
||||
) {
|
||||
ApplicationlessInjection
|
||||
.getInstance(context
|
||||
.getApplicationContext())
|
||||
.getInstance(context.getApplicationContext())
|
||||
.getCommonsApplicationComponent()
|
||||
.inject(this);
|
||||
// There may be multiple widgets active, so update all of them
|
||||
for (int appWidgetId : appWidgetIds) {
|
||||
for (final int appWidgetId : appWidgetIds) {
|
||||
updateAppWidget(context, appWidgetManager, appWidgetId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnabled(Context context) {
|
||||
public void onEnabled(final Context context) {
|
||||
// Enter relevant functionality for when the first widget is created
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisabled(Context context) {
|
||||
public void onDisabled(final Context context) {
|
||||
// Enter relevant functionality for when the last widget is disabled
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue