From eef29d26c8e533e35a0b6eed2e80551cdbcdc426 Mon Sep 17 00:00:00 2001 From: Stefan Heinze Date: Thu, 15 May 2014 11:29:10 +0200 Subject: [PATCH 01/21] erste Version mit synchronisation mit der app --- .../app/src/main/AndroidManifest.xml | 38 ++++- .../android/projectiler/app/ListProvider.java | 133 ++++++++++++++++ .../android/projectiler/app/MainActivity.java | 147 ++++++++++++------ .../app/ProjectNameIntentService.java | 46 ++++++ .../projectiler/app/ProjectilerAppWidget.java | 132 ++++++++++++++++ .../projectiler/app/ResetIntentService.java | 38 +++++ .../projectiler/app/StartIntentService.java | 55 +++++++ .../projectiler/app/StopIntentService.java | 68 ++++++++ .../projectiler/app/WidgetService.java | 87 +++++++++++ .../projectiler/app/backend/Projectiler.java | 8 + .../app/backend/UserDataStore.java | 16 ++ .../projectiler/app/utils/WidgetUtils.java | 35 +++++ .../example_appwidget_preview.png | Bin 0 -> 3522 bytes .../res/layout/adapter_navigation_drawer.xml | 2 + .../res/layout/projectiler_app_widget.xml | 80 ++++++++++ .../app/src/main/res/values-v14/dimens.xml | 10 ++ .../app/src/main/res/values/dimens.xml | 11 +- .../app/src/main/res/values/strings.xml | 2 + .../res/xml/projectiler_app_widget_info.xml | 11 ++ 19 files changed, 860 insertions(+), 59 deletions(-) create mode 100644 ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/ListProvider.java create mode 100644 ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/ProjectNameIntentService.java create mode 100644 ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/ProjectilerAppWidget.java create mode 100644 ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/ResetIntentService.java create mode 100644 ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/StartIntentService.java create mode 100644 ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/StopIntentService.java create mode 100644 ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/WidgetService.java create mode 100644 ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/utils/WidgetUtils.java create mode 100644 ProjectilerApp/Projectiler/app/src/main/res/drawable-nodpi/example_appwidget_preview.png create mode 100644 ProjectilerApp/Projectiler/app/src/main/res/layout/projectiler_app_widget.xml create mode 100644 ProjectilerApp/Projectiler/app/src/main/res/values-v14/dimens.xml create mode 100644 ProjectilerApp/Projectiler/app/src/main/res/xml/projectiler_app_widget_info.xml diff --git a/ProjectilerApp/Projectiler/app/src/main/AndroidManifest.xml b/ProjectilerApp/Projectiler/app/src/main/AndroidManifest.xml index 604c565..e8e6fa9 100644 --- a/ProjectilerApp/Projectiler/app/src/main/AndroidManifest.xml +++ b/ProjectilerApp/Projectiler/app/src/main/AndroidManifest.xml @@ -9,7 +9,9 @@ android:name="android.hardware.nfc" android:required="true" /> - + - - + - + + + + + + + + + + + + + + + + + + diff --git a/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/ListProvider.java b/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/ListProvider.java new file mode 100644 index 0000000..463822e --- /dev/null +++ b/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/ListProvider.java @@ -0,0 +1,133 @@ +package de.saxsys.android.projectiler.app; + +import android.appwidget.AppWidgetManager; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.widget.RemoteViews; +import android.widget.RemoteViewsService; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by stefan.heinze on 14.05.2014. + */ +public class ListProvider implements RemoteViewsService.RemoteViewsFactory { + public static final String EXTRA_LIST_VIEW_ROW_NUMBER = "List_Row_Number"; + private ArrayList listItemList = new ArrayList(); + private Context context = null; + private int appWidgetId; + private List projectNames; + + public ListProvider(Context context, Intent intent, List projects) { + this.context = context; + appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, + AppWidgetManager.INVALID_APPWIDGET_ID); + + populateListItem(projects); + } + + private void populateListItem(List projects) { + this.projectNames = projects; + for (int i = 0; i < projectNames.size(); i++) { + List listItem = new ArrayList(); + + listItem.add(projectNames.get(i)); + + listItemList.add(listItem); + + + + } + + + } + + @Override + public void onCreate() { + + } + + @Override + public void onDataSetChanged() { + + } + + @Override + public void onDestroy() { + + } + + @Override + public int getCount() { + return listItemList.size(); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public boolean hasStableIds() { + return false; + } + + /* + *Similar to getView of Adapter where instead of View + *we return RemoteViews + * + */ + @Override + public RemoteViews getViewAt(int position) { + + Log.i("Listprovider", "getViewAt " + position); + + final RemoteViews remoteView = new RemoteViews( + context.getPackageName(), R.layout.adapter_navigation_drawer); + //ListItem listItem = listItemList.get(position); + remoteView.setTextViewText(R.id.tv_project_name, projectNames.get(position)); +/* + Intent i = new Intent(); + Bundle extras = new Bundle(); + + extras.putInt(EXTRA_LIST_VIEW_ROW_NUMBER, position); + i.putExtras(extras); + remoteView.setOnClickFillInIntent(R.id.rl_widget, i); +*/ + + final Intent fillInIntent = new Intent(); + final Bundle extras = new Bundle(); + extras.putString(ProjectilerAppWidget.EXTRA_PROJECT_NAME, projectNames.get(position)); + fillInIntent.putExtras(extras); + remoteView.setOnClickFillInIntent(R.id.rl_widget, fillInIntent); + + + + return remoteView; + } + + @Override + public RemoteViews getLoadingView() { + return null; + } + + @Override + public int getViewTypeCount() { + return 1; + } + + + private void notifyWidget(){ + Intent intent = new Intent(context, ProjectilerAppWidget.class); + intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); + // Use an array and EXTRA_APPWIDGET_IDS instead of AppWidgetManager.EXTRA_APPWIDGET_ID, + // since it seems the onUpdate() is only fired on that: + int[] appWidgetIds = {appWidgetId}; + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds); + context.sendBroadcast(intent); + } + +} diff --git a/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/MainActivity.java b/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/MainActivity.java index baa515a..1d918d5 100644 --- a/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/MainActivity.java +++ b/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/MainActivity.java @@ -2,6 +2,8 @@ import android.app.Activity; import android.app.PendingIntent; +import android.appwidget.AppWidgetManager; +import android.content.ComponentName; import android.content.Intent; import android.content.IntentFilter; import android.nfc.FormatException; @@ -68,7 +70,6 @@ protected void onCreate(Bundle savedInstanceState) { mTitle = getTitle(); - // Set up the drawer. mNavigationDrawerFragment.setUp( R.id.navigation_drawer, @@ -81,7 +82,7 @@ protected void onCreate(Bundle savedInstanceState) { nfcPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED); tagDetected.addCategory(Intent.CATEGORY_DEFAULT); - writeTagFilters = new IntentFilter[] { tagDetected }; + writeTagFilters = new IntentFilter[]{tagDetected}; } @@ -91,7 +92,7 @@ public void onNavigationDrawerItemSelected(int position) { String projectName = ""; - if(mNavigationDrawerFragment != null) { + if (mNavigationDrawerFragment != null) { projectName = mNavigationDrawerFragment.getProjectName(position); // update the main content by replacing fragments FragmentManager fragmentManager = getSupportFragmentManager(); @@ -101,17 +102,16 @@ public void onNavigationDrawerItemSelected(int position) { Log.i("Projekt", "gestartetes Projekt: " + UserDataStore.getInstance().getProjectName(getApplicationContext()) + " selectes Project: " + projectName); // beide Buttons sichtbar, weil kein aktives projekt - if(UserDataStore.getInstance().getProjectName(getApplicationContext()).equals("")){ + if (UserDataStore.getInstance().getProjectName(getApplicationContext()).equals("")) { fragment.setArguments(PlaceholderFragment.newInstance(projectName, true, false)); - }else if(UserDataStore.getInstance().getProjectName(getApplicationContext()).equals(projectName)){ + } else if (UserDataStore.getInstance().getProjectName(getApplicationContext()).equals(projectName)) { fragment.setArguments(PlaceholderFragment.newInstance(projectName, false, true)); - }else{ + } else { fragment.setArguments(PlaceholderFragment.newInstance(projectName, false, false)); } - fragmentManager.beginTransaction() .replace(R.id.container, fragment) .commit(); @@ -140,7 +140,7 @@ public boolean onCreateOptionsMenu(Menu menu) { // if the drawer is not showing. Otherwise, let the drawer // decide what to show in the action bar. - if(UserDataStore.getInstance().getAutoLogin(getApplicationContext())){ + if (UserDataStore.getInstance().getAutoLogin(getApplicationContext())) { getMenuInflater().inflate(R.menu.main, menu); } restoreActionBar(); @@ -157,20 +157,20 @@ public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_settings) { return true; - } else if( id == R.id.action_logout){ + } else if (id == R.id.action_logout) { UserDataStore.getInstance().setAutoLogin(getApplicationContext(), false); finish(); - }else if( id == R.id.action_nfc){ + } else if (id == R.id.action_nfc) { try { - if(projectilerTag != null){ + if (projectilerTag != null) { // nfc löschen Log.d("", "write nfc"); write(NFC_KEY_WORD, projectilerTag); Crouton.makeText(MainActivity.this, "NFC in Reichweite", Style.CONFIRM).show(); - }else{ + } else { // bitte NFC hinlegen } @@ -188,7 +188,7 @@ protected void onNewIntent(Intent intent) { super.onNewIntent(intent); Log.d("", "onNewIntent"); - if(NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())){ + if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) { projectilerTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); Log.d("", "projectilerTag gesetzt"); @@ -204,13 +204,14 @@ protected void onNewIntent(Intent intent) { private void write(String text, Tag tag) throws IOException, FormatException { - NdefRecord[] records = { createRecord(text) }; + NdefRecord[] records = {createRecord(text)}; NdefMessage message = new NdefMessage(records); Ndef ndef = Ndef.get(tag); ndef.connect(); ndef.writeNdefMessage(message); ndef.close(); } + private NdefRecord createRecord(String text) throws UnsupportedEncodingException { //create the message in according with the standard @@ -253,6 +254,7 @@ public static class PlaceholderFragment extends Fragment { private TextView tvStartDate; private final Projectiler projectiler; + private View rootView; /** * Returns a new instance of this fragment for the given section @@ -272,14 +274,63 @@ public PlaceholderFragment() { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_main, container, false); + Bundle savedInstanceState) { + rootView = inflater.inflate(R.layout.fragment_main, container, false); projectName = getArguments().getString(ARG_PROJECT_NAME); startVisible = getArguments().getBoolean(ARG_START_VISIBLE); stopVisible = getArguments().getBoolean(ARG_STOP_VISIBLE); + initView(rootView); + + return rootView; + } + + private void setStartDateTextView() { + Date startDate = projectiler.getStartDate(getActivity().getApplicationContext()); + + if (startDate == null) { + tvStartDateLabel.setVisibility(View.GONE); + tvStartDate.setVisibility(View.GONE); + } else { + + if (projectiler.getProjectName(getActivity().getApplicationContext()).equals(projectName)) { + tvStartDateLabel.setVisibility(View.VISIBLE); + tvStartDate.setVisibility(View.VISIBLE); + + tvStartDate.setText(projectiler.getStartDateAsString(getActivity().getApplicationContext())); + } else { + tvStartDateLabel.setVisibility(View.GONE); + } + + + } + } + + @Override + public void onResume() { + super.onResume(); + Log.i("Fragment", "onResume"); + + if(rootView != null){ + if (UserDataStore.getInstance().getProjectName(getActivity().getApplicationContext()).equals("")) { + startVisible = true; + stopVisible = false; + } else if (UserDataStore.getInstance().getProjectName(getActivity().getApplicationContext()).equals(projectName)) { + startVisible = false; + stopVisible = true; + } else { + startVisible = false; + stopVisible = false; + } + + initView(rootView); + + } + } + + private void initView(View rootView) { TextView textView = (TextView) rootView.findViewById(R.id.section_label); btnStart = (Button) rootView.findViewById(R.id.btnStart); btnStop = (Button) rootView.findViewById(R.id.btnStop); @@ -325,40 +376,19 @@ public void onClick(View view) { ((MainActivity) getActivity()).refreshNavigationDrawer(""); + // update Widget + updateWidget(); + + } }); - btnStart.setEnabled(startVisible); btnStop.setEnabled(stopVisible); btnReset.setEnabled(stopVisible); - // ist ein startDate gesetzt? setStartDateTextView(); - - return rootView; - } - - private void setStartDateTextView(){ - Date startDate = projectiler.getStartDate(getActivity().getApplicationContext()); - - if(startDate == null){ - tvStartDateLabel.setVisibility(View.GONE); - tvStartDate.setVisibility(View.GONE); - }else{ - - if(projectiler.getProjectName(getActivity().getApplicationContext()).equals(projectName)){ - tvStartDateLabel.setVisibility(View.VISIBLE); - tvStartDate.setVisibility(View.VISIBLE); - - tvStartDate.setText(projectiler.getStartDateAsString(getActivity().getApplicationContext())); - }else{ - tvStartDateLabel.setVisibility(View.GONE); - } - - - } } @Override @@ -369,7 +399,7 @@ public void onAttach(Activity activity) { } - private class StartAsyncTask extends AsyncTask{ + private class StartAsyncTask extends AsyncTask { @Override protected Void doInBackground(Void... voids) { @@ -386,7 +416,7 @@ protected void onPostExecute(Void aVoid) { getActivity().setProgressBarIndeterminateVisibility(false); // navigation Drawer aktualisieren - ((MainActivity)getActivity()).refreshNavigationDrawer(projectName); + ((MainActivity) getActivity()).refreshNavigationDrawer(projectName); btnStart.setEnabled(false); btnStop.setEnabled(true); @@ -394,11 +424,22 @@ protected void onPostExecute(Void aVoid) { setStartDateTextView(); + updateWidget(); + } } + private void updateWidget() { + Intent intent = new Intent(getActivity(), ProjectilerAppWidget.class); + intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); + // Use an array and EXTRA_APPWIDGET_IDS instead of AppWidgetManager.EXTRA_APPWIDGET_ID, + // since it seems the onUpdate() is only fired on that: + int[] appWidgetIds = AppWidgetManager.getInstance(getActivity().getApplication()).getAppWidgetIds(new ComponentName(getActivity().getApplication(), ProjectilerAppWidget.class)); + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds); + getActivity().sendBroadcast(intent); + } - private class StopAsyncTask extends AsyncTask{ + private class StopAsyncTask extends AsyncTask { @Override protected String doInBackground(Void... voids) { @@ -408,7 +449,7 @@ protected String doInBackground(Void... voids) { } catch (CrawlingException e) { e.printStackTrace(); return e.getMessage(); - }catch (IllegalStateException e1){ + } catch (IllegalStateException e1) { return e1.getMessage(); } @@ -421,18 +462,22 @@ protected void onPostExecute(String aVoid) { getActivity().setProgressBarIndeterminateVisibility(false); - if(aVoid == null) { + if (aVoid == null) { ((MainActivity) getActivity()).refreshNavigationDrawer(""); btnStart.setEnabled(true); btnStop.setEnabled(false); btnReset.setEnabled(false); + projectiler.resetStartTime(getActivity().getApplicationContext()); + setStartDateTextView(); Crouton.makeText(getActivity(), "Zeit wurd erfolgreich gebucht", Style.INFO).show(); + updateWidget(); + - }else{ + } else { Crouton.makeText(getActivity(), aVoid, Style.ALERT).show(); } } @@ -445,7 +490,7 @@ private void refreshNavigationDrawer(String projectName) { } - private class GetProjectsAsyncTask extends AsyncTask>{ + private class GetProjectsAsyncTask extends AsyncTask> { private Projectiler defaultProjectiler; @@ -456,7 +501,7 @@ protected List doInBackground(Void... voids) { try { List projectNames = defaultProjectiler.getProjectNames(getApplicationContext()); - for(String projectName : projectNames){ + for (String projectName : projectNames) { Log.i("Projects: ", "" + projectName); } @@ -474,9 +519,9 @@ protected void onPostExecute(List itemList) { setProgressBarIndeterminateVisibility(false); // tritt auf bei autologin wenn das passwort geaendert wurde - if(itemList != null){ + if (itemList != null) { mNavigationDrawerFragment.setItems(itemList); - }else { + } else { defaultProjectiler.setAutoLogin(getApplicationContext(), false); MainActivity.this.finish(); diff --git a/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/ProjectNameIntentService.java b/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/ProjectNameIntentService.java new file mode 100644 index 0000000..bcd7e74 --- /dev/null +++ b/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/ProjectNameIntentService.java @@ -0,0 +1,46 @@ +package de.saxsys.android.projectiler.app; + +import android.app.IntentService; +import android.content.Intent; +import android.util.Log; + +import de.saxsys.android.projectiler.app.backend.Projectiler; +import de.saxsys.android.projectiler.app.utils.WidgetUtils; + +/** + * An {@link IntentService} subclass for handling asynchronous task requests in + * a service on a separate handler thread. + *

+ * TODO: Customize class - update intent actions, extra parameters and static + * helper methods. + */ +public class ProjectNameIntentService extends IntentService { + + private Projectiler projectiler; + + public ProjectNameIntentService() { + super("ProjectNameIntentService"); + Log.i("ProjectNameIntentService", "ProjectNameIntentService"); + projectiler = Projectiler.createDefaultProjectiler(); + } + + @Override + protected void onHandleIntent(Intent intent) { + Log.i("ProjectNameIntentService", "onHandleIntent"); + if (intent != null) { + + String selectedProject = intent.getStringExtra(ProjectilerAppWidget.EXTRA_PROJECT_NAME); + + Log.i("ProjectNameIntentService", "selected Project " + selectedProject); + + WidgetUtils.showProgressBarOnWidget(getApplicationContext(), projectiler); + + projectiler.saveProjectName(getApplicationContext(), selectedProject); + + WidgetUtils.hideProgressBarOnWidget(getApplicationContext(), projectiler); + + + } + } + +} diff --git a/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/ProjectilerAppWidget.java b/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/ProjectilerAppWidget.java new file mode 100644 index 0000000..239ff9c --- /dev/null +++ b/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/ProjectilerAppWidget.java @@ -0,0 +1,132 @@ +package de.saxsys.android.projectiler.app; + +import android.app.PendingIntent; +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProvider; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.SystemClock; +import android.util.Log; +import android.view.View; +import android.widget.RemoteViews; + +import java.util.Date; + +import de.saxsys.android.projectiler.app.backend.Projectiler; + + +/** + * Implementation of App Widget functionality. + */ +public class ProjectilerAppWidget extends AppWidgetProvider { + + private static final String CLICK_ACTION = "de.saxsys.android.projectiler.app.widget.CLICK"; + public static final String EXTRA_PROJECT_NAME = "de.saxsys.android.projectiler.app.widget.PROJECT_NAME"; + + @Override + public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { + // There may be multiple widgets active, so update all of them + Log.i("ProjectilerAppWidget", "onUpdate"); + final int N = appWidgetIds.length; + for (int i=0; i + * TODO: Customize class - update intent actions, extra parameters and static + * helper methods. + */ +public class ResetIntentService extends IntentService { + + private Projectiler projectiler; + + public ResetIntentService() { + super("ResetIntentService"); + projectiler = Projectiler.createDefaultProjectiler(); + } + + @Override + protected void onHandleIntent(Intent intent) { + if (intent != null) { + + WidgetUtils.showProgressBarOnWidget(getApplicationContext(), projectiler); + + projectiler.saveProjectName(getApplicationContext(), ""); + projectiler.resetStartTime(getApplicationContext()); + + WidgetUtils.hideProgressBarOnWidget(getApplicationContext(), projectiler); + } + } + +} diff --git a/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/StartIntentService.java b/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/StartIntentService.java new file mode 100644 index 0000000..e062c7f --- /dev/null +++ b/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/StartIntentService.java @@ -0,0 +1,55 @@ +package de.saxsys.android.projectiler.app; + +import android.app.IntentService; +import android.content.Intent; +import android.os.AsyncTask; + +import de.saxsys.android.projectiler.app.backend.Projectiler; +import de.saxsys.android.projectiler.app.utils.WidgetUtils; + + +/** + * An {@link IntentService} subclass for handling asynchronous task requests in + * a service on a separate handler thread. + *

+ * TODO: Customize class - update intent actions and extra parameters. + */ +public class StartIntentService extends IntentService { + + private Projectiler projectiler; + + public StartIntentService() { + super("StartIntentService"); + projectiler = Projectiler.createDefaultProjectiler(); + } + + @Override + protected void onHandleIntent(Intent intent) { + if (intent != null) { + + WidgetUtils.showProgressBarOnWidget(getApplicationContext(), projectiler); + new StartAsyncTask().execute(); + + + } + } + + private class StartAsyncTask extends AsyncTask { + + @Override + protected Void doInBackground(Void... voids) { + + projectiler.checkin(getApplicationContext()); + + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + WidgetUtils.hideProgressBarOnWidget(getApplicationContext(), projectiler); + + } + } + +} diff --git a/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/StopIntentService.java b/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/StopIntentService.java new file mode 100644 index 0000000..d7574fd --- /dev/null +++ b/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/StopIntentService.java @@ -0,0 +1,68 @@ +package de.saxsys.android.projectiler.app; + +import android.app.IntentService; +import android.content.Intent; +import android.os.AsyncTask; +import android.util.Log; +import android.widget.RemoteViews; + +import de.saxsys.android.projectiler.app.backend.Projectiler; +import de.saxsys.android.projectiler.app.crawler.CrawlingException; +import de.saxsys.android.projectiler.app.utils.WidgetUtils; + +/** + * An {@link IntentService} subclass for handling asynchronous task requests in + * a service on a separate handler thread. + *

+ * TODO: Customize class - update intent actions, extra parameters and static + * helper methods. + */ +public class StopIntentService extends IntentService { + + private Projectiler projectiler; + private RemoteViews views; + + public StopIntentService() { + super("StopIntentService"); + projectiler = Projectiler.createDefaultProjectiler(); + } + + @Override + protected void onHandleIntent(Intent intent) { + Log.i("StopIntentService", "onHandleIntent"); + if (intent != null) { + + // zeige progressBar in Widget + WidgetUtils.showProgressBarOnWidget(getApplicationContext(), projectiler); + + new StopAsyncTask().execute(); + } + } + + private class StopAsyncTask extends AsyncTask { + + @Override + protected String doInBackground(Void... voids) { + + try { + projectiler.checkout(getApplicationContext(), projectiler.getProjectName(getApplicationContext())); + } catch (CrawlingException e) { + e.printStackTrace(); + return e.getMessage(); + } catch (IllegalStateException e1) { + return e1.getMessage(); + } + + return null; + } + + @Override + protected void onPostExecute(String aVoid) { + super.onPostExecute(aVoid); + + WidgetUtils.hideProgressBarOnWidget(getApplicationContext(), projectiler); + } + } + + +} diff --git a/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/WidgetService.java b/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/WidgetService.java new file mode 100644 index 0000000..4393b44 --- /dev/null +++ b/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/WidgetService.java @@ -0,0 +1,87 @@ +package de.saxsys.android.projectiler.app; + +import android.appwidget.AppWidgetManager; +import android.content.Intent; +import android.os.AsyncTask; +import android.util.Log; +import android.widget.RemoteViewsService; + +import java.util.List; +import java.util.concurrent.ExecutionException; + +import de.saxsys.android.projectiler.app.backend.Projectiler; +import de.saxsys.android.projectiler.app.crawler.CrawlingException; +import de.saxsys.android.projectiler.app.utils.WidgetUtils; + +/** + * Created by stefan.heinze on 14.05.2014. + */ +public class WidgetService extends RemoteViewsService { + private List projectNames; + private RemoteViewsService.RemoteViewsFactory ret = null; + private Intent intent; + private Projectiler defaultProjectiler; +/* +* So pretty simple just defining the Adapter of the listview +* here Adapter is ListProvider +* */ + + @Override + public RemoteViewsService.RemoteViewsFactory onGetViewFactory(Intent intent) { + this.intent = intent; + int appWidgetId = intent.getIntExtra( + AppWidgetManager.EXTRA_APPWIDGET_ID, + AppWidgetManager.INVALID_APPWIDGET_ID); + + try { + + defaultProjectiler = Projectiler.createDefaultProjectiler(); + + WidgetUtils.showProgressBarOnWidget(getApplicationContext(), defaultProjectiler); + + ret = new GetProjectsAsyncTask().execute().get(); + + WidgetUtils.hideProgressBarOnWidget(getApplicationContext(), defaultProjectiler); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + + while(ret == null){ + try { + Thread.sleep(500); + Log.i("ListProvider", "ret is nullListProvider"); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + return ret; + } + + + private class GetProjectsAsyncTask extends AsyncTask { + + + @Override + protected RemoteViewsService.RemoteViewsFactory doInBackground(Void... voids) { + + + try { + + projectNames = defaultProjectiler.getProjectNames(getApplicationContext()); + for (String projectName : projectNames) { + Log.i("ListProvider", "" + projectName); + } + + return (new ListProvider(getApplicationContext(), intent, projectNames)); + } catch (CrawlingException e) { + e.printStackTrace(); + } + + return null; + } + } + +} diff --git a/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/backend/Projectiler.java b/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/backend/Projectiler.java index 7f7130c..ef7a8c9 100644 --- a/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/backend/Projectiler.java +++ b/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/backend/Projectiler.java @@ -139,4 +139,12 @@ public boolean getAutoLogin(Context context) { public void setAutoLogin(final Context context, boolean autoLogin) { dataStore.setAutoLogin(context, autoLogin); } + + public void setWidgetLoading(final Context context, boolean loading) { + dataStore.setWidgetLoading(context, loading); + } + + public boolean isWidgetLoading(Context context) { + return dataStore.isWidgetLoading(context); + } } diff --git a/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/backend/UserDataStore.java b/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/backend/UserDataStore.java index e9d2078..036803a 100644 --- a/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/backend/UserDataStore.java +++ b/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/backend/UserDataStore.java @@ -19,6 +19,7 @@ public class UserDataStore implements Serializable { private static final String PROJECT_NAME = "project_name"; private static final String AUTO_LOGIN = "auto_login"; private static final String START_DATE = "start_date"; + private static final String WIDGET_LOADING = "widget_loading"; private static UserDataStore INSTANCE; @@ -156,4 +157,19 @@ public boolean isCheckedIn(final Context context) { private static SharedPreferences getDefaultSharedPreferences(final Context context) { return context.getSharedPreferences("projectiler", Context.MODE_PRIVATE); } + + public void setWidgetLoading(Context context, boolean loading) { + final SharedPreferences sharedPreferences = getDefaultSharedPreferences(context); + + final SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putBoolean(WIDGET_LOADING, loading); + + editor.commit(); + } + + public boolean isWidgetLoading(final Context context){ + final SharedPreferences mySharedPreferences = getDefaultSharedPreferences(context); + + return mySharedPreferences.getBoolean(WIDGET_LOADING, false); + } } diff --git a/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/utils/WidgetUtils.java b/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/utils/WidgetUtils.java new file mode 100644 index 0000000..a255a3d --- /dev/null +++ b/ProjectilerApp/Projectiler/app/src/main/java/de/saxsys/android/projectiler/app/utils/WidgetUtils.java @@ -0,0 +1,35 @@ +package de.saxsys.android.projectiler.app.utils; + +import android.appwidget.AppWidgetManager; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; + +import de.saxsys.android.projectiler.app.ProjectilerAppWidget; +import de.saxsys.android.projectiler.app.backend.Projectiler; + +/** + * Created by stefan.heinze on 15.05.2014. + */ +public class WidgetUtils { + + + public static void refreshWidget(final Context context){ + Intent widgetIntent = new Intent(context, ProjectilerAppWidget.class); + widgetIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); + int[] appWidgetIds = AppWidgetManager.getInstance(context).getAppWidgetIds(new ComponentName(context, ProjectilerAppWidget.class)); + widgetIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds); + context.sendBroadcast(widgetIntent); + } + + + public static void showProgressBarOnWidget(final Context context, final Projectiler projectiler){ + projectiler.setWidgetLoading(context, true); + refreshWidget(context); + } + + public static void hideProgressBarOnWidget(final Context context, final Projectiler projectiler){ + projectiler.setWidgetLoading(context, false); + refreshWidget(context); + } +} diff --git a/ProjectilerApp/Projectiler/app/src/main/res/drawable-nodpi/example_appwidget_preview.png b/ProjectilerApp/Projectiler/app/src/main/res/drawable-nodpi/example_appwidget_preview.png new file mode 100644 index 0000000000000000000000000000000000000000..894b069a4907d258f60b1b2406b90f5a0fe1c35b GIT binary patch literal 3522 zcmaJ^3piA3_a6@xDwm_1J~1d=T*eGD7*t{~G6s#392#aYX)b2QC2|g;(n0D}E^|`S zMRLit5fgHkOAh7IFc`OL+?mN`#$lds_TJBqcXqPd zF27eE1OjbG+uOJTvj{kk%Sr>+x% z-dKicf&VgL23l(Uhm za0C)&0{;8Z0;16gen?jv+rMK0nx$3%lSxBDAfch52BAg zOB5zPOrOHg{*GWnWcboaG$x5k0dFAUeW<}qOD%xue^MaR{(+@1{w@At|m`Dt&2q9Lv6L_Cv9$5E*l zzgN*YfXbvY0;n{w^(h4S5C-o{qHHW2{>uY{L82)PCZ6I;MB7+u0T>1(5&>z2GB&X? zGBiP;PzWd#1v5ig8Cyfm5HJ|b#P$Tj?7OcG)i;<-q%gnx68`IJ`a|E1W+2mm$Tmbe zDTGL{rBlh^zmi6he#`~_L%hFz2|wn7_@OTZAOqRh+W)cD-?*%1F}TtNA!^@$Xq z-|0YO+ud)}1%ag6ogHx~P|nBo_4N||yhO6@-!vwcNXC{{B_L@`-0Qp9>Oce3v0&4iBBlFXuwKa*PX>tiwI*{1(Wpz!G`auxgGBLL-uAf-! z76{uWmh_6aK>90dlBCv&BL)2dZ%3u_dI20mHWybh^l26d+5^Pu{48|m3%7*6hhiCuzC}?d@tpkB%Ja5*BSO6RzzJ)F(!8A;WsgO`>)Toe9%UR z+kH6adFGg!ZSMw3oSE&m*(5&XoZ2RC@4o&)SA?Ka&ba2A!{X`ZnzqtC7qhQc zcbR)|Pt&ot_r94@^2S{)>tZkaBxHG4V z(-xOTCp)!6IbjQ$`#EHE8$?s^+Ag5#i0N(OQH`3~NmI_{L!~}@&ZOS$)Hxk;Ke};F zpi;7HrpQ4eOvWYrvYM_``pAr1>fF+j%T|=8Wc(I!^lmZ|@0xiNWxO*3cp9?tnj;l+ z5h0x^O%bb7nRoxl9(tA9u2zNqjBnWokGxWTDloA;>+A(Jsl?wYlpyMr{gaz2CgIg& zd(~9kgJ0;XcCjpx3rTDrE=-S3nVH%~JB!&?8Jlu)-Uk+y_2IhZj%hxc;rpOncQLwHpn^Wy=y%@0Yp2gD zap+z``_kF^%RlL>y7Nov>LJgBEJ94CxS7zLF1vpw%l|&{n6~Ks+cY$rb%oWMRAIj* z9TH1R44Z$hleKqoMFT5cnMl~fh>2c4X;rY) zs}k72ZH?RVJ5}H-v*ofG$Y3b{Y_KW&z8s8E;d23pn z%evOfdm=5IlwLcaexZtlY;D5VLQcy094uGVJ!$1HIu~`Wk@_cuIHA6PZESlsf{?qs zO3iFeUroDL5oeVnYhwLsaGjGvOI{W>io8)n=?^N{y3B??@ePZ?K%?spdyb46%W;FD z34OCQ^b#rmU}ek9psrNQGMkGbI&~*C-q1L99(zUq3Rx()X0c@?IJ&&rG-8%PYK_BT zioWVRYkGIbx(&bRdvXD?6`WC^{Bwzda2}(c(;-*nZ~6Po4{u8XiLNF*ioaKzz|Ks_fA2lAfZj2#@RD&W8=Ic8TXhtz zH4ySPqp12#TjW$P&gKSr3F9NAX~q?GVB9dgP=z z=~AAO7Zfc2x%Xc#wl79rhmphteq)!~{bMo}q@uCpxB4uj$GtHh>UW*Y`@Km$szVgV zekHhd(d-09_Oy0?AsPAW@iD5Sf}z(~+0G|Dw@$ztzO_aYyoj@=;w6EOm!1P&YIdt%(lZ$xySfS5(>-u>Iw(!y;jb6o@s4CS zpYJ~wq{O-~ibyMYI?74do*wP{u5#veF83tLh4i`oU<1ZE-qDFsP=8`qOhlDTS00+i zuY2BgR~qY8m)rU0hZGkTeXie5R%}EKCZ-l!Xy@UI8<3f&On)5kQkXj;zOVB+{YCwY z0uq}jU$TV@mOmh&4WxGNd~kNpe7;FcHA0xLtkUY{uNI+AX?t>E*txqQ?}&?`S<8r% z`1zGx%qDA-dmcHJA!m96Vlg+|v0dz&gp60C=7_X=$Di1skjBY%YP#J#&rMq62^p&g z)e{tBY6B;0D-0dI9&CPgJuGrkpI7)~KLJTOgDbX-%Q`ajG=9;e{{8r!9&Sju*_XP7 zLw}s(c8`=<-3{wepo!HGY4dD5V?0$_KQ609v`;7dW~~eQ5FhcN&a_F}R4>IoJ|NoGNa5|5PbYeyQ7DPw|>ER*)1m8dQ+n9i{Sh;i?~UqNls^ zXIO7yN`hMZwu6oBWy~YDcHA|^I`Nx$TfH>1{`dD@%u`>NHw1Ou%eRZ-1}ty @@ -19,6 +20,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="New Text" + android:textIsSelectable="false" android:id="@+id/tv_project_name" android:layout_centerVertical="true" android:layout_toRightOf="@+id/iv_active" /> diff --git a/ProjectilerApp/Projectiler/app/src/main/res/layout/projectiler_app_widget.xml b/ProjectilerApp/Projectiler/app/src/main/res/layout/projectiler_app_widget.xml new file mode 100644 index 0000000..9f2c789 --- /dev/null +++ b/ProjectilerApp/Projectiler/app/src/main/res/layout/projectiler_app_widget.xml @@ -0,0 +1,80 @@ + + +