1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-06-20 20:10:15 +02:00

Add share icon to Step Streaks

This commit is contained in:
vanous 2022-08-02 22:48:41 +02:00
parent 5f4d3f441f
commit fa2d537ca7
2 changed files with 214 additions and 60 deletions

View File

@ -1,28 +1,41 @@
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.core.content.FileProvider;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentActivity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.database.DBAccess;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
@ -30,6 +43,7 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.DailyTotals;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
public class StepStreaksDashboard extends DialogFragment {
@ -89,7 +103,7 @@ public class StepStreaksDashboard extends DialogFragment {
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (backgroundTaskFinished) {
outState.putSerializable(STREAKS, stepsStreaks);
outState.putParcelable(STREAKS, stepsStreaks);
}
}
@ -105,7 +119,7 @@ public class StepStreaksDashboard extends DialogFragment {
}
if (savedInstanceState != null) {
StepsStreaks streaks = (StepsStreaks) savedInstanceState.getSerializable(STREAKS);
StepsStreaks streaks = (StepsStreaks) savedInstanceState.getParcelable(STREAKS);
if (streaks != null) {
stepsStreaks = streaks;
backgroundTaskFinished = true;
@ -148,6 +162,15 @@ public class StepStreaksDashboard extends DialogFragment {
TextView date_total_value = total.findViewById(R.id.step_streak_total_date_value);
TextView date_total_label = total.findViewById(R.id.step_streak_total_label);
ImageButton step_streak_share_button = getView().findViewById(R.id.step_streak_share_button);
step_streak_share_button.setVisibility(View.GONE);
step_streak_share_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
take_share_screenshot(getActivity());
}
});
if (stepsStreaks.current.days > 0) {
current.setVisibility(View.VISIBLE);
days_current.setText(Integer.toString(stepsStreaks.current.days));
@ -170,6 +193,7 @@ public class StepStreaksDashboard extends DialogFragment {
date_maximum_value.setText(DateTimeUtils.formatDateRange(startDate, endDate));
}
if (stepsStreaks.total.steps > 0 || backgroundTaskFinished) {
step_streak_share_button.setVisibility(View.VISIBLE);
total.setVisibility(View.VISIBLE);
days_total_label.setText(R.string.steps_streaks_achievement_rate);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
@ -185,7 +209,6 @@ public class StepStreaksDashboard extends DialogFragment {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
total_total.setTooltipText(String.format(getString(R.string.steps_streaks_total_steps_average_hint), stepsStreaks.total.steps / stepsStreaks.total.total_days));
}
}
if (stepsStreaks.total.timestamp > 0) {
date_total_value.setVisibility(View.VISIBLE);
@ -322,17 +345,139 @@ public class StepStreaksDashboard extends DialogFragment {
}
}
private static class StepsStreak implements Serializable {
private void take_share_screenshot(Context context) {
final ScrollView layout = getView().findViewById(R.id.streaks_dashboard);
final LinearLayout sharingLayout = getView().findViewById(R.id.streaks_dashboard_inner);
int width = layout.getChildAt(0).getHeight();
int height = layout.getChildAt(0).getWidth();
Bitmap screenShot = getScreenShot(sharingLayout, width, height, context);
String fileName = FileUtils.makeValidFileName("Screenshot-" + "StepsStreak-" + DateTimeUtils.formatIso8601(new Date(Calendar.getInstance().getTimeInMillis())) + ".png");
try {
File targetFile = new File(FileUtils.getExternalFilesDir(), fileName);
FileOutputStream fOut = new FileOutputStream(targetFile);
screenShot.compress(Bitmap.CompressFormat.PNG, 85, fOut);
fOut.flush();
fOut.close();
shareScreenshot(targetFile, context);
GB.toast(getActivity(), "Screenshot saved", Toast.LENGTH_LONG, GB.INFO);
} catch (IOException e) {
LOG.error("Error getting screenshot", e);
}
}
private void shareScreenshot(File targetFile, Context context) {
Uri contentUri = FileProvider.getUriForFile(context,
context.getApplicationContext().getPackageName() + ".screenshot_provider", targetFile);
getActivity().grantUriPermission(
context.getApplicationContext().getPackageName(),
contentUri,
Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION
);
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
sharingIntent.setType("image/*");
String shareBody = "My daily step streaks!";
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Steps Streak");
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody);
sharingIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
try {
startActivity(Intent.createChooser(sharingIntent, "Share via"));
} catch (ActivityNotFoundException e) {
Toast.makeText(context, R.string.activity_error_no_app_for_png, Toast.LENGTH_LONG).show();
}
}
public static Bitmap getScreenShot(View view, int height, int width, Context context) {
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawColor(GBApplication.getWindowBackgroundColor(context));
view.draw(canvas);
return bitmap;
}
private static class StepsStreak implements Parcelable {
private int days = 0;
private int steps = 0;
private int timestamp;
private int total_days = 0;
private StepsStreak() {
}
protected StepsStreak(Parcel in) {
days = in.readInt();
steps = in.readInt();
timestamp = in.readInt();
total_days = in.readInt();
}
public static final Creator<StepsStreak> CREATOR = new Creator<StepsStreak>() {
@Override
public StepsStreak createFromParcel(Parcel in) {
return new StepsStreak(in);
}
@Override
public StepsStreak[] newArray(int size) {
return new StepsStreak[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(days);
dest.writeInt(steps);
dest.writeInt(timestamp);
dest.writeInt(total_days);
}
}
private class StepsStreaks implements Serializable {
private class StepsStreaks implements Parcelable {
private StepsStreak current = new StepsStreak();
private StepsStreak maximum = new StepsStreak();
private StepsStreak total = new StepsStreak();
private StepsStreaks() {
}
protected StepsStreaks(Parcel in) {
current = in.readParcelable(StepsStreak.class.getClassLoader());
maximum = in.readParcelable(StepsStreak.class.getClassLoader());
total = in.readParcelable(StepsStreak.class.getClassLoader());
}
public final Creator<StepsStreaks> CREATOR = new Creator<StepsStreaks>() {
@Override
public StepsStreaks createFromParcel(Parcel in) {
return new StepsStreaks(in);
}
@Override
public StepsStreaks[] newArray(int size) {
return new StepsStreaks[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(current, flags);
dest.writeParcelable(maximum, flags);
dest.writeParcelable(total, flags);
}
}
}

View File

@ -1,69 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/streaks_dashboard"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:minWidth="1000dp">
<LinearLayout xmlns:app="http://schemas.android.com/apk/res-auto"
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginTop="15dp"
android:layout_marginBottom="0dp"
android:gravity="center|center_vertical"
android:minWidth="1000dp"
android:orientation="vertical">
android:layout_height="match_parent">
<TextView
<LinearLayout
android:id="@+id/streaks_dashboard_inner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="1dp"
android:layout_marginEnd="1dp"
android:layout_weight="1"
android:gravity="center"
android:maxLines="2"
android:scrollHorizontally="false"
android:text="@string/steps_streaks"
android:textAllCaps="true"
android:textSize="24sp"
android:textStyle="bold"
android:tooltipText="@string/steps_streaks_hint" />
<include
layout="@layout/steps_streak_current_line_layout"
android:visibility="gone" />
<include
layout="@layout/steps_streak_maximum_line_layout"
android:visibility="gone" />
<include
layout="@layout/steps_streak_total_line_layout"
android:visibility="gone" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginStart="35dp"
android:layout_marginTop="39dp"
app:srcCompat="@drawable/ic_events_gold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="1dp"
android:layout_marginEnd="1dp"
android:layout_weight="1"
android:gravity="center"
android:maxLines="2"
android:scrollHorizontally="false"
android:text="@string/steps_streaks"
android:textAllCaps="true"
android:textSize="24sp"
android:textStyle="bold"
android:tooltipText="@string/steps_streaks_hint" />
<ProgressBar
android:id="@+id/step_streak_dashboard_loading_circle"
android:layout_width="171dp"
android:layout_height="171dp"
android:indeterminate="true" />
</RelativeLayout>
<include
layout="@layout/steps_streak_current_line_layout"
android:visibility="gone" />
<include
layout="@layout/steps_streak_maximum_line_layout"
android:visibility="gone" />
</LinearLayout>
<include
layout="@layout/steps_streak_total_line_layout"
android:visibility="gone" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginStart="35dp"
android:layout_marginTop="39dp"
app:srcCompat="@drawable/ic_events_gold" />
<ProgressBar
android:id="@+id/step_streak_dashboard_loading_circle"
android:layout_width="171dp"
android:layout_height="171dp"
android:indeterminate="true" />
</RelativeLayout>
</LinearLayout>
<ImageButton
android:id="@+id/step_streak_share_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
app:srcCompat="@drawable/ic_share" />
</RelativeLayout>
</ScrollView>