Skip to content
This repository has been archived by the owner on Mar 25, 2024. It is now read-only.

App installation screen improvements #680

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
3 changes: 1 addition & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@
android:parentActivityName=".activities.SettingsActivity" />
<activity
android:name=".activities.FwAppInstallerActivity"
android:label="@string/title_activity_fw_app_insaller"
android:parentActivityName=".activities.ControlCenterv2">
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the parent activity because we don't want the back button to re-open the main activity, we want it to finish the current activity

android:label="@string/title_activity_fw_app_insaller">
<intent-filter>
<action android:name="android.intent.action.VIEW" />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,13 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.graphics.drawable.VectorDrawableCompat;
import android.support.v4.app.NavUtils;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
Expand Down Expand Up @@ -55,23 +59,39 @@ public class FwAppInstallerActivity extends GBActivity implements InstallActivit

private static final Logger LOG = LoggerFactory.getLogger(FwAppInstallerActivity.class);
private static final String ITEM_DETAILS = "details";

private final List<ItemWithDetails> mItems = new ArrayList<>();
private TextView fwAppInstallTextView;
private Button installButton;
private Uri uri;
private GBDevice device;
private InstallHandler installHandler;
private boolean mayConnect;

private ProgressBar mProgressBar;
private ListView itemListView;
private final List<ItemWithDetails> mItems = new ArrayList<>();
private ItemWithDetailsAdapter mItemAdapter;

private ListView detailsListView;
private ItemWithDetailsAdapter mDetailsItemAdapter;
private ArrayList<ItemWithDetails> mDetails = new ArrayList<>();

private final BroadcastReceiver installationResultReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//Receive installation fail/success intent
if (mProgressBar != null)
mProgressBar.setVisibility(View.INVISIBLE);
if (installButton != null) {
installButton.setVisibility(View.VISIBLE);
installButton.setClickable(false);
if (intent.getAction().equals("nodomain.freeyourgadget.gadgetbridge.INSTALLATION_FAILED")) {
installButton.setText(getString(R.string.installation_failed_));
} else if (intent.getAction().equals("nodomain.freeyourgadget.gadgetbridge.INSTALLATION_SUCCESS")) {
installButton.setText(getString(R.string.installation_successful));
}
}
}
};

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Expand Down Expand Up @@ -128,6 +148,12 @@ private void validateInstallation() {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (GBApplication.isDarkThemeEnabled()) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the super.onCreate sets the theme to GadgetbridgeThemeDark with action bar, we don't want the action bar because we use a toolbar in the layout xml file

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you try directly extending the appcompat activity as it is done in ControlCenterv2? https://github.com/Freeyourgadget/Gadgetbridge/blob/master/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java#L63
It should allow you to avoid this check.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, I also merged the toolbars by using a toolbar.xml file, I include that file both in the ControlCenterv2 activity and the FwAppInstallerActivity activity layouts

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still need to check if the dark theme is enabled and change the theme if it is. But the else statement is redundant

setTheme(R.style.GadgetbridgeThemeDark_NoActionBar);
} else {
setTheme(R.style.GadgetbridgeTheme_NoActionBar);
}

setContentView(R.layout.activity_appinstaller);

GBDevice dev = getIntent().getParcelableExtra(GBDevice.EXTRA_DEVICE);
Expand Down Expand Up @@ -165,13 +191,37 @@ public void onClick(View v) {
setInstallEnabled(false);
installHandler.onStartInstall(device);
GBApplication.deviceService().onInstallApp(uri);
mProgressBar.setVisibility(View.VISIBLE);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("nodomain.freeyourgadget.gadgetbridge.INSTALLATION_FAILED");
intentFilter.addAction("nodomain.freeyourgadget.gadgetbridge.INSTALLATION_SUCCESS");
registerReceiver(installationResultReceiver, intentFilter);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Register the receiver to the failed/success installation intent, the receiver updates the views (progress bar/button)

}
});

