package com.github.andlyticsproject;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.graphics.PorterDuff;
import android.support.design.widget.NavigationView;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.widget.Toolbar;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.github.andlyticsproject.Preferences.StatsMode;
import com.github.andlyticsproject.Preferences.Timeframe;
import com.github.andlyticsproject.about.AboutActivity;
import com.github.andlyticsproject.adsense.AdSenseClient;
import com.github.andlyticsproject.console.v2.DevConsoleRegistry;
import com.github.andlyticsproject.console.v2.DevConsoleV2;
import com.github.andlyticsproject.db.AndlyticsDb;
import com.github.andlyticsproject.io.StatsCsvReaderWriter;
import com.github.andlyticsproject.model.AdmobStats;
import com.github.andlyticsproject.model.AppInfo;
import com.github.andlyticsproject.model.DeveloperAccount;
import com.github.andlyticsproject.sync.NotificationHandler;
import com.github.andlyticsproject.util.ChangelogBuilder;
import com.github.andlyticsproject.util.DetachableAsyncTask;
import com.github.andlyticsproject.util.Utils;
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Main extends BaseActivity implements AdapterView.OnItemSelectedListener,
SwipeRefreshLayout.OnRefreshListener, NavigationView.OnNavigationItemSelectedListener,
View.OnClickListener {
/** Key for latest version code preference. */
private static final String LAST_VERSION_CODE_KEY = "last_version_code";
public static final String TAG = Main.class.getSimpleName();
/** Dialog constant. **/
public static final int DIALOG_ABOUT_ID = 1;
private boolean cancelRequested;
private DrawerLayout mainDrawer;
private NavigationView navigationView;
private SwipeRefreshLayout swipeRefresh;
private ListView mainListView;
private TextView statusText;
private MainListAdapter adapter;
private View footer;
private StatsMode currentStatsMode;
private MenuItem statsModeMenuItem;
private List<DeveloperAccount> developerAccounts;
private DateFormat timeFormat = DateFormat.getTimeInstance(DateFormat.MEDIUM);
private static final int REQUEST_OPEN_DOCUMENT = 88;
private static final int REQUEST_CODE_MANAGE_ACCOUNTS = 99;
private static class State {
// TODO replace with loaders
LoadDbEntries loadDbEntries;
LoadRemoteEntries loadRemoteEntries;
LoadIconInCache loadIconInCache;
List<AppInfo> lastAppList;
void detachAll() {
if (loadDbEntries != null) {
loadDbEntries.detach();
}
if (loadRemoteEntries != null) {
loadRemoteEntries.detach();
}
if (loadIconInCache != null) {
loadIconInCache.detach();
}
}
void attachAll(Main activity) {
if (loadDbEntries != null) {
loadDbEntries.attach(activity);
}
if (loadRemoteEntries != null) {
loadRemoteEntries.attach(activity);
}
if (loadIconInCache != null) {
loadIconInCache.attach(activity);
}
}
void setLoadDbEntries(LoadDbEntries task) {
if (loadDbEntries != null) {
loadDbEntries.detach();
}
loadDbEntries = task;
}
void setLoadRemoteEntries(LoadRemoteEntries task) {
if (loadRemoteEntries != null) {
loadRemoteEntries.detach();
}
loadRemoteEntries = task;
}
void setLoadIconInCache(LoadIconInCache task) {
if (loadIconInCache != null) {
loadIconInCache.detach();
}
loadIconInCache = task;
}
}
private State state = new State();
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LayoutInflater layoutInflater = getLayoutInflater();
// setup Nav Drawer
mainDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
navigationView = (NavigationView) findViewById(R.id.navigation_view);
navigationView.setNavigationItemSelectedListener(this);
// setup toolbar
Toolbar mainToolbar = (Toolbar) findViewById(R.id.main_toolbar);
setSupportActionBar(mainToolbar);
ActionBar ab = getSupportActionBar();
ab.setHomeAsUpIndicator(R.drawable.icon_drawer_menu);
ab.setDisplayHomeAsUpEnabled(true);
mainToolbar.setBackgroundColor(getResources().getColor(R.color.lightBlue));
// BaseActivity has already selected the account
updateAccountsList();
// setup swipeRefreshLayou
swipeRefresh = (SwipeRefreshLayout) findViewById(R.id.swipeRefresh);
swipeRefresh.setColorSchemeResources(R.color.lightBlue);
swipeRefresh.setOnRefreshListener(this);
// setup main list
mainListView = (ListView) findViewById(R.id.main_app_list);
mainListView.addHeaderView(layoutInflater.inflate(R.layout.main_list_header, null), null,
false);
footer = layoutInflater.inflate(R.layout.main_list_footer, null);
footer.setVisibility(View.INVISIBLE);
mainListView.addFooterView(footer, null, false);
adapter = new MainListAdapter(this, accountName, currentStatsMode);
mainListView.setAdapter(adapter);
// status & progress bar
statusText = (TextView) findViewById(R.id.main_app_status_line);
currentStatsMode = Preferences.getStatsMode(this);
updateStatsMode();
State lastState = (State) getLastCustomNonConfigurationInstance();
if (lastState != null) {
state = lastState;
state.attachAll(this);
if (state.lastAppList != null) {
adapter.setAppInfos(state.lastAppList);
setSkipMainReload(true);
}
}
// show changelog
if (isUpdate()) {
showChangelog();
}
}
@Override
public void onRefresh() {
swipeRefresh.setEnabled(false);
loadRemoteEntries();
}
@Override
public void refreshStarted() {
super.refreshStarted();
if (!swipeRefresh.isRefreshing()) {
swipeRefresh.setRefreshing(true);
swipeRefresh.setEnabled(false);
}
}
@Override
public void refreshFinished() {
super.refreshFinished();
swipeRefresh.setRefreshing(false);
swipeRefresh.setEnabled(true);
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
switch (parent.getId()){
case R.id.account_selector:
if (!developerAccounts.get(position).getName().equals(accountName)) {
// Only switch if it is a new account
Intent intent = new Intent(this, Main.class);
intent.putExtra(BaseActivity.EXTRA_AUTH_ACCOUNT_NAME,
developerAccounts.get(position).getName());
startActivity(intent);
overridePendingTransition(R.anim.activity_fade_in, R.anim.activity_fade_out);
// Call finish to ensure we don't get multiple activities running
finish();
}
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// Do Nothing
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.manage_accounts:
Intent accountsIntent = new Intent(this, LoginActivity.class);
accountsIntent.putExtra(LoginActivity.EXTRA_MANAGE_ACCOUNTS_MODE, true);
startActivityForResult(accountsIntent, REQUEST_CODE_MANAGE_ACCOUNTS);
}
}
@Override
protected void onResume() {
super.onResume();
if (!isSkipMainReload() && shouldRemoteUpdateStats()) {
loadLocalEntriesAndUpdate();
} else {
loadLocalEntriesOnly();
}
setSkipMainReload(false);
AndlyticsApp.getInstance().setIsAppVisible(true);
}
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()){
case R.id.itemMainmenuImport:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Intent openIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
openIntent.setType("*/*");
openIntent.putExtra(Intent.EXTRA_MIME_TYPES, new String[] { "application/zip" });
//hidden
openIntent.putExtra("android.content.extra.SHOW_ADVANCED", true);
startActivityForResult(openIntent, REQUEST_OPEN_DOCUMENT);
} else {
File fileToImport = StatsCsvReaderWriter.getExportFileForAccount(accountName);
if (!fileToImport.exists()) {
Toast.makeText(
this,
getString(R.string.import_no_stats_file, fileToImport.getAbsolutePath()),
Toast.LENGTH_LONG).show();
return true;
}
Intent importIntent = new Intent(this, ImportActivity.class);
importIntent.setAction(Intent.ACTION_VIEW);
importIntent.setData(Uri.fromFile(fileToImport));
startActivity(importIntent);
}
break;
case R.id.itemMainmenuExport:
Intent exportIntent = new Intent(this, ExportActivity.class);
exportIntent.putExtra(ExportActivity.EXTRA_ACCOUNT_NAME, accountName);
startActivity(exportIntent);
break;
case R.id.itemMainmenuAbout:
// launch about activity
Intent aboutIntent = new Intent(this, AboutActivity.class);
startActivity(aboutIntent);
break;
case R.id.itemMainmenuPreferences:
Intent preferencesIntent = new Intent(this, AndlyticsPreferenceActivity.class);
preferencesIntent.putExtra(BaseActivity.EXTRA_AUTH_ACCOUNT_NAME, accountName);
startActivity(preferencesIntent);
break;
default:
return false;
}
return true;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.clear();
getMenuInflater().inflate(R.menu.main_menu, menu);
statsModeMenuItem = menu.findItem(R.id.itemMainmenuStatsMode);
if (isRefreshing())
menu.findItem(R.id.itemMainmenuRefresh).setActionView(
R.layout.action_bar_indeterminate_progress);
updateStatsMode();
return true;
}
/**
* Called if item in option menu is selected.
*
* @param item
* The chosen menu item
* @return boolean true/false
*/
@TargetApi(19)
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
mainDrawer.openDrawer(GravityCompat.START);
break;
case R.id.itemMainmenuRefresh:
loadRemoteEntries();
break;
case R.id.itemMainmenuStatsMode:
if (currentStatsMode.equals(StatsMode.PERCENT)) {
currentStatsMode = StatsMode.DAY_CHANGES;
} else {
currentStatsMode = StatsMode.PERCENT;
}
updateStatsMode();
break;
case R.id.itemMainmenuAccounts:
Intent accountsIntent = new Intent(this, LoginActivity.class);
accountsIntent.putExtra(LoginActivity.EXTRA_MANAGE_ACCOUNTS_MODE, true);
startActivityForResult(accountsIntent, REQUEST_CODE_MANAGE_ACCOUNTS);
break;
default:
return false;
}
return true;
}
@Override
public void onBackPressed() {
if (mainDrawer.isDrawerOpen(GravityCompat.START))
mainDrawer.closeDrawer(GravityCompat.START);
else
super.onBackPressed();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// NOTE startActivityForResult does not work when singleTask is set in
// the manifiest
// Therefore, FLAG_ACTIVITY_CLEAR_TOP is used on any intents instead.
if (requestCode == REQUEST_CODE_MANAGE_ACCOUNTS) {
if (resultCode == RESULT_OK) {
// Went to manage accounts, didn't do anything to the current
// account,
// but might have added/removed other accounts
updateAccountsList();
} else if (resultCode == RESULT_CANCELED) {
// The user removed the current account, remove it from
// preferences and finish
// so that the user has to choose an account when they next
// start the app
developerAccountManager.unselectDeveloperAccount();
finish();
}
} else if (requestCode == REQUEST_AUTHENTICATE) {
if (resultCode == RESULT_OK) {
// user entered credentials, etc, try to get data again
loadRemoteEntries();
} else {
Toast.makeText(this, getString(R.string.auth_error, accountName), Toast.LENGTH_LONG)
.show();
}
} else if (requestCode == REQUEST_GOOGLE_PLAY_SERVICES) {
if (resultCode == AppCompatActivity.RESULT_OK) {
} else {
checkGooglePlayServicesAvailable();
}
} else if (requestCode == REQUEST_AUTHORIZATION) {
if (resultCode == AppCompatActivity.RESULT_OK) {
loadRemoteEntries();
} else {
Toast.makeText(this, getString(R.string.account_authorization_denied, accountName),
Toast.LENGTH_LONG).show();
}
} else if (requestCode == REQUEST_OPEN_DOCUMENT) {
if (resultCode == RESULT_OK) {
Intent importIntent = new Intent(this, ImportActivity.class);
importIntent.setAction(Intent.ACTION_VIEW);
importIntent.setData(data.getData());
startActivity(importIntent);
} else {
Toast.makeText(
this,
getString(R.string.import_no_stats_file, data == null ? "" : data.getData()),
Toast.LENGTH_LONG).show();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
@Override
public Object onRetainCustomNonConfigurationInstance() {
state.lastAppList = adapter.getAppInfos();
state.detachAll();
return state;
}
@Override
protected void onPause() {
super.onPause();
AndlyticsApp.getInstance().setIsAppVisible(false);
}
@Override
protected void onDestroy() {
statsModeMenuItem = null;
super.onDestroy();
}
private void updateAccountsList() {
developerAccounts = developerAccountManager.getActiveDeveloperAccounts();
Spinner accountSelector = (Spinner) navigationView.findViewById(R.id.account_selector);
accountSelector.getBackground().setColorFilter(
getResources().getColor(R.color.primary_material_light), PorterDuff.Mode.SRC_ATOP);
AccountSelectorAdaper accountsAdapter = new AccountSelectorAdaper(this,
R.layout.account_selector_item, developerAccounts);
accountsAdapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
accountSelector.setAdapter(accountsAdapter);
accountSelector.setOnItemSelectedListener(this);
// Only use the spinner if we have multiple accounts
accountSelector.setEnabled(developerAccounts.size() > 1);
if (developerAccounts.size() > 1) {
int selectedIndex = 0;
int index = 0;
for (DeveloperAccount account : developerAccounts) {
if (account.getName().equals(accountName)) {
selectedIndex = index;
}
index++;
}
accountSelector.setSelection(selectedIndex);
}
navigationView.findViewById(R.id.manage_accounts).setOnClickListener(this);
}
private void updateMainList(List<AppInfo> apps) {
if (apps != null) {
if (apps.size() > 0) {
footer.setVisibility(View.VISIBLE);
}
adapter.setAppInfos(apps);
adapter.notifyDataSetChanged();
Date lastUpdateDate = null;
for (int i = 0; i < apps.size(); i++) {
Date dateObject = apps.get(i).getLastUpdate();
if (lastUpdateDate == null || lastUpdateDate.before(dateObject)) {
lastUpdateDate = dateObject;
}
}
if (lastUpdateDate != null) {
statusText.setText(Preferences.getDateFormatLong(this).format(lastUpdateDate) + " "
+ timeFormat.format(lastUpdateDate));
}
}
if (!swipeRefresh.isRefreshing()) {
swipeRefresh.setRefreshing(false);
swipeRefresh.setEnabled(true);
}
findViewById(R.id.main_app_list_loading).setVisibility(View.GONE);
}
private static class LoadRemoteEntries extends
DetachableAsyncTask<String, Integer, Exception, Main> {
private ContentAdapter db;
public LoadRemoteEntries(Main activity) {
super(activity);
db = ContentAdapter.getInstance(activity.getApplication());
}
@Override
protected void onPreExecute() {
if (activity == null) {
return;
}
activity.refreshStarted();
}
@SuppressLint("NewApi")
@SuppressWarnings("unchecked")
@Override
protected Exception doInBackground(String... params) {
if (activity == null) {
return null;
}
Exception exception = null;
List<AppInfo> appDownloadInfos = null;
try {
DevConsoleV2 v2 = DevConsoleRegistry.getInstance().get(activity.accountName);
appDownloadInfos = v2.getAppInfo(activity);
if (activity.cancelRequested) {
activity.cancelRequested = false;
return null;
}
Map<String, List<String>> admobAccountSiteMap = new HashMap<String, List<String>>();
List<AppStatsDiff> diffs = new ArrayList<AppStatsDiff>();
for (AppInfo appDownloadInfo : appDownloadInfos) {
// update in database and check for diffs
// sets DB ID of ApInfo
diffs.add(db.insertOrUpdateStats(appDownloadInfo));
String[] admobDetails = AndlyticsDb.getInstance(activity).getAdmobDetails(
appDownloadInfo.getPackageName());
if (admobDetails != null) {
String admobAccount = admobDetails[0];
String admobSiteId = admobDetails[1];
String adUnitId = admobDetails[2];
if (admobAccount != null && adUnitId == null) {
List<String> siteList = admobAccountSiteMap.get(admobAccount);
if (siteList == null) {
siteList = new ArrayList<String>();
}
siteList.add(admobSiteId);
admobAccountSiteMap.put(admobAccount, siteList);
} else {
List<String> siteList = admobAccountSiteMap.get(admobAccount);
if (siteList == null) {
siteList = new ArrayList<String>();
}
siteList.add(adUnitId);
admobAccountSiteMap.put(admobAccount, siteList);
}
}
// update app details
AndlyticsDb.getInstance(activity).insertOrUpdateAppDetails(appDownloadInfo);
}
// check for notifications
NotificationHandler.handleNotificaions(activity, diffs, activity.accountName);
// sync admob accounts
Set<String> admobAccuntKeySet = admobAccountSiteMap.keySet();
for (String admobAccount : admobAccuntKeySet) {
AdSenseClient.foregroundSyncStats(activity, admobAccount,
admobAccountSiteMap.get(admobAccount));
}
activity.state.setLoadIconInCache(new LoadIconInCache(activity));
Utils.execute(activity.state.loadIconInCache, appDownloadInfos);
} catch (UserRecoverableAuthIOException userRecoverableException) {
activity.startActivityForResult(userRecoverableException.getIntent(),
REQUEST_AUTHORIZATION);
} catch (Exception e) {
// These exceptions can contain very long JSON strings
// Explicitly print out the root cause first
Log.e(TAG,
"Error while requesting developer console : " + Utils.stackTraceToString(e));
Log.e(TAG, "Error while requesting developer console : " + e.getMessage(), e);
exception = e;
}
return exception;
}
@Override
protected void onPostExecute(Exception exception) {
if (activity == null) {
return;
}
activity.refreshFinished();
if (exception == null) {
activity.developerAccountManager.saveLastStatsRemoteUpdateTime(
activity.accountName, System.currentTimeMillis());
activity.loadLocalEntriesOnly();
return;
}
activity.handleUserVisibleException(exception);
activity.loadLocalEntriesOnly();
}
}
private void loadLocalEntriesOnly() {
loadDbEntries(false);
}
private void loadLocalEntriesAndUpdate() {
loadDbEntries(true);
}
private void loadDbEntries(boolean triggerRemoteCall) {
state.setLoadDbEntries(new LoadDbEntries(this));
Utils.execute(state.loadDbEntries, triggerRemoteCall);
}
private static class LoadDbEntries extends DetachableAsyncTask<Boolean, Void, Boolean, Main> {
private ContentAdapter db;
LoadDbEntries(Main activity) {
super(activity);
db = ContentAdapter.getInstance(activity.getApplication());
}
private List<AppInfo> allStats = new ArrayList<AppInfo>();
private List<AppInfo> filteredStats = new ArrayList<AppInfo>();
private Boolean triggerRemoteCall;
@Override
protected Boolean doInBackground(Boolean... params) {
if (activity == null) {
return null;
}
allStats = db.getAllAppsLatestStats(activity.accountName);
for (AppInfo appInfo : allStats) {
if (!appInfo.isGhost()) {
if (appInfo.getAdmobSiteId() != null || appInfo.getAdmobAdUnitId() != null) {
List<AdmobStats> admobStats = db.getAdmobStats(appInfo.getAdmobSiteId(),
appInfo.getAdmobAdUnitId(), Timeframe.LAST_TWO_DAYS).getStats();
if (admobStats.size() > 0) {
AdmobStats admob = admobStats.get(admobStats.size() - 1);
appInfo.setAdmobStats(admob);
}
}
filteredStats.add(appInfo);
}
}
triggerRemoteCall = params[0];
return null;
}
@Override
protected void onPostExecute(Boolean result) {
if (activity == null) {
return;
}
activity.updateMainList(filteredStats);
if (triggerRemoteCall) {
activity.loadRemoteEntries();
} else {
if (allStats.isEmpty()) {
Toast.makeText(activity, R.string.no_published_apps, Toast.LENGTH_LONG).show();
}
}
}
}
private static class LoadIconInCache extends
DetachableAsyncTask<List<AppInfo>, Void, Boolean, Main> {
LoadIconInCache(Main activity) {
super(activity);
}
@Override
protected Boolean doInBackground(List<AppInfo>... params) {
if (activity == null) {
return null;
}
List<AppInfo> appInfos = params[0];
Boolean success = Boolean.FALSE;
for (AppInfo appInfo : appInfos) {
String iconUrl = appInfo.getIconUrl();
if (iconUrl != null) {
File iconFile = new File(activity.getCacheDir(), appInfo.getIconName());
if (!iconFile.exists()) {
try {
if (iconFile.createNewFile()) {
Utils.getAndSaveToFile(new URL(iconUrl), iconFile);
success = Boolean.TRUE;
}
} catch (IOException e) {
if (iconFile.exists()) {
iconFile.delete();
}
Log.d("log_tag", "Error: " + e);
}
}
}
}
return success;
}
@Override
protected void onPostExecute(Boolean success) {
if (activity == null) {
return;
}
if (success) {
activity.adapter.notifyDataSetChanged();
}
}
}
private void updateStatsMode() {
if (statsModeMenuItem != null) {
switch (currentStatsMode) {
case PERCENT:
statsModeMenuItem.setTitle(R.string.daily);
statsModeMenuItem.setIcon(R.drawable.icon_plusminus);
break;
case DAY_CHANGES:
statsModeMenuItem.setTitle(R.string.percentage);
statsModeMenuItem.setIcon(R.drawable.icon_percent);
break;
default:
break;
}
}
adapter.setStatsMode(currentStatsMode);
adapter.notifyDataSetChanged();
Preferences.saveStatsMode(currentStatsMode, Main.this);
}
private void loadRemoteEntries() {
state.setLoadRemoteEntries(new LoadRemoteEntries(this));
Utils.execute(state.loadRemoteEntries);
}
/**
* checks if the app is started for the first time (after an update).
*
* @return <code>true</code> if this is the first start (after an update)
* else <code>false</code>
*/
private boolean isUpdate() {
// Get the versionCode of the Package, which must be different
// (incremented) in each release on the market in the
// AndroidManifest.xml
final int versionCode = Utils.getActualVersionCode(this);
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
final long lastVersionCode = prefs.getLong(LAST_VERSION_CODE_KEY, 0);
// don't show popup on first install, creates weird interaction with
// authorization popup from GLS
if (lastVersionCode == 0) {
return false;
}
if (versionCode != lastVersionCode) {
Log.i(TAG, "versionCode " + versionCode + " is different from the last known version "
+ lastVersionCode);
return true;
} else {
Log.i(TAG, "versionCode " + versionCode + " is already known");
return false;
}
}
private void showChangelog() {
final int versionCode = Utils.getActualVersionCode(this);
final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
ChangelogBuilder.create(this, new Dialog.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int i) {
// Mark this version as read
sp.edit().putLong(LAST_VERSION_CODE_KEY, versionCode).commit();
dialogInterface.dismiss();
}
}).show();
}
private static class AccountSelectorAdaper extends ArrayAdapter<DeveloperAccount> {
private Context context;
private List<DeveloperAccount> accounts;
private int textViewResourceId;
public AccountSelectorAdaper(Context context, int textViewResourceId,
List<DeveloperAccount> objects) {
super(context, textViewResourceId, objects);
this.context = context;
this.accounts = objects;
this.textViewResourceId = textViewResourceId;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(textViewResourceId, parent, false);
}
TextView subtitle = (TextView) rowView.findViewById(android.R.id.text1);
subtitle.setText(accounts.get(position).getName());
Resources res = context.getResources();
if (res.getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
// Scale the text down slightly to fit on landscape due to the
// shorter Action Bar
// and additional padding due to the drop down
// We don't use predefined values as it saves duplicating all of
// the different display
// configuration values from the ABS library
float px = subtitle.getTextSize() * 0.9f;
subtitle.setTextSize(px / (res.getDisplayMetrics().densityDpi / 160f));
}
// TODO In the future when accounts linked to multiple developer
// consoles are supported
// we can either merge all the apps together, or extend this adapter
// to let the user select
// account/console E.g:
// account1
// account2/console1
// account2/console2
// ...
return rowView;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
View result = super.getDropDownView(position, convertView, parent);
((TextView) result).setText(accounts.get(position).getName());
return result;
}
}
}