mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-19 19:18:27 +00:00
Experience upgrade splash screen.
Behaves similarly to the DatabaseUpgradeActivity. You have a static list of ExperienceUpgrade models that include a "trigger" version, where when a user upgrades through it a notification will appear, and there will be a splash explanation screen. Right now the splash screens are basic and not too configurable, but that can be reworked as upgrades demand. Closes #4151
This commit is contained in:
parent
0b20e99cd2
commit
3035dc4df9
@ -200,6 +200,11 @@
|
||||
android:launchMode="singleTask"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
<activity android:name=".ExperienceUpgradeActivity"
|
||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
|
||||
android:launchMode="singleTask"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
<activity android:name=".PassphraseCreateActivity"
|
||||
android:label="@string/AndroidManifest__create_passphrase"
|
||||
android:windowSoftInputMode="stateUnchanged"
|
||||
@ -435,5 +440,12 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".ExperienceUpgradeActivity$AppUpgradeReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.PACKAGE_REPLACED"/>
|
||||
<data android:scheme="package" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
</application>
|
||||
</manifest>
|
||||
|
@ -58,7 +58,7 @@ dependencies {
|
||||
compile 'com.soundcloud.android:android-crop:0.9.10@aar'
|
||||
compile 'com.android.support:appcompat-v7:22.1.1'
|
||||
compile 'com.android.support:recyclerview-v7:21.0.3'
|
||||
compile 'com.melnykov:floatingactionbutton:1.1.0'
|
||||
compile 'com.melnykov:floatingactionbutton:1.3.0'
|
||||
compile 'com.google.zxing:android-integration:3.1.0'
|
||||
compile ('com.android.support:support-v4-preferencefragment:1.0.0@aar'){
|
||||
exclude module: 'support-v4'
|
||||
@ -80,6 +80,7 @@ dependencies {
|
||||
compile 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
|
||||
compile 'org.whispersystems:textsecure-android:1.8.1'
|
||||
compile 'com.h6ah4i.android.compat:mulsellistprefcompat:1.0.0'
|
||||
compile 'me.relex:circleindicator:1.0.0@aar'
|
||||
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile 'org.assertj:assertj-core:1.7.1'
|
||||
@ -118,7 +119,7 @@ dependencyVerification {
|
||||
'com.soundcloud.android:android-crop:ffd4b973cf6e97f7d64118a0dc088df50e9066fd5634fe6911dd0c0c5d346177',
|
||||
'com.android.support:appcompat-v7:9a2355537c2f01cf0b95523605c18606b8d824017e6e94a05c77b0cfc8f21c96',
|
||||
'com.android.support:recyclerview-v7:e525ad3f33c84bb12b73d2dc975b55364a53f0f2d0697e043efba59ba73e22d2',
|
||||
'com.melnykov:floatingactionbutton:0679ad9f7d61eb7aeab91e8dc56358cdedd5b1c1b9c48464499ffa05c40d3985',
|
||||
'com.melnykov:floatingactionbutton:15d58d4fac0f7a288d0e5301bbaf501a146f5b3f5921277811bf99bd3b397263',
|
||||
'com.google.zxing:android-integration:89e56aadf1164bd71e57949163c53abf90af368b51669c0d4a47a163335f95c4',
|
||||
'com.android.support:support-v4-preferencefragment:5470f5872514a6226fa1fc6f4e000991f38805691c534cf0bd2778911fc773ad',
|
||||
'com.android.support:gridlayout-v7:a9b770cffca2c7c5cd83cba4dd12503365de5e8d9c79c479165adf18ab3bc25b',
|
||||
@ -129,6 +130,7 @@ dependencyVerification {
|
||||
'org.whispersystems:libpastelog:550d33c565380d90f4c671e7b8ed5f3a6da55a9fda468373177106b2eb5220b2',
|
||||
'com.amulyakhare:com.amulyakhare.textdrawable:54c92b5fba38cfd316a07e5a30528068f45ce8515a6890f1297df4c401af5dcb',
|
||||
'com.h6ah4i.android.compat:mulsellistprefcompat:47167c5cb796de1a854788e9ff318358e36c8fb88123baaa6e38fb78511dfabe',
|
||||
'me.relex:circleindicator:996766d3dad51401331515e742948f2a10982d17c626edd976a246b9bf046aac',
|
||||
'com.nineoldandroids:library:68025a14e3e7673d6ad2f95e4b46d78d7d068343aa99256b686fe59de1b3163a',
|
||||
'javax.inject:javax.inject:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
|
||||
'com.madgag.spongycastle:core:8d6240b974b0aca4d3da9c7dd44d42339d8a374358aca5fc98e50a995764511f',
|
||||
|
BIN
res/drawable-xxhdpi/splash_logo.png
Normal file
BIN
res/drawable-xxhdpi/splash_logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
BIN
res/drawable-xxxhdpi/ic_arrow_forward_white_24dp.png
Normal file
BIN
res/drawable-xxxhdpi/ic_arrow_forward_white_24dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 509 B |
49
res/layout/color_fragment.xml
Normal file
49
res/layout/color_fragment.xml
Normal file
@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:background="#FF2090ea">
|
||||
|
||||
<TextView android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:id="@+id/blurb"
|
||||
android:textSize="34sp"
|
||||
android:textIsSelectable="false"
|
||||
android:gravity="center_horizontal|bottom"
|
||||
android:paddingLeft="20dp"
|
||||
android:paddingRight="20dp"
|
||||
android:fontFamily="sans-serif-light"
|
||||
tools:text="@string/ExperienceUpgradeActivity_welcome_to_signal"
|
||||
android:textColor="@android:color/white" />
|
||||
|
||||
<ImageView android:id="@+id/watermark"
|
||||
android:layout_width="@dimen/onboarding_watermark_size"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="2"
|
||||
android:maxHeight="@dimen/onboarding_watermark_size"
|
||||
android:scaleType="fitCenter"
|
||||
tools:src="@drawable/splash_logo"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_below="@id/blurb"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:layout_marginTop="@dimen/onboarding_margin_vert" />
|
||||
|
||||
<TextView android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="3"
|
||||
android:id="@+id/subblurb"
|
||||
android:textSize="20sp"
|
||||
android:textIsSelectable="false"
|
||||
android:gravity="center_horizontal"
|
||||
android:layout_marginTop="20dp"
|
||||
android:paddingLeft="20dp"
|
||||
android:paddingRight="20dp"
|
||||
android:fontFamily="sans-serif-light"
|
||||
tools:text="@string/ExperienceUpgradeActivity_textsecure_is_now_called_signal"
|
||||
android:textColor="@android:color/white" />
|
||||
|
||||
</LinearLayout>
|
44
res/layout/experience_upgrade_activity.xml
Normal file
44
res/layout/experience_upgrade_activity.xml
Normal file
@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:fab="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/container"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.v4.view.ViewPager
|
||||
android:id="@+id/pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<Button android:id="@+id/continue_button"
|
||||
android:layout_width="140sp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="continue"
|
||||
android:visibility="invisible"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_centerHorizontal="true" />
|
||||
|
||||
<me.relex.circleindicator.CircleIndicator
|
||||
android:id="@+id/indicator"
|
||||
android:layout_gravity="bottom|center_horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_marginBottom="25dp"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
android:layout_height="40dp" />
|
||||
|
||||
<com.melnykov.fab.FloatingActionButton
|
||||
android:id="@+id/fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|right"
|
||||
android:layout_margin="25dp"
|
||||
android:src="@drawable/ic_arrow_forward_white_24dp"
|
||||
android:focusable="true"
|
||||
android:contentDescription="@string/conversation_list_fragment__fab_content_description"
|
||||
fab:fab_shadow="false"
|
||||
fab:fab_colorNormal="#33000000"
|
||||
fab:fab_colorPressed="#66000000"
|
||||
fab:fab_colorRipple="#66000000" />
|
||||
</FrameLayout>
|
@ -1,9 +1,12 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<resources>
|
||||
<color name="textsecure_primary">#ff2090ea</color>
|
||||
<color name="textsecure_primary_dark">#ff1c7ac5</color>
|
||||
<color name="signal_primary">#ff2090ea</color>
|
||||
<color name="signal_primary_dark">#ff1c7ac5</color>
|
||||
<color name="signal_primary_alpha33">#552090ea</color>
|
||||
|
||||
<color name="textsecure_primary_alpha33">#552090ea</color>
|
||||
<color name="textsecure_primary">@color/signal_primary</color>
|
||||
<color name="textsecure_primary_dark">@color/signal_primary_dark</color>
|
||||
<color name="textsecure_primary_alpha33">@color/signal_primary_alpha33</color>
|
||||
|
||||
<color name="white">#ffffffff</color>
|
||||
<color name="black">#ff000000</color>
|
||||
|
@ -55,4 +55,8 @@
|
||||
holding the phone, *before* moving it up to your face and having
|
||||
the prox sensor kick in.) -->
|
||||
<dimen name="button_cluster_side_padding">20dp</dimen>
|
||||
|
||||
<dimen name="onboarding_margin_vert">35dp</dimen>
|
||||
<dimen name="onboarding_margin_land">20dp</dimen>
|
||||
<dimen name="onboarding_watermark_size">140dp</dimen>
|
||||
</resources>
|
||||
|
@ -187,6 +187,12 @@
|
||||
<!-- ShareActivity -->
|
||||
<string name="ShareActivity_share_with">Share with</string>
|
||||
|
||||
<!-- ExperienceUpgradeActivity -->
|
||||
<string name="ExperienceUpgradeActivity_welcome_to_signal_dgaf">Welcome to Signal.</string>
|
||||
<string name="ExperienceUpgradeActivity_textsecure_is_now_called_signal">TextSecure and RedPhone are now one private messenger, for every situation: Signal.</string>
|
||||
<string name="ExperienceUpgradeActivity_welcome_to_signal_excited">Welcome to Signal!</string>
|
||||
<string name="ExperienceUpgradeActivity_textsecure_is_now_signal">TextSecure is now Signal.</string>
|
||||
<string name="ExperienceUpgradeActivity_textsecure_is_now_signal_long">TextSecure and RedPhone are now one app: Signal. Tap to explore.</string>
|
||||
<!-- ExportFragment -->
|
||||
<string name="ExportFragment_export">Export</string>
|
||||
<string name="ExportFragment_export_plaintext_to_sd_card">Export plaintext to SD card?</string>
|
||||
|
54
src/org/thoughtcrime/securesms/BasicIntroFragment.java
Normal file
54
src/org/thoughtcrime/securesms/BasicIntroFragment.java
Normal file
@ -0,0 +1,54 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class BasicIntroFragment extends Fragment {
|
||||
|
||||
private static final String ARG_DRAWABLE = "drawable";
|
||||
private static final String ARG_TEXT = "text";
|
||||
private static final String ARG_SUBTEXT = "subtext";
|
||||
|
||||
private int drawable;
|
||||
private int text;
|
||||
private int subtext;
|
||||
|
||||
public static BasicIntroFragment newInstance(int drawable, int text, int subtext) {
|
||||
BasicIntroFragment fragment = new BasicIntroFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ARG_DRAWABLE, drawable);
|
||||
args.putInt(ARG_TEXT, text);
|
||||
args.putInt(ARG_SUBTEXT, subtext);
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
public BasicIntroFragment() {}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (getArguments() != null) {
|
||||
drawable = getArguments().getInt(ARG_DRAWABLE);
|
||||
text = getArguments().getInt(ARG_TEXT );
|
||||
subtext = getArguments().getInt(ARG_SUBTEXT );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.color_fragment, container, false);
|
||||
|
||||
((ImageView)v.findViewById(R.id.watermark)).setImageResource(drawable);
|
||||
((TextView)v.findViewById(R.id.blurb)).setText(text);
|
||||
((TextView)v.findViewById(R.id.subblurb)).setText(subtext);
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
224
src/org/thoughtcrime/securesms/ExperienceUpgradeActivity.java
Normal file
224
src/org/thoughtcrime/securesms/ExperienceUpgradeActivity.java
Normal file
@ -0,0 +1,224 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Build;
|
||||
import android.os.Build.VERSION_CODES;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
|
||||
import com.melnykov.fab.FloatingActionButton;
|
||||
import com.nineoldandroids.animation.ArgbEvaluator;
|
||||
|
||||
import org.thoughtcrime.securesms.IntroPagerAdapter.IntroPage;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.whispersystems.libaxolotl.util.guava.Optional;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import me.relex.circleindicator.CircleIndicator;
|
||||
|
||||
public class ExperienceUpgradeActivity extends BaseActionBarActivity {
|
||||
private static final String TAG = ExperienceUpgradeActivity.class.getSimpleName();
|
||||
private static final int NOTIFICATION_ID = 1339;
|
||||
|
||||
private enum ExperienceUpgrade {
|
||||
SIGNAL_REBRANDING(155,
|
||||
new IntroPage(0xFF2090EA,
|
||||
BasicIntroFragment.newInstance(R.drawable.splash_logo,
|
||||
R.string.ExperienceUpgradeActivity_welcome_to_signal_dgaf,
|
||||
R.string.ExperienceUpgradeActivity_textsecure_is_now_called_signal)),
|
||||
R.string.ExperienceUpgradeActivity_welcome_to_signal_excited,
|
||||
R.string.ExperienceUpgradeActivity_textsecure_is_now_signal,
|
||||
R.string.ExperienceUpgradeActivity_textsecure_is_now_signal_long);
|
||||
|
||||
private int version;
|
||||
private List<IntroPage> pages;
|
||||
private @StringRes int notificationTitle;
|
||||
private @StringRes int notificationText;
|
||||
private @StringRes int notificationBigText;
|
||||
|
||||
ExperienceUpgrade(int version,
|
||||
@NonNull List<IntroPage> pages,
|
||||
@StringRes int notificationTitle,
|
||||
@StringRes int notificationText,
|
||||
@StringRes int notificationBigText)
|
||||
{
|
||||
this.version = version;
|
||||
this.pages = pages;
|
||||
this.notificationTitle = notificationTitle;
|
||||
this.notificationText = notificationText;
|
||||
this.notificationBigText = notificationBigText;
|
||||
}
|
||||
|
||||
ExperienceUpgrade(int version,
|
||||
@NonNull IntroPage page,
|
||||
@StringRes int notificationTitle,
|
||||
@StringRes int notificationText,
|
||||
@StringRes int notificationBigText)
|
||||
{
|
||||
this(version, Collections.singletonList(page), notificationTitle, notificationText, notificationBigText);
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public List<IntroPage> getPages() {
|
||||
return pages;
|
||||
}
|
||||
|
||||
public IntroPage getPage(int i) {
|
||||
return pages.get(i);
|
||||
}
|
||||
|
||||
public int getNotificationTitle() {
|
||||
return notificationTitle;
|
||||
}
|
||||
|
||||
public int getNotificationText() {
|
||||
return notificationText;
|
||||
}
|
||||
|
||||
public int getNotificationBigText() {
|
||||
return notificationBigText;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setStatusBarColor(getResources().getColor(R.color.signal_primary_dark));
|
||||
|
||||
Optional<ExperienceUpgrade> upgrade = getExperienceUpgrade(this);
|
||||
if (!upgrade.isPresent()) {
|
||||
onContinue();
|
||||
return;
|
||||
}
|
||||
|
||||
setContentView(R.layout.experience_upgrade_activity);
|
||||
final ViewPager pager = ViewUtil.findById(this, R.id.pager);
|
||||
final CircleIndicator indicator = ViewUtil.findById(this, R.id.indicator);
|
||||
final FloatingActionButton fab = ViewUtil.findById(this, R.id.fab);
|
||||
|
||||
pager.setAdapter(new IntroPagerAdapter(getSupportFragmentManager(), upgrade.get().getPages()));
|
||||
|
||||
if (upgrade.get().getPages().size() > 1) {
|
||||
indicator.setViewPager(pager);
|
||||
indicator.setOnPageChangeListener(new OnPageChangeListener(upgrade.get()));
|
||||
} else {
|
||||
indicator.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
fab.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onContinue();
|
||||
}
|
||||
});
|
||||
|
||||
getWindow().setBackgroundDrawable(new ColorDrawable(upgrade.get().getPage(0).backgroundColor));
|
||||
ServiceUtil.getNotificationManager(this).cancel(NOTIFICATION_ID);
|
||||
}
|
||||
|
||||
@TargetApi(VERSION_CODES.LOLLIPOP)
|
||||
private void setStatusBarColor(int color) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
getWindow().setStatusBarColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
private void onContinue() {
|
||||
TextSecurePreferences.setLastExperienceVersionCode(this, Util.getCurrentApkReleaseVersion(this));
|
||||
startActivity((Intent)getIntent().getParcelableExtra("next_intent"));
|
||||
finish();
|
||||
}
|
||||
|
||||
public static boolean isUpdate(Context context) {
|
||||
return getExperienceUpgrade(context).isPresent();
|
||||
}
|
||||
|
||||
public static Optional<ExperienceUpgrade> getExperienceUpgrade(Context context) {
|
||||
final int currentVersionCode = Util.getCurrentApkReleaseVersion(context);
|
||||
final int lastSeenVersion = TextSecurePreferences.getLastExperienceVersionCode(context);
|
||||
Log.w(TAG, "getExperienceUpgrade(" + lastSeenVersion + ")");
|
||||
|
||||
if (lastSeenVersion >= currentVersionCode || lastSeenVersion == 0) {
|
||||
TextSecurePreferences.setLastExperienceVersionCode(context, currentVersionCode);
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
Optional<ExperienceUpgrade> eligibleUpgrade = Optional.absent();
|
||||
for (ExperienceUpgrade upgrade : ExperienceUpgrade.values()) {
|
||||
if (lastSeenVersion < upgrade.getVersion()) eligibleUpgrade = Optional.of(upgrade);
|
||||
}
|
||||
|
||||
return eligibleUpgrade;
|
||||
}
|
||||
|
||||
private final class OnPageChangeListener implements ViewPager.OnPageChangeListener {
|
||||
private final ArgbEvaluator evaluator = new ArgbEvaluator();
|
||||
private final ExperienceUpgrade upgrade;
|
||||
|
||||
public OnPageChangeListener(ExperienceUpgrade upgrade) {
|
||||
this.upgrade = upgrade;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position) {}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {}
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
final int nextPosition = (position + 1) % upgrade.getPages().size();
|
||||
|
||||
final int color = (Integer)evaluator.evaluate(positionOffset,
|
||||
upgrade.getPage(position).backgroundColor,
|
||||
upgrade.getPage(nextPosition).backgroundColor);
|
||||
getWindow().setBackgroundDrawable(new ColorDrawable(color));
|
||||
}
|
||||
}
|
||||
|
||||
public static class AppUpgradeReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if(Intent.ACTION_PACKAGE_REPLACED.equals(intent.getAction()) &&
|
||||
intent.getData().getSchemeSpecificPart().equals(context.getPackageName()))
|
||||
{
|
||||
Optional<ExperienceUpgrade> experienceUpgrade = getExperienceUpgrade(context);
|
||||
if (!experienceUpgrade.isPresent()) return;
|
||||
|
||||
Intent targetIntent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
|
||||
Notification notification = new NotificationCompat.Builder(context)
|
||||
.setSmallIcon(R.drawable.icon_notification)
|
||||
.setColor(context.getResources().getColor(R.color.signal_primary))
|
||||
.setContentTitle(context.getString(experienceUpgrade.get().getNotificationTitle()))
|
||||
.setContentText(context.getString(experienceUpgrade.get().getNotificationText()))
|
||||
.setStyle(new NotificationCompat.BigTextStyle().bigText(context.getString(experienceUpgrade.get().getNotificationBigText())))
|
||||
.setAutoCancel(true)
|
||||
.setContentIntent(PendingIntent.getActivity(context, 0,
|
||||
targetIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT))
|
||||
.build();
|
||||
ServiceUtil.getNotificationManager(context).notify(NOTIFICATION_ID, notification);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
38
src/org/thoughtcrime/securesms/IntroPagerAdapter.java
Normal file
38
src/org/thoughtcrime/securesms/IntroPagerAdapter.java
Normal file
@ -0,0 +1,38 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentStatePagerAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class IntroPagerAdapter extends FragmentStatePagerAdapter {
|
||||
|
||||
public static class IntroPage {
|
||||
final int backgroundColor;
|
||||
final Fragment fragment;
|
||||
|
||||
public IntroPage(int backgroundColor, Fragment fragment) {
|
||||
this.backgroundColor = backgroundColor;
|
||||
this.fragment = fragment;
|
||||
}
|
||||
}
|
||||
|
||||
private List<IntroPage> pages;
|
||||
|
||||
public IntroPagerAdapter(FragmentManager fm, List<IntroPage> pages) {
|
||||
super(fm);
|
||||
this.pages = pages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int i) {
|
||||
IntroPage page = pages.get(i);
|
||||
return page.fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return pages.size();
|
||||
}
|
||||
}
|
@ -31,6 +31,7 @@ public abstract class PassphraseRequiredActionBarActivity extends BaseActionBarA
|
||||
private static final int STATE_PROMPT_PASSPHRASE = 2;
|
||||
private static final int STATE_UPGRADE_DATABASE = 3;
|
||||
private static final int STATE_PROMPT_PUSH_REGISTRATION = 4;
|
||||
private static final int STATE_EXPERIENCE_UPGRADE = 5;
|
||||
|
||||
private BroadcastReceiver clearKeyReceiver;
|
||||
private boolean isVisible;
|
||||
@ -128,17 +129,20 @@ public abstract class PassphraseRequiredActionBarActivity extends BaseActionBarA
|
||||
Log.w(TAG, "routeApplicationState(), state: " + state);
|
||||
|
||||
switch (state) {
|
||||
case STATE_CREATE_PASSPHRASE: return getCreatePassphraseIntent();
|
||||
case STATE_PROMPT_PASSPHRASE: return getPromptPassphraseIntent();
|
||||
case STATE_UPGRADE_DATABASE: return getUpgradeDatabaseIntent(masterSecret);
|
||||
case STATE_PROMPT_PUSH_REGISTRATION: return getPushRegistrationIntent(masterSecret);
|
||||
default: return null;
|
||||
case STATE_CREATE_PASSPHRASE: return getCreatePassphraseIntent();
|
||||
case STATE_PROMPT_PASSPHRASE: return getPromptPassphraseIntent();
|
||||
case STATE_UPGRADE_DATABASE: return getUpgradeDatabaseIntent(masterSecret);
|
||||
case STATE_PROMPT_PUSH_REGISTRATION: return getPushRegistrationIntent(masterSecret);
|
||||
case STATE_EXPERIENCE_UPGRADE: return getExperienceUpgradeIntent();
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
private int getApplicationState(MasterSecret masterSecret) {
|
||||
if (!MasterSecretUtil.isPassphraseInitialized(this)) {
|
||||
return STATE_CREATE_PASSPHRASE;
|
||||
} else if (ExperienceUpgradeActivity.isUpdate(this)) {
|
||||
return STATE_EXPERIENCE_UPGRADE;
|
||||
} else if (masterSecret == null) {
|
||||
return STATE_PROMPT_PASSPHRASE;
|
||||
} else if (DatabaseUpgradeActivity.isUpdate(this)) {
|
||||
@ -166,6 +170,10 @@ public abstract class PassphraseRequiredActionBarActivity extends BaseActionBarA
|
||||
masterSecret);
|
||||
}
|
||||
|
||||
private Intent getExperienceUpgradeIntent() {
|
||||
return getRoutedIntent(ExperienceUpgradeActivity.class, getIntent(), null);
|
||||
}
|
||||
|
||||
private Intent getPushRegistrationIntent(MasterSecret masterSecret) {
|
||||
return getRoutedIntent(RegistrationActivity.class, getConversationListIntent(), masterSecret);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.thoughtcrime.securesms.util;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.view.WindowManager;
|
||||
@ -18,4 +19,8 @@ public class ServiceUtil {
|
||||
public static ConnectivityManager getConnectivityManager(Context context) {
|
||||
return (ConnectivityManager) context.getSystemService(Activity.CONNECTIVITY_SERVICE);
|
||||
}
|
||||
|
||||
public static NotificationManager getNotificationManager(Context context) {
|
||||
return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ public class TextSecurePreferences {
|
||||
public static final String ENABLE_MANUAL_MMS_PREF = "pref_enable_manual_mms";
|
||||
|
||||
private static final String LAST_VERSION_CODE_PREF = "last_version_code";
|
||||
private static final String LAST_EXPERIENCE_VERSION_PREF = "last_experience_version_code";
|
||||
public static final String RINGTONE_PREF = "pref_key_ringtone";
|
||||
private static final String VIBRATE_PREF = "pref_key_vibrate";
|
||||
private static final String NOTIFICATION_PREF = "pref_key_enable_notifications";
|
||||
@ -342,7 +343,15 @@ public class TextSecurePreferences {
|
||||
if (!setIntegerPrefrenceBlocking(context, LAST_VERSION_CODE_PREF, versionCode)) {
|
||||
throw new IOException("couldn't write version code to sharedpreferences");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int getLastExperienceVersionCode(Context context) {
|
||||
return getIntegerPreference(context, LAST_EXPERIENCE_VERSION_PREF, 0);
|
||||
}
|
||||
|
||||
public static void setLastExperienceVersionCode(Context context, int versionCode) {
|
||||
setIntegerPrefrence(context, LAST_EXPERIENCE_VERSION_PREF, versionCode);
|
||||
}
|
||||
|
||||
public static String getTheme(Context context) {
|
||||
return getStringPreference(context, THEME_PREF, "light");
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
package org.thoughtcrime.securesms.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.app.Activity;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build.VERSION;
|
||||
import android.os.Build.VERSION_CODES;
|
||||
@ -72,6 +72,11 @@ public class ViewUtil {
|
||||
return (T) parent.findViewById(resId);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends View> T findById(@NonNull Activity parent, @IdRes int resId) {
|
||||
return (T) parent.findViewById(resId);
|
||||
}
|
||||
|
||||
private static Animation getAlphaAnimation(float from, float to, int duration) {
|
||||
final Animation anim = new AlphaAnimation(from, to);
|
||||
anim.setInterpolator(new FastOutSlowInInterpolator());
|
||||
|
Loading…
x
Reference in New Issue
Block a user