uri = getIntent().getData();
if (uri == null) { //for "share" intent
uri = getIntent().getParcelableExtra(Intent.EXTRA_STREAM);
}

//Get apps count and app index from calling intent
int appsCount = getIntent().getIntExtra("APPS_COUNT", 1);
int currentAppIndex = getIntent().getIntExtra("APP_INDEX", 1);

//Set up the toolbar
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitleTextColor(ContextCompat.getColor(getApplicationContext(), android.R.color.white));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set the text color to white

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above about extending AppCompat activity: I believe you will not need this after changing.
Since it took some time to get the colors under control (and is not all done yet :-) ) I really would like to avoid using colors outside of the theme-inherited ones.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll change it, BTW, I'm pretty sure we should no longer use the themes that include action bars, AFAIK toolbars are the way to go.
https://medium.com/@ZakTaccardi/goodbye-actionbar-apis-hello-toolbar-af6ae7b31e5d

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, we didn't because of lack of time on our end, perhaps you can open a new PR after this one is merged to take care of the migration? It would be really great!

toolbar.setTitle(getResources().getString(R.string.installation_d_d, currentAppIndex, appsCount));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set the title to installing ($index/$count)

toolbar.setNavigationIcon(VectorDrawableCompat.create(getResources(), R.drawable.ic_arrow_back, null));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
toolbar.setElevation(16);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set elevation only on lollipop+ devices (the fancy shadow)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AppCompat should take care of this as well without explicit version checking.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, right

toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finish the current installation activity when the back button is clicked

}
});

