mirror of
https://github.com/nerzhul/ownCloud-SMS-App.git
synced 2026-08-21 05:13:27 +00:00
Big commit: Android Studio + Re-enable ContactList view and make it working to prepare SMS restauration
This commit is contained in:
+125
@@ -0,0 +1,125 @@
|
||||
package fr.unix_experience.owncloud_sms.activities;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2015, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.PeriodicSync;
|
||||
import android.os.Bundle;
|
||||
import android.preference.ListPreference;
|
||||
import android.util.Log;
|
||||
import fr.nrz.androidlib.activities.NrzSettingsActivity;
|
||||
import fr.unix_experience.owncloud_sms.R;
|
||||
import fr.unix_experience.owncloud_sms.defines.DefaultPrefs;
|
||||
import fr.unix_experience.owncloud_sms.prefs.OCSMSSharedPrefs;
|
||||
|
||||
public class GeneralSettingsActivity extends NrzSettingsActivity {
|
||||
private static final String TAG = GeneralSettingsActivity.class.getSimpleName();
|
||||
|
||||
private static AccountManager _accountMgr;
|
||||
private static String _accountAuthority;
|
||||
private static String _accountType;
|
||||
|
||||
@Override
|
||||
protected void onPostCreate(final Bundle savedInstanceState) {
|
||||
_accountMgr = AccountManager.get(getBaseContext());
|
||||
_accountAuthority = getString(R.string.account_authority);
|
||||
_accountType = getString(R.string.account_type);
|
||||
_prefsRessourceFile = R.xml.pref_data_sync;
|
||||
|
||||
// Bind our boolean preferences
|
||||
_boolPrefs.add(new BindObjectPref("push_on_receive", DefaultPrefs.pushOnReceive));
|
||||
_boolPrefs.add(new BindObjectPref("sync_wifi", DefaultPrefs.syncWifi));
|
||||
_boolPrefs.add(new BindObjectPref("sync_4g", DefaultPrefs.sync4G));
|
||||
_boolPrefs.add(new BindObjectPref("sync_3g", DefaultPrefs.sync3G));
|
||||
_boolPrefs.add(new BindObjectPref("sync_gprs", DefaultPrefs.syncGPRS));
|
||||
_boolPrefs.add(new BindObjectPref("sync_2g", DefaultPrefs.sync2G));
|
||||
_boolPrefs.add(new BindObjectPref("sync_others", DefaultPrefs.syncOthers));
|
||||
|
||||
// Bind our string preferences
|
||||
_stringPrefs.add(new BindObjectPref("sync_frequency", ""));
|
||||
|
||||
// Must be at the end, after preference bind
|
||||
super.onPostCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
protected static void handleCheckboxPreference(final String key, final Boolean value) {
|
||||
// Network types allowed for sync
|
||||
if(key.equals(new String("push_on_receive")) ||
|
||||
key.equals(new String("sync_wifi")) || key.equals("sync_2g") ||
|
||||
key.equals(new String("sync_3g")) || key.equals("sync_gprs") ||
|
||||
key.equals("sync_4g") || key.equals("sync_others")) {
|
||||
final OCSMSSharedPrefs prefs = new OCSMSSharedPrefs(_context);
|
||||
Log.d(TAG,"GeneralSettingsActivity.handleCheckboxPreference: set " + key + " to "
|
||||
+ value.toString());
|
||||
prefs.putBoolean(key, value);
|
||||
}
|
||||
else {
|
||||
// Unknown option
|
||||
}
|
||||
}
|
||||
|
||||
protected static void handleListPreference(final String key, final String value,
|
||||
final ListPreference preference) {
|
||||
// For list preferences, look up the correct display value in
|
||||
// the preference's 'entries' list.
|
||||
final int index = preference.findIndexOfValue(value);
|
||||
|
||||
// Set the summary to reflect the new value.
|
||||
preference
|
||||
.setSummary(index >= 0 ? preference.getEntries()[index]
|
||||
: null);
|
||||
|
||||
// Handle sync frequency change
|
||||
if (key.equals("sync_frequency")) {
|
||||
final Account[] myAccountList = _accountMgr.getAccountsByType(_accountType);
|
||||
final long syncFreq = Long.parseLong(value);
|
||||
|
||||
// Get ownCloud SMS account list
|
||||
for (int i = 0; i < myAccountList.length; i++) {
|
||||
// And get all authorities for this account
|
||||
final List<PeriodicSync> syncList = ContentResolver.getPeriodicSyncs(myAccountList[i], _accountAuthority);
|
||||
|
||||
boolean foundSameSyncCycle = false;
|
||||
for (int j = 0; j < syncList.size(); j++) {
|
||||
final PeriodicSync ps = syncList.get(i);
|
||||
|
||||
if (ps.period == syncFreq && ps.extras.getInt("synctype") == 1) {
|
||||
foundSameSyncCycle = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundSameSyncCycle == false) {
|
||||
final Bundle b = new Bundle();
|
||||
b.putInt("synctype", 1);
|
||||
|
||||
ContentResolver.removePeriodicSync(myAccountList[i],
|
||||
_accountAuthority, b);
|
||||
ContentResolver.addPeriodicSync(myAccountList[i],
|
||||
_accountAuthority, b, syncFreq * 60);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Unhandled option
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
package fr.unix_experience.owncloud_sms.activities;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2015, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
import com.owncloud.android.lib.common.OwnCloudClientFactory;
|
||||
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
|
||||
|
||||
import fr.unix_experience.owncloud_sms.R;
|
||||
import fr.unix_experience.owncloud_sms.authenticators.OwnCloudAuthenticator;
|
||||
import fr.unix_experience.owncloud_sms.defines.DefaultPrefs;
|
||||
import fr.unix_experience.owncloud_sms.enums.LoginReturnCode;
|
||||
|
||||
/**
|
||||
* A login screen that offers login via email/password.
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
public class LoginActivity extends Activity {
|
||||
/**
|
||||
* Keep track of the login task to ensure we can cancel it if requested.
|
||||
*/
|
||||
private UserLoginTask mAuthTask = null;
|
||||
|
||||
// UI references.
|
||||
private Spinner _protocolView;
|
||||
private EditText _loginView;
|
||||
private EditText _passwordView;
|
||||
private EditText _serverView;
|
||||
private View mProgressView;
|
||||
private View mLoginFormView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_login);
|
||||
|
||||
// Set up the login form.
|
||||
_protocolView = (Spinner) findViewById(R.id.oc_protocol);
|
||||
_serverView = (EditText) findViewById(R.id.oc_server);
|
||||
_loginView = (EditText) findViewById(R.id.oc_login);
|
||||
|
||||
_passwordView = (EditText) findViewById(R.id.oc_password);
|
||||
_passwordView
|
||||
.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||
@Override
|
||||
public boolean onEditorAction(TextView textView, int id,
|
||||
KeyEvent keyEvent) {
|
||||
if (id == R.id.oc_login || id == EditorInfo.IME_NULL) {
|
||||
attemptLogin();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
Button _signInButton = (Button) findViewById(R.id.oc_signin_button);
|
||||
_signInButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
attemptLogin();
|
||||
}
|
||||
});
|
||||
|
||||
mLoginFormView = findViewById(R.id.login_form);
|
||||
mProgressView = findViewById(R.id.login_progress);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to sign in or register the account specified by the login form.
|
||||
* If there are form errors (invalid email, missing fields, etc.), the
|
||||
* errors are presented and no actual login attempt is made.
|
||||
*/
|
||||
public void attemptLogin() {
|
||||
if (mAuthTask != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset errors.
|
||||
_loginView.setError(null);
|
||||
_passwordView.setError(null);
|
||||
|
||||
// Store values at the time of the login attempt.
|
||||
String protocol = _protocolView.getSelectedItem().toString();
|
||||
String login = _loginView.getText().toString();
|
||||
String password = _passwordView.getText().toString();
|
||||
String serverAddr = _serverView.getText().toString();
|
||||
|
||||
boolean cancel = false;
|
||||
View focusView = null;
|
||||
|
||||
// Check for a valid server address.
|
||||
if (TextUtils.isEmpty(protocol)) {
|
||||
cancel = true;
|
||||
}
|
||||
|
||||
// Check for a valid server address.
|
||||
if (TextUtils.isEmpty(serverAddr)) {
|
||||
_serverView.setError(getString(R.string.error_field_required));
|
||||
focusView = _loginView;
|
||||
cancel = true;
|
||||
}
|
||||
|
||||
// Check for a valid login address.
|
||||
if (TextUtils.isEmpty(login)) {
|
||||
_loginView.setError(getString(R.string.error_field_required));
|
||||
focusView = _loginView;
|
||||
cancel = true;
|
||||
}
|
||||
|
||||
// Check for a valid password
|
||||
if (TextUtils.isEmpty(password)) {
|
||||
_passwordView.setError(getString(R.string.error_field_required));
|
||||
focusView = _passwordView;
|
||||
cancel = true;
|
||||
}
|
||||
|
||||
if (!isPasswordValid(password)) {
|
||||
_passwordView.setError(getString(R.string.error_invalid_password));
|
||||
focusView = _passwordView;
|
||||
cancel = true;
|
||||
}
|
||||
|
||||
if (cancel) {
|
||||
// There was an error; don't attempt login and focus the first
|
||||
// form field with an error.
|
||||
focusView.requestFocus();
|
||||
} else {
|
||||
// Show a progress spinner, and kick off a background task to
|
||||
// perform the user login attempt.
|
||||
showProgress(true);
|
||||
String serverURL = new String(protocol + serverAddr);
|
||||
mAuthTask = new UserLoginTask(serverURL, login, password);
|
||||
mAuthTask.execute((Void) null);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPasswordValid(String password) {
|
||||
// TODO: Replace this with your own logic
|
||||
return password.length() > 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the progress UI and hides the login form.
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
|
||||
public void showProgress(final boolean show) {
|
||||
// On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
|
||||
// for very easy animations. If available, use these APIs to fade-in
|
||||
// the progress spinner.
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
|
||||
int shortAnimTime = getResources().getInteger(
|
||||
android.R.integer.config_shortAnimTime);
|
||||
|
||||
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
|
||||
mLoginFormView.animate().setDuration(shortAnimTime)
|
||||
.alpha(show ? 0 : 1)
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mLoginFormView.setVisibility(show ? View.GONE
|
||||
: View.VISIBLE);
|
||||
}
|
||||
});
|
||||
|
||||
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
|
||||
mProgressView.animate().setDuration(shortAnimTime)
|
||||
.alpha(show ? 1 : 0)
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mProgressView.setVisibility(show ? View.VISIBLE
|
||||
: View.GONE);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// The ViewPropertyAnimator APIs are not available, so simply show
|
||||
// and hide the relevant UI components.
|
||||
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
|
||||
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an asynchronous login/registration task used to authenticate
|
||||
* the user.
|
||||
*/
|
||||
public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {
|
||||
|
||||
UserLoginTask(String serverURI, String login, String password) {
|
||||
_serverURI = Uri.parse(serverURI);
|
||||
_login = login;
|
||||
_password = password;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... params) {
|
||||
// Create client object to perform remote operations
|
||||
OwnCloudClient ocClient = OwnCloudClientFactory.createOwnCloudClient(
|
||||
_serverURI, getBaseContext(),
|
||||
// Activity or Service context
|
||||
true
|
||||
);
|
||||
|
||||
// Set basic credentials
|
||||
ocClient.setCredentials(
|
||||
OwnCloudCredentialsFactory.newBasicCredentials(_login, _password)
|
||||
);
|
||||
|
||||
// Send an authentication test to ownCloud
|
||||
OwnCloudAuthenticator at = new OwnCloudAuthenticator(getBaseContext());
|
||||
at.setClient(ocClient);
|
||||
|
||||
_returnCode = at.testCredentials();
|
||||
|
||||
return (_returnCode == LoginReturnCode.OK);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final Boolean success) {
|
||||
mAuthTask = null;
|
||||
showProgress(false);
|
||||
|
||||
if (success) {
|
||||
String accountType = getIntent().getStringExtra(PARAM_AUTHTOKEN_TYPE);
|
||||
if (accountType == null) {
|
||||
accountType = getString(R.string.account_type);
|
||||
}
|
||||
|
||||
// Generate a label
|
||||
String accountLabel = _login + "@" + _serverURI.getHost();
|
||||
|
||||
// We create the account
|
||||
final Account account = new Account(accountLabel, accountType);
|
||||
Bundle accountBundle = new Bundle();
|
||||
accountBundle.putString("ocLogin", _login);
|
||||
accountBundle.putString("ocURI", _serverURI.toString());
|
||||
|
||||
// And we push it to Android
|
||||
AccountManager accMgr = AccountManager.get(getApplicationContext());
|
||||
accMgr.addAccountExplicitly(account, _password, accountBundle);
|
||||
|
||||
// Set sync options
|
||||
ContentResolver.setSyncAutomatically(account, getString(R.string.account_authority), true);
|
||||
|
||||
Bundle b = new Bundle();
|
||||
b.putInt("synctype", 1);
|
||||
|
||||
ContentResolver.addPeriodicSync(account, getString(R.string.account_authority), b, DefaultPrefs.syncInterval * 60);
|
||||
// Then it's finished
|
||||
finish();
|
||||
|
||||
// Start sync settings, we have finished to configure account
|
||||
Intent settingsIntent = new Intent(Settings.ACTION_SYNC_SETTINGS);
|
||||
settingsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
getApplicationContext().startActivity(settingsIntent);
|
||||
} else {
|
||||
switch (_returnCode) {
|
||||
case INVALID_ADDR:
|
||||
_serverView.setError(getString(R.string.error_invalid_server_address));
|
||||
_serverView.requestFocus();
|
||||
break;
|
||||
case HTTP_CONN_FAILED:
|
||||
_serverView.setError(getString(R.string.error_http_connection_failed));
|
||||
_serverView.requestFocus();
|
||||
break;
|
||||
case CONN_FAILED:
|
||||
_serverView.setError(getString(R.string.error_connection_failed));
|
||||
_serverView.requestFocus();
|
||||
break;
|
||||
case INVALID_LOGIN:
|
||||
_passwordView.setError(getString(R.string.error_invalid_login));
|
||||
_passwordView.requestFocus();
|
||||
break;
|
||||
case UNKNOWN_ERROR:
|
||||
_serverView.setError("UNK");
|
||||
_serverView.requestFocus();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCancelled() {
|
||||
mAuthTask = null;
|
||||
showProgress(false);
|
||||
}
|
||||
|
||||
private final Uri _serverURI;
|
||||
private final String _login;
|
||||
private final String _password;
|
||||
private LoginReturnCode _returnCode;
|
||||
|
||||
public static final String PARAM_AUTHTOKEN_TYPE = "auth.token";
|
||||
public static final String PARAM_CREATE = "create";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
package fr.unix_experience.owncloud_sms.activities;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2015, Loic Blot <loic.blot@unix-experience.fr>
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.json.JSONArray;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.support.v13.app.FragmentPagerAdapter;
|
||||
import android.support.v4.view.PagerAdapter;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
import fr.unix_experience.owncloud_sms.R;
|
||||
import fr.unix_experience.owncloud_sms.activities.remote_account.AccountListActivity;
|
||||
import fr.unix_experience.owncloud_sms.engine.ASyncSMSSync.SyncTask;
|
||||
import fr.unix_experience.owncloud_sms.engine.ConnectivityMonitor;
|
||||
import fr.unix_experience.owncloud_sms.engine.SmsFetcher;
|
||||
import fr.unix_experience.owncloud_sms.notifications.OCSMSNotificationManager;
|
||||
|
||||
public class MainActivity extends Activity {
|
||||
|
||||
/**
|
||||
* The {@link android.support.v4.view.PagerAdapter} that will provide
|
||||
* fragments for each of the sections. We use a {@link FragmentPagerAdapter}
|
||||
* derivative, which will keep every loaded fragment in memory. If this
|
||||
* becomes too memory intensive, it may be best to switch to a
|
||||
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
|
||||
*/
|
||||
PagerAdapter mPagerAdapter;
|
||||
|
||||
/**
|
||||
* The {@link ViewPager} that will host the section contents.
|
||||
*/
|
||||
ViewPager mViewPager;
|
||||
|
||||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
// Create the adapter that will return a fragment for each of the three
|
||||
// primary sections of the activity.
|
||||
|
||||
final List<Fragment> fragments = new Vector<Fragment>();
|
||||
|
||||
/*
|
||||
* Add the Main tabs here
|
||||
*/
|
||||
|
||||
fragments.add(Fragment.instantiate(this,StarterFragment.class.getName()));
|
||||
fragments.add(Fragment.instantiate(this,SecondTestFragment.class.getName()));
|
||||
fragments.add(Fragment.instantiate(this,ThanksAndRateFragment.class.getName()));
|
||||
|
||||
mPagerAdapter = new MainPagerAdapter(getFragmentManager(), fragments);
|
||||
|
||||
// Set up the ViewPager with the sections adapter.
|
||||
mViewPager = (ViewPager) findViewById(R.id.pager);
|
||||
mViewPager.setAdapter(mPagerAdapter);
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
|
||||
* one of the sections/tabs/pages.
|
||||
*/
|
||||
public class MainPagerAdapter extends FragmentPagerAdapter {
|
||||
|
||||
private final List<Fragment> mFragments;
|
||||
|
||||
public MainPagerAdapter(final FragmentManager fragmentManager, final List<Fragment> fragments) {
|
||||
super(fragmentManager);
|
||||
mFragments = fragments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(final int position) {
|
||||
// getItem is called to instantiate the fragment for the given page.
|
||||
// Return a PlaceholderFragment (defined as a static inner class
|
||||
// below).
|
||||
return mFragments.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
// Show 3 total pages.
|
||||
return mFragments.size();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragments for activity must be there
|
||||
*/
|
||||
public static class StarterFragment extends Fragment {
|
||||
@Override
|
||||
public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
|
||||
final Bundle savedInstanceState) {
|
||||
final View rootView = inflater.inflate(R.layout.fragment_mainactivity_main, container,
|
||||
false);
|
||||
return rootView;
|
||||
}
|
||||
}
|
||||
|
||||
public static class SecondTestFragment extends Fragment {
|
||||
@Override
|
||||
public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
|
||||
final Bundle savedInstanceState) {
|
||||
final View rootView = inflater.inflate(R.layout.fragment_mainactivity_gotosettings, container,
|
||||
false);
|
||||
return rootView;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ThanksAndRateFragment extends Fragment {
|
||||
@Override
|
||||
public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
|
||||
final Bundle savedInstanceState) {
|
||||
final View rootView = inflater.inflate(R.layout.fragment_mainactivity_thanks_note, container,
|
||||
false);
|
||||
return rootView;
|
||||
}
|
||||
}
|
||||
|
||||
public void openAppSettings(final View view) {
|
||||
startActivity(new Intent(this, GeneralSettingsActivity.class));
|
||||
}
|
||||
|
||||
public void openAddAccount(final View view) {
|
||||
startActivity(new Intent(Settings.ACTION_ADD_ACCOUNT));
|
||||
}
|
||||
|
||||
public void syncAllMessages(final View view) {
|
||||
final Context ctx = getApplicationContext();
|
||||
final ConnectivityMonitor cMon = new ConnectivityMonitor(ctx);
|
||||
|
||||
if (cMon.isValid()) {
|
||||
// Now fetch messages since last stored date
|
||||
final JSONArray smsList = new SmsFetcher(ctx)
|
||||
.bufferizeMessagesSinceDate((long) 0);
|
||||
|
||||
if (smsList != null) {
|
||||
final OCSMSNotificationManager nMgr = new OCSMSNotificationManager(ctx);
|
||||
nMgr.setSyncProcessMsg();
|
||||
new SyncTask(getApplicationContext(), smsList).execute();
|
||||
}
|
||||
}
|
||||
else {
|
||||
Toast.makeText(ctx, ctx.getString(R.string.err_sync_no_connection_available), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
public void selectRemoteAccount(final View view) {
|
||||
startActivity(new Intent(this, AccountListActivity.class));
|
||||
}
|
||||
|
||||
public void openGooglePlayStore(final View view) {
|
||||
Intent intent;
|
||||
try {
|
||||
intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + getPackageName()));
|
||||
|
||||
} catch (final android.content.ActivityNotFoundException anfe) {
|
||||
intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + getPackageName()));
|
||||
}
|
||||
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package fr.unix_experience.owncloud_sms.activities.remote_account;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.app.ListActivity;
|
||||
import android.os.Bundle;
|
||||
import fr.nrz.androidlib.adapters.AndroidAccountAdapter;
|
||||
import fr.unix_experience.owncloud_sms.R;
|
||||
|
||||
public class AccountListActivity extends ListActivity {
|
||||
ArrayList<Account> listItems = new ArrayList<Account>();
|
||||
AndroidAccountAdapter adapter;
|
||||
|
||||
@Override
|
||||
public void onCreate(final Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
|
||||
final AccountManager _accountMgr = AccountManager.get(getBaseContext());
|
||||
|
||||
setContentView(R.layout.restore_activity_accountlist);
|
||||
adapter = new AndroidAccountAdapter(this,
|
||||
android.R.layout.simple_list_item_1,
|
||||
listItems,
|
||||
R.layout.account_list_item,
|
||||
R.id.accountname, ContactListActivity.class);
|
||||
setListAdapter(adapter);
|
||||
|
||||
final Account[] accountList =
|
||||
_accountMgr.getAccountsByType(getString(R.string.account_type));
|
||||
for (final Account element : accountList) {
|
||||
listItems.add(element);
|
||||
}
|
||||
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package fr.unix_experience.owncloud_sms.activities.remote_account;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.app.ListActivity;
|
||||
import android.os.Bundle;
|
||||
import fr.nrz.androidlib.adapters.AndroidAccountAdapter;
|
||||
import fr.unix_experience.owncloud_sms.R;
|
||||
import fr.unix_experience.owncloud_sms.adapters.ContactListAdapter;
|
||||
import fr.unix_experience.owncloud_sms.engine.ASyncContactLoad;
|
||||
|
||||
public class ContactListActivity extends ListActivity implements ASyncContactLoad {
|
||||
|
||||
static AccountManager _accountMgr;
|
||||
ContactListAdapter adapter;
|
||||
|
||||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
assert getIntent().getExtras() != null;
|
||||
|
||||
final String accountName = getIntent().getExtras().getString("account");
|
||||
|
||||
// accountName cannot be null, devel error
|
||||
assert accountName != null;
|
||||
|
||||
_accountMgr = AccountManager.get(getBaseContext());
|
||||
final Account[] myAccountList =
|
||||
_accountMgr.getAccountsByType(getString(R.string.account_type));
|
||||
|
||||
// Init view
|
||||
ArrayList<String> objects = new ArrayList<String>();
|
||||
setContentView(R.layout.restore_activity_contactlist);
|
||||
adapter = new ContactListAdapter(getBaseContext(),
|
||||
android.R.layout.simple_list_item_1,
|
||||
objects,
|
||||
R.layout.contact_list_item,
|
||||
R.id.contactname);
|
||||
|
||||
setListAdapter(adapter);
|
||||
|
||||
for (final Account element : myAccountList) {
|
||||
if (element.name.equals(accountName)) {
|
||||
new ContactLoadTask(element, getBaseContext(), adapter, objects).execute();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This function fetch contacts from the ownCloud instance and generate the list activity
|
||||
private void loadContacts(final Account account) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package fr.unix_experience.owncloud_sms.adapters;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class ContactListAdapter extends ArrayAdapter<String> {
|
||||
private final ArrayList<String> _objects;
|
||||
private static int _itemLayout;
|
||||
private static int _fieldId;
|
||||
|
||||
public ContactListAdapter(final Context context, final int resource,
|
||||
final ArrayList<String> objects, final int itemLayout,
|
||||
final int fieldId) {
|
||||
super(context, resource, resource, objects);
|
||||
_objects = objects;
|
||||
_itemLayout = itemLayout;
|
||||
_fieldId = fieldId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(final int position, final View convertView, final ViewGroup parent) {
|
||||
View v = convertView;
|
||||
if (v == null) {
|
||||
final LayoutInflater inflater =
|
||||
(LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
v = inflater.inflate(_itemLayout, null);
|
||||
}
|
||||
|
||||
final String element = _objects.get(position);
|
||||
|
||||
if (element != null) {
|
||||
final TextView label = (TextView) v.findViewById(_fieldId);
|
||||
if (label != null) {
|
||||
label.setText(element + " >");
|
||||
label.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(final View v) {
|
||||
// @TODO
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
+196
@@ -0,0 +1,196 @@
|
||||
package fr.unix_experience.owncloud_sms.authenticators;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2015, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import org.apache.commons.httpclient.HttpException;
|
||||
import org.apache.commons.httpclient.methods.GetMethod;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
|
||||
import fr.unix_experience.owncloud_sms.activities.LoginActivity;
|
||||
import fr.unix_experience.owncloud_sms.enums.LoginReturnCode;
|
||||
import android.accounts.AbstractAccountAuthenticator;
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountAuthenticatorResponse;
|
||||
import android.accounts.AccountManager;
|
||||
import android.accounts.NetworkErrorException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
public class OwnCloudAuthenticator extends AbstractAccountAuthenticator {
|
||||
// Simple constructor
|
||||
public OwnCloudAuthenticator(Context context) {
|
||||
super(context);
|
||||
_context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle editProperties(AccountAuthenticatorResponse response,
|
||||
String accountType) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle addAccount(AccountAuthenticatorResponse response,
|
||||
String accountType, String authTokenType,
|
||||
String[] requiredFeatures, Bundle options)
|
||||
throws NetworkErrorException {
|
||||
final Bundle result;
|
||||
final Intent intent;
|
||||
|
||||
intent = new Intent(_context, LoginActivity.class);
|
||||
|
||||
result = new Bundle();
|
||||
result.putParcelable(AccountManager.KEY_INTENT, intent);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle confirmCredentials(AccountAuthenticatorResponse response,
|
||||
Account account, Bundle options) throws NetworkErrorException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle getAuthToken(AccountAuthenticatorResponse response,
|
||||
Account account, String authTokenType, Bundle options)
|
||||
throws NetworkErrorException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthTokenLabel(String authTokenType) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle updateCredentials(AccountAuthenticatorResponse response,
|
||||
Account account, String authTokenType, Bundle options)
|
||||
throws NetworkErrorException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle hasFeatures(AccountAuthenticatorResponse response,
|
||||
Account account, String[] features) throws NetworkErrorException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return codes
|
||||
* 1: invalid address
|
||||
* 2: HTTP failed
|
||||
* 3: connexion failed
|
||||
* 4: invalid login
|
||||
* 5: unknown error
|
||||
*/
|
||||
public LoginReturnCode testCredentials() {
|
||||
LoginReturnCode bRet = LoginReturnCode.OK;
|
||||
GetMethod get = null;
|
||||
int status = -1;
|
||||
|
||||
try {
|
||||
get = new GetMethod(_client.getBaseUri() + "/index.php/ocs/cloud/user?format=json");
|
||||
} catch (IllegalArgumentException e) {
|
||||
return LoginReturnCode.INVALID_ADDR;
|
||||
}
|
||||
|
||||
get.addRequestHeader("OCS-APIREQUEST", "true");
|
||||
|
||||
try {
|
||||
status = _client.executeMethod(get);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return LoginReturnCode.INVALID_ADDR;
|
||||
} catch (HttpException e) {
|
||||
return LoginReturnCode.HTTP_CONN_FAILED;
|
||||
} catch (IOException e) {
|
||||
return LoginReturnCode.CONN_FAILED;
|
||||
}
|
||||
|
||||
try {
|
||||
if(isSuccess(status)) {
|
||||
String response = get.getResponseBodyAsString();
|
||||
Log.d(TAG, "Successful response: " + response);
|
||||
|
||||
// Parse the response
|
||||
JSONObject respJSON = new JSONObject(response);
|
||||
JSONObject respOCS = respJSON.getJSONObject(NODE_OCS);
|
||||
JSONObject respData = respOCS.getJSONObject(NODE_DATA);
|
||||
String id = respData.getString(NODE_ID);
|
||||
String displayName = respData.getString(NODE_DISPLAY_NAME);
|
||||
String email = respData.getString(NODE_EMAIL);
|
||||
|
||||
Log.d(TAG, "*** Parsed user information: " + id + " - " + displayName + " - " + email);
|
||||
|
||||
} else {
|
||||
String response = get.getResponseBodyAsString();
|
||||
Log.e(TAG, "Failed response while getting user information ");
|
||||
if (response != null) {
|
||||
Log.e(TAG, "*** status code: " + status + " ; response message: " + response);
|
||||
} else {
|
||||
Log.e(TAG, "*** status code: " + status);
|
||||
}
|
||||
|
||||
if (status == 401) {
|
||||
bRet = LoginReturnCode.INVALID_LOGIN;
|
||||
}
|
||||
else {
|
||||
bRet = LoginReturnCode.UNKNOWN_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Exception while getting OC user information", e);
|
||||
bRet = LoginReturnCode.UNKNOWN_ERROR;
|
||||
|
||||
} finally {
|
||||
get.releaseConnection();
|
||||
}
|
||||
return bRet;
|
||||
}
|
||||
|
||||
private boolean isSuccess(int status) {
|
||||
return (status == HttpStatus.SC_OK);
|
||||
}
|
||||
|
||||
public void setClient(OwnCloudClient oc) {
|
||||
_client = oc;
|
||||
}
|
||||
|
||||
private Context _context;
|
||||
private OwnCloudClient _client;
|
||||
|
||||
private static final String TAG = OwnCloudAuthenticator.class.getSimpleName();
|
||||
|
||||
private static final String NODE_OCS = "ocs";
|
||||
private static final String NODE_DATA = "data";
|
||||
private static final String NODE_ID = "id";
|
||||
private static final String NODE_DISPLAY_NAME= "display-name";
|
||||
private static final String NODE_EMAIL= "email";
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package fr.unix_experience.owncloud_sms.authenticators;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2015, Loic Blot <loic.blot@unix-experience.fr>
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
|
||||
public class OwnCloudAuthenticatorService extends Service {
|
||||
// Instance field that stores the authenticator object
|
||||
private OwnCloudAuthenticator mAuthenticator;
|
||||
@Override
|
||||
public void onCreate() {
|
||||
// Create a new authenticator object
|
||||
mAuthenticator = new OwnCloudAuthenticator(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return mAuthenticator.getIBinder();
|
||||
}
|
||||
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
package fr.unix_experience.owncloud_sms.broadcast_receivers;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2015, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import org.json.JSONArray;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
import fr.unix_experience.owncloud_sms.engine.ASyncSMSSync;
|
||||
import fr.unix_experience.owncloud_sms.engine.ConnectivityMonitor;
|
||||
import fr.unix_experience.owncloud_sms.engine.SmsFetcher;
|
||||
import fr.unix_experience.owncloud_sms.prefs.OCSMSSharedPrefs;
|
||||
|
||||
public class ConnectivityChanged extends BroadcastReceiver implements ASyncSMSSync {
|
||||
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
final ConnectivityMonitor cMon = new ConnectivityMonitor(context);
|
||||
|
||||
final OCSMSSharedPrefs prefs = new OCSMSSharedPrefs(context);
|
||||
|
||||
if (!prefs.pushOnReceive()) {
|
||||
Log.d(TAG,"ConnectivityChanges.onReceive: pushOnReceive is disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
// If data is available and previous dataConnectionState was false, then we need to sync
|
||||
if (cMon.isValid() && dataConnectionAvailable == false) {
|
||||
dataConnectionAvailable = true;
|
||||
Log.d(TAG,"ConnectivityChanged.onReceive, data conn available");
|
||||
checkMessagesAndSend(context);
|
||||
}
|
||||
// No data available and previous dataConnectionState was true
|
||||
else if (dataConnectionAvailable == true && !cMon.isValid()) {
|
||||
dataConnectionAvailable = false;
|
||||
Log.d(TAG,"ConnectivityChanges.onReceive: data conn is off");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkMessagesAndSend(final Context context) {
|
||||
// Get last message synced from preferences
|
||||
final Long lastMessageSynced = (new OCSMSSharedPrefs(context)).getLastMessageDate();
|
||||
Log.d(TAG,"Synced Last:" + lastMessageSynced);
|
||||
|
||||
// Now fetch messages since last stored date
|
||||
final JSONArray smsList = new SmsFetcher(context).bufferizeMessagesSinceDate(lastMessageSynced);
|
||||
|
||||
final ConnectivityMonitor cMon = new ConnectivityMonitor(context);
|
||||
|
||||
// Synchronize if network is valid and there are SMS
|
||||
if (cMon.isValid() && smsList != null) {
|
||||
new SyncTask(context, smsList).execute();
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean dataConnectionAvailable = false;
|
||||
|
||||
private static final String TAG = ConnectivityChanged.class.getSimpleName();
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package fr.unix_experience.owncloud_sms.broadcast_receivers;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2015, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import fr.unix_experience.owncloud_sms.observers.SmsObserver;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
|
||||
public class IncomingSms extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (_mboxObserver == null) {
|
||||
Log.d(TAG,"_mboxObserver == null");
|
||||
_mboxObserver = new SmsObserver(new Handler(), context);
|
||||
context.getContentResolver().
|
||||
registerContentObserver(Uri.parse("content://sms"), true, _mboxObserver);
|
||||
}
|
||||
}
|
||||
|
||||
private static SmsObserver _mboxObserver;
|
||||
|
||||
private static final String TAG = IncomingSms.class.getSimpleName();
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package fr.unix_experience.owncloud_sms.defines;
|
||||
|
||||
public class DefaultPrefs {
|
||||
public final static Integer syncInterval = 15;
|
||||
public final static Boolean pushOnReceive = true;
|
||||
|
||||
public final static Boolean syncWifi = true;
|
||||
public final static Boolean sync2G = true;
|
||||
public final static Boolean syncGPRS = true;
|
||||
public final static Boolean sync3G = true;
|
||||
public final static Boolean sync4G = true;
|
||||
public final static Boolean syncOthers = true;
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package fr.unix_experience.owncloud_sms.engine;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
import fr.unix_experience.owncloud_sms.adapters.ContactListAdapter;
|
||||
import fr.unix_experience.owncloud_sms.exceptions.OCSyncException;
|
||||
|
||||
public interface ASyncContactLoad {
|
||||
class ContactLoadTask extends AsyncTask<Void, Void, Boolean> {
|
||||
private static AccountManager _accountMgr = null;
|
||||
private static Account _account;
|
||||
private final Context _context;
|
||||
private ContactListAdapter _adapter;
|
||||
private ArrayList<String> _objects;
|
||||
|
||||
public ContactLoadTask(final Account account, final Context context,
|
||||
ContactListAdapter adapter, ArrayList<String> objects) {
|
||||
if (_accountMgr == null) {
|
||||
_accountMgr = AccountManager.get(context);
|
||||
}
|
||||
|
||||
_account = account;
|
||||
_context = context;
|
||||
_adapter = adapter;
|
||||
_objects = objects;
|
||||
}
|
||||
@Override
|
||||
protected Boolean doInBackground(final Void... params) {
|
||||
// Create client
|
||||
final String ocURI = _accountMgr.getUserData(_account, "ocURI");
|
||||
if (ocURI == null) {
|
||||
// @TODO: Handle the problem
|
||||
return false;
|
||||
}
|
||||
|
||||
final Uri serverURI = Uri.parse(ocURI);
|
||||
|
||||
final OCSMSOwnCloudClient _client = new OCSMSOwnCloudClient(_context,
|
||||
serverURI, _accountMgr.getUserData(_account, "ocLogin"),
|
||||
_accountMgr.getPassword(_account));
|
||||
|
||||
try {
|
||||
if (_client.getServerAPIVersion() < 2) {
|
||||
// @TODO: handle error
|
||||
return false;
|
||||
}
|
||||
|
||||
JSONArray phoneNumbers = _client.getServerPhoneNumbers();
|
||||
Log.d(TAG, phoneNumbers.toString());
|
||||
for (int i = 0; i < phoneNumbers.length(); i++) {
|
||||
String phone = phoneNumbers.getString(i);
|
||||
_objects.add(phone);
|
||||
}
|
||||
|
||||
} catch (JSONException e) {
|
||||
// @TODO: handle error
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
} catch (final OCSyncException e) {
|
||||
// @TODO: handle error
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
protected void onPostExecute(final Boolean success) {
|
||||
_adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
static final String TAG = ASyncContactLoad.class.getSimpleName();
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package fr.unix_experience.owncloud_sms.engine;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2015, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import org.json.JSONArray;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
import fr.unix_experience.owncloud_sms.R;
|
||||
import fr.unix_experience.owncloud_sms.exceptions.OCSyncException;
|
||||
import fr.unix_experience.owncloud_sms.notifications.OCSMSNotificationManager;
|
||||
|
||||
public interface ASyncSMSSync {
|
||||
class SyncTask extends AsyncTask<Void, Void, Void> {
|
||||
public SyncTask(final Context context, final JSONArray smsList) {
|
||||
_context = context;
|
||||
_smsList = smsList;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(final Void... params) {
|
||||
final OCSMSNotificationManager nMgr = new OCSMSNotificationManager(_context);
|
||||
|
||||
// Get ownCloud SMS account list
|
||||
final AccountManager _accountMgr = AccountManager.get(_context);
|
||||
|
||||
final Account[] myAccountList = _accountMgr.getAccountsByType(_context.getString(R.string.account_type));
|
||||
for (final Account element : myAccountList) {
|
||||
final Uri serverURI = Uri.parse(_accountMgr.getUserData(element, "ocURI"));
|
||||
|
||||
final OCSMSOwnCloudClient _client = new OCSMSOwnCloudClient(_context,
|
||||
serverURI, _accountMgr.getUserData(element, "ocLogin"),
|
||||
_accountMgr.getPassword(element));
|
||||
|
||||
try {
|
||||
_client.doPushRequest(_smsList);
|
||||
nMgr.dropSyncErrorMsg();
|
||||
} catch (final OCSyncException e) {
|
||||
Log.e(TAG, _context.getString(e.getErrorId()));
|
||||
nMgr.setSyncErrorMsg(_context.getString(e.getErrorId()));
|
||||
}
|
||||
}
|
||||
nMgr.dropSyncProcessMsg();
|
||||
return null;
|
||||
}
|
||||
|
||||
private final Context _context;
|
||||
private final JSONArray _smsList;
|
||||
}
|
||||
|
||||
static final String TAG = ASyncSMSSync.class.getSimpleName();
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package fr.unix_experience.owncloud_sms.engine;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2015, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.telephony.TelephonyManager;
|
||||
import fr.unix_experience.owncloud_sms.prefs.OCSMSSharedPrefs;
|
||||
|
||||
public class ConnectivityMonitor {
|
||||
public ConnectivityMonitor(final Context context) {
|
||||
_context = context;
|
||||
}
|
||||
|
||||
// Valid connection = WiFi or Mobile data
|
||||
public boolean isValid() {
|
||||
if (_cMgr == null) {
|
||||
_cMgr = (ConnectivityManager) _context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
}
|
||||
|
||||
final android.net.NetworkInfo niWiFi = _cMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
|
||||
final android.net.NetworkInfo niMobile = _cMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
|
||||
|
||||
if (niWiFi.isAvailable() || niMobile.isAvailable()) {
|
||||
// Load the connectivity manager to determine on which network we are connected
|
||||
final NetworkInfo netInfo = _cMgr.getActiveNetworkInfo();
|
||||
if (netInfo == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final OCSMSSharedPrefs prefs = new OCSMSSharedPrefs(_context);
|
||||
|
||||
// Check
|
||||
switch (netInfo.getType()) {
|
||||
case ConnectivityManager.TYPE_WIFI:
|
||||
return prefs.syncInWifi();
|
||||
case ConnectivityManager.TYPE_MOBILE:
|
||||
switch (netInfo.getSubtype()) {
|
||||
case TelephonyManager.NETWORK_TYPE_EDGE:
|
||||
case TelephonyManager.NETWORK_TYPE_CDMA:
|
||||
case TelephonyManager.NETWORK_TYPE_1xRTT:
|
||||
case TelephonyManager.NETWORK_TYPE_IDEN:
|
||||
return prefs.syncIn2G();
|
||||
case TelephonyManager.NETWORK_TYPE_GPRS:
|
||||
return prefs.syncInGPRS();
|
||||
case TelephonyManager.NETWORK_TYPE_HSDPA:
|
||||
case TelephonyManager.NETWORK_TYPE_HSPA:
|
||||
case TelephonyManager.NETWORK_TYPE_HSUPA:
|
||||
case TelephonyManager.NETWORK_TYPE_UMTS:
|
||||
case TelephonyManager.NETWORK_TYPE_EHRPD:
|
||||
case TelephonyManager.NETWORK_TYPE_EVDO_B:
|
||||
case TelephonyManager.NETWORK_TYPE_HSPAP:
|
||||
return prefs.syncIn3G();
|
||||
case TelephonyManager.NETWORK_TYPE_LTE:
|
||||
return prefs.syncIn4G();
|
||||
default:
|
||||
return prefs.syncInOtherModes();
|
||||
}
|
||||
default:
|
||||
return prefs.syncInOtherModes();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private ConnectivityManager _cMgr;
|
||||
private final Context _context;
|
||||
}
|
||||
@@ -0,0 +1,410 @@
|
||||
package fr.unix_experience.owncloud_sms.engine;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2015, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.ConnectException;
|
||||
|
||||
import org.apache.commons.httpclient.HttpException;
|
||||
import org.apache.commons.httpclient.HttpMethod;
|
||||
import org.apache.commons.httpclient.methods.GetMethod;
|
||||
import org.apache.commons.httpclient.methods.PostMethod;
|
||||
import org.apache.commons.httpclient.methods.StringRequestEntity;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
import com.owncloud.android.lib.common.OwnCloudClientFactory;
|
||||
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
|
||||
|
||||
import fr.unix_experience.owncloud_sms.R;
|
||||
import fr.unix_experience.owncloud_sms.enums.OCSyncErrorType;
|
||||
import fr.unix_experience.owncloud_sms.exceptions.OCSyncException;
|
||||
import fr.unix_experience.owncloud_sms.prefs.OCSMSSharedPrefs;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class OCSMSOwnCloudClient {
|
||||
|
||||
public OCSMSOwnCloudClient(final Context context, final Uri serverURI, final String accountName, final String accountPassword) {
|
||||
_context = context;
|
||||
|
||||
_ocClient = OwnCloudClientFactory.createOwnCloudClient(
|
||||
serverURI, _context, true);
|
||||
|
||||
// Set basic credentials
|
||||
_ocClient.setCredentials(
|
||||
OwnCloudCredentialsFactory.newBasicCredentials(accountName, accountPassword)
|
||||
);
|
||||
|
||||
_serverAPIVersion = 1;
|
||||
}
|
||||
|
||||
public Integer getServerAPIVersion() throws OCSyncException {
|
||||
final GetMethod get = createGetVersionRequest();
|
||||
final JSONObject obj = doHttpRequest(get, true);
|
||||
if (obj == null) {
|
||||
// Return default version
|
||||
return 1;
|
||||
}
|
||||
|
||||
try {
|
||||
_serverAPIVersion = obj.getInt("version");
|
||||
}
|
||||
catch (final JSONException e) {
|
||||
Log.e(TAG, "No version received from server, assuming version 1", e);
|
||||
_serverAPIVersion = 1;
|
||||
}
|
||||
|
||||
return _serverAPIVersion;
|
||||
}
|
||||
|
||||
public JSONArray getServerPhoneNumbers() throws OCSyncException {
|
||||
final GetMethod get = createGetPhoneListRequest();
|
||||
final JSONObject obj = doHttpRequest(get, true);
|
||||
if (obj == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Log.d(TAG, obj.toString());
|
||||
try {
|
||||
return obj.getJSONArray("phoneList");
|
||||
} catch (final JSONException e) {
|
||||
Log.e(TAG, "No phonelist received from server, empty it", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void doPushRequest(final JSONArray smsList) throws OCSyncException {
|
||||
/**
|
||||
* If we need other API push, set it here
|
||||
*/
|
||||
switch (_serverAPIVersion) {
|
||||
case 1:
|
||||
default: doPushRequestV1(smsList); break;
|
||||
}
|
||||
}
|
||||
|
||||
public void doPushRequestV1(JSONArray smsList) throws OCSyncException {
|
||||
// We need to save this date as a step for connectivity change
|
||||
Long lastMsgDate = (long) 0;
|
||||
|
||||
if (smsList == null) {
|
||||
final GetMethod get = createGetSmsIdListRequest();
|
||||
final JSONObject smsGetObj = doHttpRequest(get);
|
||||
if (smsGetObj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
JSONObject smsBoxes = new JSONObject();
|
||||
JSONArray inboxSmsList = null, sentSmsList = null, draftsSmsList = null;
|
||||
try {
|
||||
smsBoxes = smsGetObj.getJSONObject("smslist");
|
||||
} catch (final JSONException e) {
|
||||
try {
|
||||
smsGetObj.getJSONArray("smslist");
|
||||
} catch (final JSONException e2) {
|
||||
Log.e(TAG, "Invalid datas received from server (doPushRequest, get SMS list)", e);
|
||||
throw new OCSyncException(R.string.err_sync_get_smslist, OCSyncErrorType.PARSE);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
inboxSmsList = smsBoxes.getJSONArray("inbox");
|
||||
} catch (final JSONException e) {
|
||||
Log.d(TAG, "No inbox Sms received from server (doPushRequest, get SMS list)");
|
||||
}
|
||||
|
||||
try {
|
||||
sentSmsList = smsBoxes.getJSONArray("sent");
|
||||
} catch (final JSONException e) {
|
||||
Log.d(TAG, "No sent Sms received from server (doPushRequest, get SMS list)");
|
||||
}
|
||||
|
||||
try {
|
||||
draftsSmsList = smsBoxes.getJSONArray("drafts");
|
||||
} catch (final JSONException e) {
|
||||
Log.d(TAG, "No drafts Sms received from server (doPushRequest, get SMS list)");
|
||||
}
|
||||
|
||||
final SmsFetcher fetcher = new SmsFetcher(_context);
|
||||
fetcher.setExistingInboxMessages(inboxSmsList);
|
||||
fetcher.setExistingSentMessages(sentSmsList);
|
||||
fetcher.setExistingDraftsMessages(draftsSmsList);
|
||||
|
||||
smsList = fetcher.fetchAllMessages();
|
||||
|
||||
// Get maximum message date present in smsList to keep a step when connectivity changes
|
||||
lastMsgDate = fetcher.getLastMessageDate();
|
||||
}
|
||||
|
||||
if (smsList.length() == 0) {
|
||||
Log.d(TAG, "No new SMS to sync, sync done");
|
||||
return;
|
||||
}
|
||||
|
||||
final PostMethod post = createPushRequest(smsList);
|
||||
if (post == null) {
|
||||
Log.e(TAG,"Push request for POST is null");
|
||||
throw new OCSyncException(R.string.err_sync_craft_http_request, OCSyncErrorType.IO);
|
||||
}
|
||||
|
||||
final JSONObject obj = doHttpRequest(post);
|
||||
if (obj == null) {
|
||||
Log.e(TAG,"Request failed. It doesn't return a valid JSON Object");
|
||||
throw new OCSyncException(R.string.err_sync_push_request, OCSyncErrorType.IO);
|
||||
}
|
||||
|
||||
Boolean pushStatus;
|
||||
String pushMessage;
|
||||
try {
|
||||
pushStatus = obj.getBoolean("status");
|
||||
pushMessage = obj.getString("msg");
|
||||
}
|
||||
catch (final JSONException e) {
|
||||
Log.e(TAG, "Invalid datas received from server", e);
|
||||
throw new OCSyncException(R.string.err_sync_push_request_resp, OCSyncErrorType.PARSE);
|
||||
}
|
||||
|
||||
// Push was OK, we can save the lastMessageDate which was saved to server
|
||||
(new OCSMSSharedPrefs(_context)).setLastMessageDate(lastMsgDate);
|
||||
|
||||
Log.d(TAG, "SMS Push request said: status " + pushStatus + " - " + pushMessage);
|
||||
}
|
||||
|
||||
public GetMethod createGetVersionRequest() {
|
||||
return createGetRequest(OC_GET_VERSION);
|
||||
}
|
||||
|
||||
public GetMethod createGetPhoneListRequest() {
|
||||
return createGetRequest(OC_GET_PHONELIST);
|
||||
}
|
||||
|
||||
public GetMethod createGetSmsIdListRequest() {
|
||||
return createGetRequest(OC_GET_ALL_SMS_IDS);
|
||||
}
|
||||
|
||||
public GetMethod createGetSmsIdListWithStateRequest() {
|
||||
return createGetRequest(OC_GET_ALL_SMS_IDS_WITH_STATUS);
|
||||
}
|
||||
|
||||
public GetMethod createGetLastSmsTimestampRequest() {
|
||||
return createGetRequest(OC_GET_LAST_MSG_TIMESTAMP);
|
||||
}
|
||||
|
||||
private GetMethod createGetRequest(final String oc_call) {
|
||||
final GetMethod get = new GetMethod(_ocClient.getBaseUri() + oc_call);
|
||||
get.addRequestHeader("OCS-APIREQUEST", "true");
|
||||
return get;
|
||||
}
|
||||
|
||||
public PostMethod createPushRequest() throws OCSyncException {
|
||||
final SmsFetcher fetcher = new SmsFetcher(_context);
|
||||
final JSONArray smsList = fetcher.fetchAllMessages();
|
||||
return createPushRequest(smsList);
|
||||
}
|
||||
|
||||
public PostMethod createPushRequest(final JSONArray smsList) throws OCSyncException {
|
||||
final JSONObject obj = createPushJSONObject(smsList);
|
||||
if (obj == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final StringRequestEntity ent = createJSONRequestEntity(obj);
|
||||
if (ent == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final PostMethod post = new PostMethod(_ocClient.getBaseUri() + OC_PUSH_ROUTE);
|
||||
post.addRequestHeader("OCS-APIREQUEST", "true");
|
||||
post.setRequestEntity(ent);
|
||||
|
||||
return post;
|
||||
}
|
||||
|
||||
private JSONObject createPushJSONObject(final JSONArray smsList) throws OCSyncException {
|
||||
if (smsList == null) {
|
||||
Log.e(TAG,"NULL SMS List");
|
||||
throw new OCSyncException(R.string.err_sync_create_json_null_smslist, OCSyncErrorType.IO);
|
||||
}
|
||||
|
||||
final JSONObject reqJSON = new JSONObject();
|
||||
|
||||
try {
|
||||
reqJSON.put("smsDatas", smsList);
|
||||
reqJSON.put("smsCount", smsList == null ? 0 : smsList.length());
|
||||
} catch (final JSONException e) {
|
||||
Log.e(TAG,"JSON Exception when creating JSON request object");
|
||||
throw new OCSyncException(R.string.err_sync_create_json_put_smslist, OCSyncErrorType.PARSE);
|
||||
}
|
||||
|
||||
return reqJSON;
|
||||
}
|
||||
|
||||
private StringRequestEntity createJSONRequestEntity(final JSONObject obj) throws OCSyncException {
|
||||
StringRequestEntity requestEntity;
|
||||
try {
|
||||
requestEntity = new StringRequestEntity(
|
||||
obj.toString(),
|
||||
"application/json",
|
||||
"UTF-8");
|
||||
|
||||
} catch (final UnsupportedEncodingException e) {
|
||||
Log.e(TAG,"Unsupported encoding when generating request");
|
||||
throw new OCSyncException(R.string.err_sync_create_json_request_encoding, OCSyncErrorType.PARSE);
|
||||
}
|
||||
|
||||
return requestEntity;
|
||||
}
|
||||
|
||||
private JSONObject doHttpRequest(final HttpMethod req) throws OCSyncException {
|
||||
return doHttpRequest(req, false);
|
||||
}
|
||||
|
||||
// skipError permit to skip invalid JSON datas
|
||||
private JSONObject doHttpRequest(final HttpMethod req, final Boolean skipError) throws OCSyncException {
|
||||
JSONObject respJSON = null;
|
||||
int status = 0;
|
||||
|
||||
// We try maximumHttpReqTries because sometimes network is slow or unstable
|
||||
int tryNb = 0;
|
||||
final ConnectivityMonitor cMon = new ConnectivityMonitor(_context);
|
||||
|
||||
while (tryNb < maximumHttpReqTries) {
|
||||
tryNb++;
|
||||
|
||||
if (!cMon.isValid()) {
|
||||
if (tryNb == maximumHttpReqTries) {
|
||||
req.releaseConnection();
|
||||
throw new OCSyncException(R.string.err_sync_no_connection_available, OCSyncErrorType.IO);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
status = _ocClient.executeMethod(req);
|
||||
|
||||
Log.d(TAG, "HTTP Request done at try " + tryNb);
|
||||
|
||||
// Force loop exit
|
||||
tryNb = maximumHttpReqTries;
|
||||
} catch (final ConnectException e) {
|
||||
Log.e(TAG, "Unable to perform a connection to ownCloud instance", e);
|
||||
|
||||
// If it's the last try
|
||||
if (tryNb == maximumHttpReqTries) {
|
||||
req.releaseConnection();
|
||||
throw new OCSyncException(R.string.err_sync_http_request_connect, OCSyncErrorType.IO);
|
||||
}
|
||||
} catch (final HttpException e) {
|
||||
Log.e(TAG, "Unable to perform a connection to ownCloud instance", e);
|
||||
|
||||
// If it's the last try
|
||||
if (tryNb == maximumHttpReqTries) {
|
||||
req.releaseConnection();
|
||||
throw new OCSyncException(R.string.err_sync_http_request_httpexception, OCSyncErrorType.IO);
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
Log.e(TAG, "Unable to perform a connection to ownCloud instance", e);
|
||||
|
||||
// If it's the last try
|
||||
if (tryNb == maximumHttpReqTries) {
|
||||
req.releaseConnection();
|
||||
throw new OCSyncException(R.string.err_sync_http_request_ioexception, OCSyncErrorType.IO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(status == HttpStatus.SC_OK) {
|
||||
String response = null;
|
||||
try {
|
||||
response = req.getResponseBodyAsString();
|
||||
} catch (final IOException e) {
|
||||
Log.e(TAG, "Unable to parse server response", e);
|
||||
throw new OCSyncException(R.string.err_sync_http_request_resp, OCSyncErrorType.IO);
|
||||
}
|
||||
//Log.d(TAG, "Successful response: " + response);
|
||||
|
||||
// Parse the response
|
||||
try {
|
||||
respJSON = new JSONObject(response);
|
||||
} catch (final JSONException e) {
|
||||
if (skipError == false) {
|
||||
if (response.contains("ownCloud") && response.contains("DOCTYPE")) {
|
||||
Log.e(TAG, "OcSMS app not enabled or ownCloud upgrade is required");
|
||||
throw new OCSyncException(R.string.err_sync_ocsms_not_installed_or_oc_upgrade_required,
|
||||
OCSyncErrorType.SERVER_ERROR);
|
||||
}
|
||||
else {
|
||||
Log.e(TAG, "Unable to parse server response", e);
|
||||
throw new OCSyncException(R.string.err_sync_http_request_parse_resp, OCSyncErrorType.PARSE);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
} else if (status == HttpStatus.SC_FORBIDDEN) {
|
||||
// Authentication failed
|
||||
throw new OCSyncException(R.string.err_sync_auth_failed, OCSyncErrorType.AUTH);
|
||||
} else {
|
||||
// Unk error
|
||||
String response = null;
|
||||
try {
|
||||
response = req.getResponseBodyAsString();
|
||||
} catch (final IOException e) {
|
||||
Log.e(TAG, "Unable to parse server response", e);
|
||||
throw new OCSyncException(R.string.err_sync_http_request_resp, OCSyncErrorType.PARSE);
|
||||
}
|
||||
|
||||
Log.e(TAG, "Server set unhandled HTTP return code " + status);
|
||||
if (response != null) {
|
||||
Log.e(TAG, "Status code: " + status + ". Response message: " + response);
|
||||
} else {
|
||||
Log.e(TAG, "Status code: " + status);
|
||||
}
|
||||
throw new OCSyncException(R.string.err_sync_http_request_returncode_unhandled, OCSyncErrorType.SERVER_ERROR);
|
||||
}
|
||||
return respJSON;
|
||||
}
|
||||
|
||||
public OwnCloudClient getOCClient() { return _ocClient; }
|
||||
|
||||
private static int maximumHttpReqTries = 3;
|
||||
|
||||
private final OwnCloudClient _ocClient;
|
||||
private final Context _context;
|
||||
|
||||
private Integer _serverAPIVersion;
|
||||
|
||||
private static String OC_GET_VERSION = "/index.php/apps/ocsms/get/apiversion?format=json";
|
||||
private static String OC_GET_ALL_SMS_IDS = "/index.php/apps/ocsms/get/smsidlist?format=json";
|
||||
private static String OC_GET_ALL_SMS_IDS_WITH_STATUS = "/index.php/apps/ocsms/get/smsidstate?format=json";
|
||||
private static String OC_GET_LAST_MSG_TIMESTAMP = "/index.php/apps/ocsms/get/lastmsgtime?format=json";
|
||||
private static String OC_PUSH_ROUTE = "/index.php/apps/ocsms/push?format=json";
|
||||
private static String OC_GET_PHONELIST = "/index.php/apps/ocsms/get/phones/numberlist?format=json";
|
||||
|
||||
private static final String TAG = OCSMSOwnCloudClient.class.getSimpleName();
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,325 @@
|
||||
package fr.unix_experience.owncloud_sms.engine;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2015, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import fr.unix_experience.owncloud_sms.enums.MailboxID;
|
||||
import fr.unix_experience.owncloud_sms.providers.SmsDataProvider;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.util.Log;
|
||||
|
||||
public class SmsFetcher {
|
||||
public SmsFetcher(Context ct) {
|
||||
_lastMsgDate = (long) 0;
|
||||
_context = ct;
|
||||
|
||||
_existingInboxMessages = null;
|
||||
_existingSentMessages = null;
|
||||
_existingDraftsMessages = null;
|
||||
}
|
||||
|
||||
public JSONArray fetchAllMessages() {
|
||||
_jsonDataDump = new JSONArray();
|
||||
bufferizeMailboxMessages(MailboxID.INBOX);
|
||||
bufferizeMailboxMessages(MailboxID.SENT);
|
||||
bufferizeMailboxMessages(MailboxID.DRAFTS);
|
||||
return _jsonDataDump;
|
||||
}
|
||||
|
||||
private void bufferizeMailboxMessages(MailboxID mbID) {
|
||||
String mbURI = mapMailboxIDToURI(mbID);
|
||||
|
||||
if (_context == null || mbURI == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mbID != MailboxID.INBOX && mbID != MailboxID.SENT &&
|
||||
mbID != MailboxID.DRAFTS) {
|
||||
Log.e(TAG,"Unhandled MailboxID " + mbID.ordinal());
|
||||
return;
|
||||
}
|
||||
|
||||
// We generate a ID list for this message box
|
||||
String existingIDs = buildExistingMessagesString(mbID);
|
||||
|
||||
Cursor c = null;
|
||||
if (existingIDs.length() > 0) {
|
||||
c = (new SmsDataProvider(_context)).query(mbURI, "_id NOT IN (" + existingIDs + ")");
|
||||
}
|
||||
else {
|
||||
c = (new SmsDataProvider(_context)).query(mbURI);
|
||||
}
|
||||
|
||||
// Reading mailbox
|
||||
if (c != null && c.getCount() > 0) {
|
||||
c.moveToFirst();
|
||||
do {
|
||||
JSONObject entry = new JSONObject();
|
||||
|
||||
try {
|
||||
for(int idx=0;idx<c.getColumnCount();idx++) {
|
||||
String colName = c.getColumnName(idx);
|
||||
|
||||
// Id column is must be an integer
|
||||
if (colName.equals(new String("_id")) ||
|
||||
colName.equals(new String("type"))) {
|
||||
entry.put(colName, c.getInt(idx));
|
||||
}
|
||||
// Seen and read must be pseudo boolean
|
||||
else if (colName.equals(new String("read")) ||
|
||||
colName.equals(new String("seen"))) {
|
||||
entry.put(colName, c.getInt(idx) > 0 ? "true" : "false");
|
||||
}
|
||||
else {
|
||||
// Special case for date, we need to record last without searching
|
||||
if (colName.equals(new String("date"))) {
|
||||
final Long tmpDate = c.getLong(idx);
|
||||
if (tmpDate > _lastMsgDate) {
|
||||
_lastMsgDate = tmpDate;
|
||||
}
|
||||
}
|
||||
entry.put(colName, c.getString(idx));
|
||||
}
|
||||
}
|
||||
|
||||
// Mailbox ID is required by server
|
||||
entry.put("mbox", mbID.ordinal());
|
||||
|
||||
_jsonDataDump.put(entry);
|
||||
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "JSON Exception when reading SMS Mailbox", e);
|
||||
c.close();
|
||||
}
|
||||
}
|
||||
while(c.moveToNext());
|
||||
|
||||
Log.d(TAG, c.getCount() + " messages read from " + mbURI);
|
||||
|
||||
c.close();
|
||||
}
|
||||
}
|
||||
|
||||
// Used by Content Observer
|
||||
public JSONArray getLastMessage(MailboxID mbID) {
|
||||
String mbURI = mapMailboxIDToURI(mbID);
|
||||
|
||||
if (_context == null || mbURI == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Fetch Sent SMS Message from Built-in Content Provider
|
||||
Cursor c = (new SmsDataProvider(_context)).query(mbURI);
|
||||
|
||||
c.moveToNext();
|
||||
|
||||
// We create a list of strings to store results
|
||||
JSONArray results = new JSONArray();
|
||||
|
||||
JSONObject entry = new JSONObject();
|
||||
|
||||
try {
|
||||
Integer mboxId = -1;
|
||||
for(int idx = 0;idx < c.getColumnCount(); idx++) {
|
||||
String colName = c.getColumnName(idx);
|
||||
|
||||
// Id column is must be an integer
|
||||
if (colName.equals(new String("_id"))) {
|
||||
entry.put(colName, c.getInt(idx));
|
||||
}
|
||||
// Seen and read must be pseudo boolean
|
||||
else if (colName.equals(new String("read")) ||
|
||||
colName.equals(new String("seen"))) {
|
||||
entry.put(colName, c.getInt(idx) > 0 ? "true" : "false");
|
||||
}
|
||||
else if (colName.equals(new String("type"))) {
|
||||
mboxId = c.getInt(idx);
|
||||
entry.put(colName, c.getInt(idx));
|
||||
}
|
||||
else {
|
||||
entry.put(colName, c.getString(idx));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Mailbox ID is required by server
|
||||
* mboxId is greater than server mboxId by 1 because types
|
||||
* aren't indexed in the same mean
|
||||
*/
|
||||
entry.put("mbox", (mboxId - 1));
|
||||
|
||||
results.put(entry);
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "JSON Exception when reading SMS Mailbox", e);
|
||||
c.close();
|
||||
}
|
||||
|
||||
c.close();
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
// Used by ConnectivityChanged Event
|
||||
public JSONArray bufferizeMessagesSinceDate(Long sinceDate) {
|
||||
_jsonDataDump = new JSONArray();
|
||||
bufferizeMessagesSinceDate(MailboxID.INBOX, sinceDate);
|
||||
bufferizeMessagesSinceDate(MailboxID.SENT, sinceDate);
|
||||
bufferizeMessagesSinceDate(MailboxID.DRAFTS, sinceDate);
|
||||
return _jsonDataDump;
|
||||
}
|
||||
|
||||
// Used by ConnectivityChanged Event
|
||||
public void bufferizeMessagesSinceDate(MailboxID mbID, Long sinceDate) {
|
||||
String mbURI = mapMailboxIDToURI(mbID);
|
||||
|
||||
if (_context == null || mbURI == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Cursor c = new SmsDataProvider(_context).query(mbURI, "date > ?", new String[] { sinceDate.toString() });
|
||||
|
||||
// Reading mailbox
|
||||
if (c != null && c.getCount() > 0) {
|
||||
c.moveToFirst();
|
||||
do {
|
||||
JSONObject entry = new JSONObject();
|
||||
|
||||
try {
|
||||
for(int idx=0;idx<c.getColumnCount();idx++) {
|
||||
String colName = c.getColumnName(idx);
|
||||
|
||||
// Id column is must be an integer
|
||||
if (colName.equals(new String("_id")) ||
|
||||
colName.equals(new String("type"))) {
|
||||
entry.put(colName, c.getInt(idx));
|
||||
|
||||
// bufferize Id for future use
|
||||
if (colName.equals(new String("_id"))) {
|
||||
}
|
||||
}
|
||||
// Seen and read must be pseudo boolean
|
||||
else if (colName.equals(new String("read")) ||
|
||||
colName.equals(new String("seen"))) {
|
||||
entry.put(colName, c.getInt(idx) > 0 ? "true" : "false");
|
||||
}
|
||||
else {
|
||||
// Special case for date, we need to record last without searching
|
||||
if (colName.equals(new String("date"))) {
|
||||
final Long tmpDate = c.getLong(idx);
|
||||
if (tmpDate > _lastMsgDate) {
|
||||
_lastMsgDate = tmpDate;
|
||||
}
|
||||
}
|
||||
entry.put(colName, c.getString(idx));
|
||||
}
|
||||
}
|
||||
|
||||
// Mailbox ID is required by server
|
||||
entry.put("mbox", mbID.ordinal());
|
||||
|
||||
_jsonDataDump.put(entry);
|
||||
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "JSON Exception when reading SMS Mailbox", e);
|
||||
c.close();
|
||||
}
|
||||
}
|
||||
while(c.moveToNext());
|
||||
|
||||
Log.d(TAG, c.getCount() + " messages read from " + mbURI);
|
||||
|
||||
c.close();
|
||||
}
|
||||
}
|
||||
|
||||
private String mapMailboxIDToURI(MailboxID mbID) {
|
||||
if (mbID == MailboxID.INBOX) {
|
||||
return "content://sms/inbox";
|
||||
}
|
||||
else if (mbID == MailboxID.DRAFTS) {
|
||||
return "content://sms/drafts";
|
||||
}
|
||||
else if (mbID == MailboxID.SENT) {
|
||||
return "content://sms/sent";
|
||||
}
|
||||
else if (mbID == MailboxID.ALL) {
|
||||
return "content://sms";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String buildExistingMessagesString(MailboxID _mbID) {
|
||||
JSONArray existingMessages = null;
|
||||
if (_mbID == MailboxID.INBOX) {
|
||||
existingMessages = _existingInboxMessages;
|
||||
} else if (_mbID == MailboxID.DRAFTS) {
|
||||
existingMessages = _existingDraftsMessages;
|
||||
} else if (_mbID == MailboxID.SENT) {
|
||||
existingMessages = _existingSentMessages;
|
||||
}
|
||||
// Note: The default case isn't possible, we check the mailbox before
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (existingMessages != null) {
|
||||
int len = existingMessages.length();
|
||||
for (int i = 0; i < len; i++) {
|
||||
try {
|
||||
if (sb.length() > 0) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(existingMessages.getInt(i));
|
||||
} catch (JSONException e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void setExistingInboxMessages(JSONArray inboxMessages) {
|
||||
_existingInboxMessages = inboxMessages;
|
||||
}
|
||||
|
||||
public void setExistingSentMessages(JSONArray sentMessages) {
|
||||
_existingSentMessages = sentMessages;
|
||||
}
|
||||
|
||||
public void setExistingDraftsMessages(JSONArray draftMessages) {
|
||||
_existingDraftsMessages = draftMessages;
|
||||
}
|
||||
|
||||
public Long getLastMessageDate() {
|
||||
return _lastMsgDate;
|
||||
}
|
||||
|
||||
private Context _context;
|
||||
private JSONArray _jsonDataDump;
|
||||
private JSONArray _existingInboxMessages;
|
||||
private JSONArray _existingSentMessages;
|
||||
private JSONArray _existingDraftsMessages;
|
||||
|
||||
private Long _lastMsgDate;
|
||||
|
||||
private static final String TAG = SmsFetcher.class.getSimpleName();
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package fr.unix_experience.owncloud_sms.enums;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2015, Loic Blot <loic.blot@unix-experience.fr>
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
public enum LoginReturnCode {
|
||||
OK,
|
||||
INVALID_ADDR,
|
||||
HTTP_CONN_FAILED,
|
||||
CONN_FAILED,
|
||||
INVALID_LOGIN,
|
||||
UNKNOWN_ERROR,
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package fr.unix_experience.owncloud_sms.enums;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2015, Loic Blot <loic.blot@unix-experience.fr>
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
public enum MailboxID {
|
||||
INBOX,
|
||||
SENT,
|
||||
DRAFTS,
|
||||
ALL,
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package fr.unix_experience.owncloud_sms.enums;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2015, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
public enum OCSMSNotificationType {
|
||||
SYNC,
|
||||
SYNC_FAILED,
|
||||
DEBUG,
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package fr.unix_experience.owncloud_sms.enums;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2015, Loic Blot <loic.blot@unix-experience.fr>
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
public enum OCSyncErrorType {
|
||||
IO,
|
||||
PARSE,
|
||||
AUTH,
|
||||
SERVER_ERROR,
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package fr.unix_experience.owncloud_sms.exceptions;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2015, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import fr.unix_experience.owncloud_sms.enums.OCSyncErrorType;
|
||||
|
||||
public class OCSyncException extends Exception {
|
||||
/**
|
||||
* Serial, generated by Eclipse to be compliant with JAVA
|
||||
*/
|
||||
private static final long serialVersionUID = -4277316598892180792L;
|
||||
|
||||
public OCSyncException(int errorId, OCSyncErrorType errorType) {
|
||||
_errorId = errorId;
|
||||
_errorType = errorType;
|
||||
}
|
||||
|
||||
public int getErrorId() {
|
||||
return _errorId;
|
||||
}
|
||||
|
||||
public OCSyncErrorType getErrorType() {
|
||||
return _errorType;
|
||||
}
|
||||
|
||||
private int _errorId;
|
||||
private OCSyncErrorType _errorType;
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
package fr.unix_experience.owncloud_sms.notifications;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2015, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import android.content.Context;
|
||||
import fr.nrz.androidlib.notifications.NrzNotification;
|
||||
import fr.unix_experience.owncloud_sms.R;
|
||||
import fr.unix_experience.owncloud_sms.enums.OCSMSNotificationType;
|
||||
|
||||
public class OCSMSNotificationManager {
|
||||
|
||||
public OCSMSNotificationManager(final Context context) {
|
||||
_context = context;
|
||||
_notification = new NrzNotification(_context, R.drawable.ic_stat_ocsms);
|
||||
}
|
||||
|
||||
public void setSyncProcessMsg() {
|
||||
createNotificationIfPossible(OCSMSNotificationType.SYNC,
|
||||
_context.getString(R.string.sync_title),
|
||||
_context.getString(R.string.sync_inprogress)
|
||||
);
|
||||
}
|
||||
|
||||
public void dropSyncProcessMsg() {
|
||||
_notification.cancelNotify(OCSMSNotificationType.SYNC.ordinal());
|
||||
}
|
||||
|
||||
public void setSyncErrorMsg(final String errMsg) {
|
||||
createNotificationIfPossible(OCSMSNotificationType.SYNC_FAILED,
|
||||
_context.getString(R.string.sync_title),
|
||||
_context.getString(R.string.fatal_error) + "\n" + errMsg
|
||||
);
|
||||
}
|
||||
|
||||
public void dropSyncErrorMsg() {
|
||||
_notification.cancelNotify(OCSMSNotificationType.SYNC_FAILED.ordinal());
|
||||
}
|
||||
|
||||
public void setDebugMsg(final String errMsg) {
|
||||
createNotificationIfPossible(OCSMSNotificationType.DEBUG,
|
||||
"DEBUG", errMsg
|
||||
);
|
||||
}
|
||||
|
||||
private void createNotificationIfPossible(final OCSMSNotificationType nType, final String nTitle, final String nMsg) {
|
||||
_notification.createNotify(nType.ordinal(), nTitle, nMsg);
|
||||
}
|
||||
|
||||
private final Context _context;
|
||||
private final NrzNotification _notification;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package fr.unix_experience.owncloud_sms.observers;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2015, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import org.json.JSONArray;
|
||||
|
||||
import fr.unix_experience.owncloud_sms.engine.ASyncSMSSync;
|
||||
import fr.unix_experience.owncloud_sms.engine.ConnectivityMonitor;
|
||||
import fr.unix_experience.owncloud_sms.engine.OCSMSOwnCloudClient;
|
||||
import fr.unix_experience.owncloud_sms.engine.SmsFetcher;
|
||||
import fr.unix_experience.owncloud_sms.enums.MailboxID;
|
||||
import android.content.Context;
|
||||
import android.database.ContentObserver;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
|
||||
public class SmsObserver extends ContentObserver implements ASyncSMSSync {
|
||||
|
||||
public SmsObserver(Handler handler) {
|
||||
super(handler);
|
||||
}
|
||||
|
||||
public SmsObserver(Handler handler, Context ct) {
|
||||
super(handler);
|
||||
_context = ct;
|
||||
}
|
||||
|
||||
public void onChange(boolean selfChange) {
|
||||
super.onChange(selfChange);
|
||||
Log.d(TAG, "onChange SmsObserver");
|
||||
|
||||
SmsFetcher fetcher = new SmsFetcher(_context);
|
||||
JSONArray smsList = fetcher.getLastMessage(MailboxID.ALL);
|
||||
|
||||
ConnectivityMonitor cMon = new ConnectivityMonitor(_context);
|
||||
|
||||
// Synchronize if network is valid and there are SMS
|
||||
if (cMon.isValid() && smsList != null) {
|
||||
new SyncTask(_context, smsList).execute();
|
||||
}
|
||||
}
|
||||
|
||||
public void setContext(Context context) {
|
||||
_context = context;
|
||||
}
|
||||
|
||||
private Context _context;
|
||||
|
||||
private static final String TAG = OCSMSOwnCloudClient.class.getSimpleName();
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package fr.unix_experience.owncloud_sms.prefs;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2015, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import fr.nrz.androidlib.common.SharedPrefs;
|
||||
import fr.unix_experience.owncloud_sms.R;
|
||||
import fr.unix_experience.owncloud_sms.defines.DefaultPrefs;
|
||||
|
||||
public class OCSMSSharedPrefs extends SharedPrefs {
|
||||
|
||||
public OCSMSSharedPrefs(final Context context) {
|
||||
super(context, R.string.shared_preference_file);
|
||||
}
|
||||
|
||||
public void setLastMessageDate(final Long msgDate) {
|
||||
final SharedPreferences.Editor editor = _sPrefs.edit();
|
||||
editor.putLong(_context.getString(R.string.pref_lastmsgdate), msgDate);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public Long getLastMessageDate() {
|
||||
return _sPrefs.getLong(_context.getString(R.string.pref_lastmsgdate), 0);
|
||||
}
|
||||
|
||||
public Boolean pushOnReceive() {
|
||||
return _sPrefs.getBoolean("push_on_receive", DefaultPrefs.pushOnReceive);
|
||||
}
|
||||
|
||||
public Boolean syncInWifi() {
|
||||
return _sPrefs.getBoolean("sync_wifi", DefaultPrefs.syncWifi);
|
||||
}
|
||||
|
||||
public Boolean syncIn2G() {
|
||||
return _sPrefs.getBoolean("sync_2g", DefaultPrefs.sync2G);
|
||||
}
|
||||
|
||||
public Boolean syncInGPRS() {
|
||||
return _sPrefs.getBoolean("sync_gprs", DefaultPrefs.syncGPRS);
|
||||
}
|
||||
|
||||
public Boolean syncIn3G() {
|
||||
return _sPrefs.getBoolean("sync_3g", DefaultPrefs.sync3G);
|
||||
}
|
||||
|
||||
public Boolean syncIn4G() {
|
||||
return _sPrefs.getBoolean("sync_4g", DefaultPrefs.sync4G);
|
||||
}
|
||||
|
||||
public Boolean syncInOtherModes() {
|
||||
return _sPrefs.getBoolean("sync_others", DefaultPrefs.syncOthers);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package fr.unix_experience.owncloud_sms.providers;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2015, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
|
||||
public class SmsDataProvider extends ContentProvider {
|
||||
public SmsDataProvider () {}
|
||||
|
||||
public SmsDataProvider (final Context ct) {
|
||||
super();
|
||||
_context = ct;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Cursor query(final String mailBox) {
|
||||
return query(Uri.parse(mailBox),
|
||||
new String[] { "read", "date", "address", "seen", "body", "_id", "type", },
|
||||
null, null, null
|
||||
);
|
||||
}
|
||||
|
||||
public Cursor query(final String mailBox, final String selection) {
|
||||
return query(Uri.parse(mailBox),
|
||||
new String[] { "read", "date", "address", "seen", "body", "_id", "type", },
|
||||
selection, null, null
|
||||
);
|
||||
}
|
||||
|
||||
public Cursor query(final String mailBox, final String selection, final String[] selectionArgs) {
|
||||
return query(Uri.parse(mailBox),
|
||||
new String[] { "read", "date", "address", "seen", "body", "_id", "type", },
|
||||
selection, selectionArgs, null
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor query(final Uri uri, final String[] projection, final String selection,
|
||||
final String[] selectionArgs, final String sortOrder) {
|
||||
if (_context != null && _context.getContentResolver() != null) {
|
||||
return _context.getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType(final Uri uri) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insert(final Uri uri, final ContentValues values) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int delete(final Uri uri, final String selection, final String[] selectionArgs) {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(final Uri uri, final ContentValues values, final String selection,
|
||||
final String[] selectionArgs) {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
private Context _context;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package fr.unix_experience.owncloud_sms.sync_adapters;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2015, Loic Blot <loic.blot@unix-experience.fr>
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
|
||||
public class SmsSlowSyncService extends Service {
|
||||
// Storage for an instance of the sync adapter
|
||||
private static SmsSyncAdapter _adapter = null;
|
||||
// Object to use as a thread-safe lock
|
||||
private static final Object sSyncAdapterLock = new Object();
|
||||
/*
|
||||
* Instantiate the sync adapter object.
|
||||
*/
|
||||
@Override
|
||||
public void onCreate() {
|
||||
/*
|
||||
* Create the sync adapter as a singleton.
|
||||
* Set the sync adapter as syncable
|
||||
* Disallow parallel syncs
|
||||
*/
|
||||
synchronized (sSyncAdapterLock) {
|
||||
if (_adapter == null) {
|
||||
_adapter = new SmsSyncAdapter(getApplicationContext(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Return an object that allows the system to invoke
|
||||
* the sync adapter.
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
/*
|
||||
* Get the object that allows external processes
|
||||
* to call onPerformSync(). The object is created
|
||||
* in the base class code when the SyncAdapter
|
||||
* constructors call super()
|
||||
*/
|
||||
return _adapter.getSyncAdapterBinder();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package fr.unix_experience.owncloud_sms.sync_adapters;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2015, Loic Blot <loic.blot@unix-experience.fr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.content.AbstractThreadedSyncAdapter;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.Context;
|
||||
import android.content.SyncResult;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import fr.unix_experience.owncloud_sms.R;
|
||||
import fr.unix_experience.owncloud_sms.engine.OCSMSOwnCloudClient;
|
||||
import fr.unix_experience.owncloud_sms.enums.OCSyncErrorType;
|
||||
import fr.unix_experience.owncloud_sms.exceptions.OCSyncException;
|
||||
import fr.unix_experience.owncloud_sms.notifications.OCSMSNotificationManager;
|
||||
|
||||
public class SmsSyncAdapter extends AbstractThreadedSyncAdapter {
|
||||
|
||||
public SmsSyncAdapter(final Context context, final boolean autoInitialize) {
|
||||
super(context, autoInitialize);
|
||||
_accountMgr = AccountManager.get(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPerformSync(final Account account, final Bundle extras, final String authority,
|
||||
final ContentProviderClient provider, final SyncResult syncResult) {
|
||||
|
||||
final OCSMSNotificationManager nMgr = new OCSMSNotificationManager(getContext());
|
||||
|
||||
// Create client
|
||||
final String ocURI = _accountMgr.getUserData(account, "ocURI");
|
||||
if (ocURI == null) {
|
||||
nMgr.setSyncErrorMsg(getContext().getString(R.string.err_sync_account_unparsable));
|
||||
return;
|
||||
}
|
||||
|
||||
final Uri serverURI = Uri.parse(ocURI);
|
||||
nMgr.setSyncProcessMsg();
|
||||
|
||||
final OCSMSOwnCloudClient _client = new OCSMSOwnCloudClient(getContext(),
|
||||
serverURI, _accountMgr.getUserData(account, "ocLogin"),
|
||||
_accountMgr.getPassword(account));
|
||||
|
||||
try {
|
||||
// getServerAPI version
|
||||
Log.d(TAG,"Server API version: " + _client.getServerAPIVersion());
|
||||
|
||||
// and push datas
|
||||
_client.doPushRequest(null);
|
||||
nMgr.dropSyncErrorMsg();
|
||||
} catch (final OCSyncException e) {
|
||||
nMgr.setSyncErrorMsg(getContext().getString(e.getErrorId()));
|
||||
if (e.getErrorType() == OCSyncErrorType.IO) {
|
||||
syncResult.stats.numIoExceptions++;
|
||||
}
|
||||
else if (e.getErrorType() == OCSyncErrorType.PARSE) {
|
||||
syncResult.stats.numParseExceptions++;
|
||||
}
|
||||
else if (e.getErrorType() == OCSyncErrorType.AUTH) {
|
||||
syncResult.stats.numAuthExceptions++;
|
||||
}
|
||||
else {
|
||||
// UNHANDLED
|
||||
}
|
||||
}
|
||||
|
||||
nMgr.dropSyncProcessMsg();
|
||||
|
||||
}
|
||||
|
||||
private final AccountManager _accountMgr;
|
||||
|
||||
private static final String TAG = SmsSyncAdapter.class.getSimpleName();
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package fr.unix_experience.owncloud_sms.sync_adapters;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014-2015, Loic Blot <loic.blot@unix-experience.fr>
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
|
||||
public class SmsSyncService extends Service {
|
||||
// Storage for an instance of the sync adapter
|
||||
private static SmsSyncAdapter _adapter = null;
|
||||
// Object to use as a thread-safe lock
|
||||
private static final Object sSyncAdapterLock = new Object();
|
||||
/*
|
||||
* Instantiate the sync adapter object.
|
||||
*/
|
||||
@Override
|
||||
public void onCreate() {
|
||||
/*
|
||||
* Create the sync adapter as a singleton.
|
||||
* Set the sync adapter as syncable
|
||||
* Disallow parallel syncs
|
||||
*/
|
||||
synchronized (sSyncAdapterLock) {
|
||||
if (_adapter == null) {
|
||||
_adapter = new SmsSyncAdapter(getApplicationContext(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Return an object that allows the system to invoke
|
||||
* the sync adapter.
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
/*
|
||||
* Get the object that allows external processes
|
||||
* to call onPerformSync(). The object is created
|
||||
* in the base class code when the SyncAdapter
|
||||
* constructors call super()
|
||||
*/
|
||||
return _adapter.getSyncAdapterBinder();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user