Added storage permissions request, refactored MainActivity (fixes #483).

This commit is contained in:
Felix Ableitner 2015-11-13 23:49:46 +01:00
parent 53cb57b986
commit 7b67325fd4
2 changed files with 108 additions and 67 deletions

View File

@ -1,7 +1,7 @@
package com.nutomic.syncthingandroid.activities; package com.nutomic.syncthingandroid.activities;
import android.Manifest;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.ComponentName; import android.content.ComponentName;
@ -14,10 +14,14 @@ import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.design.widget.TabLayout; import android.support.design.widget.TabLayout;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.GravityCompat;
import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout; import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
@ -25,13 +29,13 @@ import android.support.v7.app.ActionBarDrawerToggle;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.Log; import android.util.Log;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Gravity;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import com.nutomic.syncthingandroid.R; import com.nutomic.syncthingandroid.R;
import com.nutomic.syncthingandroid.fragments.DeviceListFragment; import com.nutomic.syncthingandroid.fragments.DeviceListFragment;
@ -40,6 +44,7 @@ import com.nutomic.syncthingandroid.fragments.FolderListFragment;
import com.nutomic.syncthingandroid.syncthing.RestApi; import com.nutomic.syncthingandroid.syncthing.RestApi;
import com.nutomic.syncthingandroid.syncthing.SyncthingService; import com.nutomic.syncthingandroid.syncthing.SyncthingService;
import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -62,70 +67,82 @@ public class MainActivity extends SyncthingActivity
*/ */
private static final long USAGE_REPORTING_DIALOG_DELAY = TimeUnit.DAYS.toMillis(3); private static final long USAGE_REPORTING_DIALOG_DELAY = TimeUnit.DAYS.toMillis(3);
private AlertDialog mLoadingDialog; private static final int REQUEST_WRITE_STORAGE = 142;
private AlertDialog mLoadingDialog;
private AlertDialog mDisabledDialog; private AlertDialog mDisabledDialog;
private ViewPager mViewPager;
private FolderListFragment mFolderListFragment;
private DeviceListFragment mDeviceListFragment;
private DrawerFragment mDrawerFragment;
private ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
private SharedPreferences mPreferences;
/** /**
* Causes population of folder and device lists, unlocks info drawer. * Handles various dialogs based on current state.
*/ */
@Override @Override
@SuppressLint("InflateParams")
public void onApiChange(SyncthingService.State currentState) { public void onApiChange(SyncthingService.State currentState) {
if (currentState == SyncthingService.State.ACTIVE && switch (currentState) {
new Date().getTime() > getFirstStartTime() + USAGE_REPORTING_DIALOG_DELAY && case INIT:
getApi().getUsageReportAccepted() == RestApi.UsageReportSetting.UNDECIDED) { mLoadingDialog.show();
showUsageReportingDialog();
} else if (currentState == SyncthingService.State.ERROR) {
finish();
} else if (currentState != SyncthingService.State.ACTIVE && !isFinishing()) {
if (currentState == SyncthingService.State.DISABLED) {
if (mLoadingDialog != null) {
mLoadingDialog.dismiss();
mLoadingDialog = null;
}
mDisabledDialog = SyncthingService.showDisabledDialog(MainActivity.this);
} else if (mLoadingDialog == null) {
LayoutInflater inflater = getLayoutInflater();
View dialogLayout = inflater.inflate(R.layout.dialog_loading, null);
TextView loadingText = (TextView) dialogLayout.findViewById(R.id.loading_text);
loadingText.setText((getService().isFirstStart())
? R.string.web_gui_creating_key
: R.string.api_loading);
mLoadingDialog = new AlertDialog.Builder(MainActivity.this)
.setCancelable(false)
.setView(dialogLayout)
.show();
final SharedPreferences sp =
PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
// Make sure the first start dialog is shown on top. // Make sure the first start dialog is shown on top.
if (sp.getBoolean("first_start", true)) { if (isFirstStart()) {
showFirstStartDialog(sp); showFirstStartDialog();
} }
break;
case STARTING:
mLoadingDialog.show();
dismissDisabledDialog();
int permissionState = ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permissionState != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_WRITE_STORAGE);
} }
return; break;
} case ACTIVE:
mLoadingDialog.hide();
if (mLoadingDialog != null) { dismissDisabledDialog();
mLoadingDialog.dismiss();
mLoadingDialog = null;
}
if (mDisabledDialog != null) {
mDisabledDialog.dismiss();
mDisabledDialog = null;
}
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED); mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
mDrawerFragment.requestGuiUpdate(); mDrawerFragment.requestGuiUpdate();
if (new Date().getTime() > getFirstStartTime() + USAGE_REPORTING_DIALOG_DELAY &&
getApi().getUsageReportAccepted() == RestApi.UsageReportSetting.UNDECIDED) {
showUsageReportingDialog();
}
break;
case ERROR:
finish();
break;
case DISABLED:
mLoadingDialog.hide();
if (!isFinishing()) {
mDisabledDialog = SyncthingService.showDisabledDialog(MainActivity.this);
}
break;
}
}
private void dismissDisabledDialog() {
if (mDisabledDialog != null) {
mDisabledDialog.cancel();
mDisabledDialog = null;
}
}
private boolean isFirstStart() {
return mPreferences.getBoolean("first_start", true);
} }
/** /**
* Returns the unix timestamp at which the app was first installed. * Returns the unix timestamp at which the app was first installed.
*/ */
@TargetApi(9)
private long getFirstStartTime() { private long getFirstStartTime() {
PackageManager pm = getPackageManager(); PackageManager pm = getPackageManager();
long firstInstallTime = 0; long firstInstallTime = 0;
@ -140,14 +157,14 @@ public class MainActivity extends SyncthingActivity
/** /**
* Displays information for first app start. * Displays information for first app start.
*/ */
private void showFirstStartDialog(final SharedPreferences sp) { private void showFirstStartDialog() {
new AlertDialog.Builder(MainActivity.this) new AlertDialog.Builder(MainActivity.this)
.setTitle(R.string.welcome_title) .setTitle(R.string.welcome_title)
.setMessage(R.string.welcome_text) .setMessage(R.string.welcome_text)
.setNeutralButton(android.R.string.ok, new DialogInterface.OnClickListener() { .setNeutralButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialogInterface, int i) { public void onClick(DialogInterface dialogInterface, int i) {
sp.edit().putBoolean("first_start", false).apply(); mPreferences.edit().putBoolean("first_start", false).apply();
} }
}) })
.show(); .show();
@ -186,18 +203,6 @@ public class MainActivity extends SyncthingActivity
} }
}; };
private FolderListFragment mFolderListFragment;
private DeviceListFragment mDeviceListFragment;
private DrawerFragment mDrawerFragment;
private ViewPager mViewPager;
private ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
/** /**
* Initializes tab navigation. * Initializes tab navigation.
*/ */
@ -205,6 +210,7 @@ public class MainActivity extends SyncthingActivity
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mViewPager = (ViewPager) findViewById(R.id.pager); mViewPager = (ViewPager) findViewById(R.id.pager);
@ -236,13 +242,27 @@ public class MainActivity extends SyncthingActivity
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
mDrawerLayout.setDrawerListener(mDrawerToggle); mDrawerLayout.setDrawerListener(mDrawerToggle);
setOptimalDrawerWidth(findViewById(R.id.drawer)); setOptimalDrawerWidth(findViewById(R.id.drawer));
LayoutInflater inflater = getLayoutInflater();
@SuppressLint("InflateParams")
View dialogLayout = inflater.inflate(R.layout.dialog_loading, null);
TextView loadingText = (TextView) dialogLayout.findViewById(R.id.loading_text);
loadingText.setText((isFirstStart())
? R.string.web_gui_creating_key
: R.string.api_loading);
mLoadingDialog = new AlertDialog.Builder(MainActivity.this)
.setCancelable(false)
.setView(dialogLayout)
.create();
} }
@Override @Override
public void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
if (mLoadingDialog != null) {
mLoadingDialog.dismiss(); mLoadingDialog.dismiss();
if (mDisabledDialog != null) {
mDisabledDialog.dismiss();
} }
if (getService() != null) { if (getService() != null) {
getService().unregisterOnApiChangeListener(this); getService().unregisterOnApiChangeListener(this);
@ -323,7 +343,7 @@ public class MainActivity extends SyncthingActivity
* Closes the drawer. Use when navigating away from activity. * Closes the drawer. Use when navigating away from activity.
*/ */
public void closeDrawer() { public void closeDrawer() {
mDrawerLayout.closeDrawer(Gravity.LEFT); mDrawerLayout.closeDrawer(GravityCompat.START);
} }
/** /**
@ -332,8 +352,8 @@ public class MainActivity extends SyncthingActivity
@Override @Override
public boolean onKeyDown(int keyCode, KeyEvent e) { public boolean onKeyDown(int keyCode, KeyEvent e) {
if (keyCode == KeyEvent.KEYCODE_MENU) { if (keyCode == KeyEvent.KEYCODE_MENU) {
if (!mDrawerLayout.isDrawerOpen(Gravity.LEFT)) if (!mDrawerLayout.isDrawerOpen(GravityCompat.START))
mDrawerLayout.openDrawer(Gravity.RIGHT); mDrawerLayout.openDrawer(GravityCompat.END);
else else
closeDrawer(); closeDrawer();
@ -399,11 +419,28 @@ public class MainActivity extends SyncthingActivity
.setView(v) .setView(v)
.setPositiveButton(R.string.yes, listener) .setPositiveButton(R.string.yes, listener)
.setNegativeButton(R.string.no, listener) .setNegativeButton(R.string.no, listener)
.setNeutralButton("Open Website", listener) .setNeutralButton(R.string.open_website, listener)
.setCancelable(false)
.show(); .show();
} }
}); });
} }
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_WRITE_STORAGE:
Log.d(TAG, Arrays.toString(grantResults));
if (grantResults.length == 0 ||
grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, R.string.toast_write_storage_permission_required,
Toast.LENGTH_LONG).show();
finish();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
} }

View File

@ -30,6 +30,10 @@
<string name="off">off</string> <string name="off">off</string>
<string name="open_website">Open Website</string>
<string name="toast_write_storage_permission_required">Write storage permission is required for this app</string>
<!-- FoldersFragment --> <!-- FoldersFragment -->