installHandler = findInstallHandlerFor(uri);
if (installHandler == null) {
setInfoText(getString(R.string.installer_activity_unable_to_find_handler));
Expand Down Expand Up @@ -220,13 +270,13 @@ protected void onDestroy() {
}

@Override
public void setInfoText(String text) {
fwAppInstallTextView.setText(text);
public CharSequence getInfoText() {
return fwAppInstallTextView.getText();
}

@Override
public CharSequence getInfoText() {
return fwAppInstallTextView.getText();
public void setInfoText(String text) {
fwAppInstallTextView.setText(text);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
Expand Down Expand Up @@ -97,6 +98,7 @@ protected void onCreate(Bundle savedInstanceState) {
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
intent.setType("*/*");
startActivityForResult(intent, READ_REQUEST_CODE);
}
Expand Down Expand Up @@ -213,8 +215,21 @@ public void onActivityResult(int requestCode, int resultCode, Intent resultData)
if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
Intent startIntent = new Intent(AppManagerActivity.this, FwAppInstallerActivity.class);
startIntent.setAction(Intent.ACTION_VIEW);
startIntent.setDataAndType(resultData.getData(), null);
startActivity(startIntent);
ClipData clipData = resultData.getClipData();
if (clipData != null) {
//If there is more than one app to install
int appsCount = clipData.getItemCount();
for (int i = 0; i < appsCount; i++) {
startIntent.setDataAndType(clipData.getItemAt(i).getUri(), null);
startIntent.putExtra("APPS_COUNT", appsCount);
startIntent.putExtra("APP_INDEX", Math.abs(i - appsCount));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because we want it to be (1/3) -> (2/3) -> (3/3), not (3/3) -> (2/3) -> (1/3)
Why not use for (int i = appsCount; i >=0 ; i--) you ask?
That would be a good question.

startActivity(startIntent);
}
} else {
//If there is one app to install
startIntent.setDataAndType(resultData.getData(), null);
startActivity(startIntent);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -625,12 +625,15 @@ void installApp(Uri uri, int appId) {
}

private void finishInstall(boolean hadError) {
Intent resultIntent;
if (!mIsInstalling) {
return;
}
if (hadError) {
resultIntent = new Intent("nodomain.freeyourgadget.gadgetbridge.INSTALLATION_FAILED");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The installation was unsuccessful, set the intent action to failed

GB.updateInstallNotification(getContext().getString(R.string.installation_failed_), false, 0, getContext());
} else {
resultIntent = new Intent("nodomain.freeyourgadget.gadgetbridge.INSTALLATION_SUCCESS");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The installation was successful, set the intent action to success

GB.updateInstallNotification(getContext().getString(R.string.installation_successful), false, 0, getContext());
if (mPebbleProtocol.mFwMajor >= 3) {
String filenameSuffix;
Expand All @@ -646,6 +649,7 @@ private void finishInstall(boolean hadError) {
}
}
}
getContext().sendBroadcast(resultIntent);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Send the broadcast

mInstallState = PebbleAppInstallState.UNKNOWN;

if (hadError && mAppInstallToken != -1) {
Expand Down
9 changes: 9 additions & 0 deletions app/src/main/res/drawable/ic_arrow_back.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFF"
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
</vector>
118 changes: 55 additions & 63 deletions app/src/main/res/layout/activity_appinstaller.xml
Original file line number Diff line number Diff line change
@@ -1,77 +1,69 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This layout is pretty much a list of views that goes from top to bottom, no reason to use RelativeLayout with so many rules when we can simply use a vertical LinearLayout

xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
android:animateLayoutChanges="true"
android:orientation="vertical"
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.FwAppInstallerActivity">

<ListView
android:id="@+id/itemListView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="false"></ListView>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:title="@string/app_name" />

<TextView
android:id="@+id/infoTextView"
android:layout_width="fill_parent"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_alignParentTop="false"
android:layout_alignParentEnd="false"
android:layout_alignParentStart="false"
android:layout_below="@+id/itemListView" />
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">

<ImageView
android:id="@+id/fwappStatusIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="Status Icon"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="false"
android:layout_alignParentLeft="false"
android:layout_below="@+id/infoTextView" />
<ListView
android:id="@+id/itemListView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

<ProgressBar
android:id="@+id/installProgressBar"
android:layout_width="40dp"
android:layout_height="40dp"
android:indeterminate="true"
android:layout_gravity="center_horizontal"
android:visibility="gone"
android:layout_below="@+id/fwappStatusIcon"
android:layout_centerHorizontal="true" />
<TextView
android:id="@+id/infoTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/appinstaller_install"
android:id="@+id/installButton"
android:layout_gravity="center_horizontal"
android:enabled="false"
android:layout_alignParentBottom="false"
android:layout_alignWithParentIfMissing="false"
android:layout_alignParentTop="false"
android:layout_alignParentLeft="false"
android:layout_centerHorizontal="true"
android:layout_below="@+id/installProgressBar"
android:layout_marginTop="10dp" />
<ImageView
android:id="@+id/fwappStatusIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />

<ListView
android:id="@+id/detailsListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/installButton"
android:layout_alignParentEnd="false"></ListView>
<ProgressBar
android:id="@+id/installProgressBar"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_horizontal"
android:indeterminate="true"
android:visibility="gone" />

<android.widget.Space
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" />
<Button
android:id="@+id/installButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:enabled="false"
android:text="@string/appinstaller_install" />

<ListView
android:id="@+id/detailsListView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<android.widget.Space
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</RelativeLayout>
</LinearLayout>
</LinearLayout>
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@
<string name="cannot_connect_bt_address_invalid_">Cannot connect. BT address invalid?</string>
<string name="gadgetbridge_running">Gadgetbridge running</string>
<string name="installing_binary_d_d">installing binary %1$d/%2$d</string>
<string name="installation_d_d">Installation (%1$d/%2$d)</string>
<string name="installation_failed_">installation failed!</string>
<string name="installation_successful">installation successful</string>
<string name="firmware_install_warning">YOU ARE TRYING TO INSTALL A FIRMWARE, PROCEED AT YOUR OWN RISK.\n\n\n This firmware is for HW Revision: %s</string>
Expand Down