diff --git a/app/app.iml b/app/app.iml
new file mode 100644
index 0000000..dee7099
--- /dev/null
+++ b/app/app.iml
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 2e57537..f516866 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -6,7 +6,7 @@ android {
defaultConfig {
applicationId "com.example.admin.personallibrarycatalogue"
- minSdkVersion 21
+ minSdkVersion 16
targetSdkVersion 22
versionCode 1
versionName "1.0"
@@ -24,4 +24,5 @@ dependencies {
compile 'com.android.support:appcompat-v7:22.1.1'
compile 'com.android.support:support-v4:22.1.1'
compile 'com.google.android.gms:play-services:7.3.0'
+ compile(group: 'org.twitter4j', name: 'twitter4j-core', version: '4.0.3')
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 15e3a21..07cd5f8 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -3,7 +3,8 @@
package="com.example.admin.personallibrarycatalogue" >
-
+
+
+
+ android:label="@string/title_activity_books_list" >
+ android:launchMode="singleTask" >
+
+
+
+
+
+
+
+
+
@@ -33,6 +44,7 @@
android:name=".data.BooksProvider"
android:authorities="com.example.admin.personallibrarycatalogue.app" />
+
diff --git a/app/src/main/AndroidManifest.xml.orig b/app/src/main/AndroidManifest.xml.orig
new file mode 100644
index 0000000..73d1d95
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml.orig
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+=======
+ android:label="@string/title_activity_books_list"
+ android:launchMode="singleTask" >
+>>>>>>> lab_273_content_providers
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/java/com/example/admin/personallibrarycatalogue/BooksListActivity.java b/app/src/main/java/com/example/admin/personallibrarycatalogue/BooksListActivity.java
index 68eec6f..7153e7e 100644
--- a/app/src/main/java/com/example/admin/personallibrarycatalogue/BooksListActivity.java
+++ b/app/src/main/java/com/example/admin/personallibrarycatalogue/BooksListActivity.java
@@ -1,6 +1,8 @@
package com.example.admin.personallibrarycatalogue;
+import android.content.Context;
import android.content.Intent;
+import android.net.Uri;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.ContextMenu;
@@ -8,14 +10,20 @@
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
+import android.widget.EditText;
public class BooksListActivity extends ActionBarActivity {
+ public static Context contextOfApplication;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_books_list);
+
+ contextOfApplication = getApplicationContext();
+
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment, new BooksListActivityFragment())
@@ -23,6 +31,21 @@ protected void onCreate(Bundle savedInstanceState) {
}
}
+ public static Context getContextOfApplication(){
+ return contextOfApplication;
+ }
+
+ @Override
+ public void onResume(){
+ super.onResume();
+ Uri uri = getIntent().getData();
+ if (uri != null && uri.toString().startsWith(ConstantValues.TWITTER_CALLBACK_URL)) {
+ String verifier = uri.getQueryParameter(ConstantValues.URL_PARAMETER_TWITTER_OAUTH_VERIFIER);
+ String status = ((BooksListActivityFragment) getSupportFragmentManager().findFragmentById(R.id.fragment)).getStatus();
+ new TwitterGetAccessTokenTask().execute(verifier,status);
+ }
+ }
+
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
diff --git a/app/src/main/java/com/example/admin/personallibrarycatalogue/BooksListActivityFragment.java b/app/src/main/java/com/example/admin/personallibrarycatalogue/BooksListActivityFragment.java
index c864d5c..64f49f8 100644
--- a/app/src/main/java/com/example/admin/personallibrarycatalogue/BooksListActivityFragment.java
+++ b/app/src/main/java/com/example/admin/personallibrarycatalogue/BooksListActivityFragment.java
@@ -1,13 +1,25 @@
package com.example.admin.personallibrarycatalogue;
+import android.content.ContentValues;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.database.Cursor;
+import android.support.v4.app.LoaderManager;
+import android.graphics.Color;
+import android.os.AsyncTask;
+import android.preference.PreferenceManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.net.Uri;
import android.support.v4.app.Fragment;
import android.os.Bundle;
+import android.support.v7.internal.widget.AdapterViewCompat;
+import android.text.Editable;
+import android.text.TextWatcher;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.MenuInflater;
@@ -15,12 +27,21 @@
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
+import android.widget.EditText;
import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
import com.example.admin.personallibrarycatalogue.data.Book;
import com.example.admin.personallibrarycatalogue.data.DatabaseContract;
import com.example.admin.personallibrarycatalogue.data.LibraryDatabaseHelper;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import twitter4j.auth.RequestToken;
+
/**
* The fragment which responsible for showing list of all books
@@ -28,10 +49,25 @@
public class BooksListActivityFragment extends Fragment implements android.support.v4.app.LoaderManager.LoaderCallbacks {
private static final int LIBRARY_LOADER = 0;
- private final static String EXTRA_ID = "id";
+ private static final String SPACE = " ";
+ private static final String I_HAVE_BOOK = "I have book";
+ private static final String AND_WANT_TO_LET_KNOW = "and want to let world about it!";
+ private final static String ID = "id";
private ListView listView_;
+ private static String status_ = "";
private BooksListAdapter booksListAdapter_;
- private LibraryDatabaseHelper helper_;
+
+
+ private static final String[] BOOK_COLUMNS = {
+
+ DatabaseContract.BooksTable.TABLE_NAME + "." + DatabaseContract.BooksTable._ID,
+ DatabaseContract.BooksTable.TITLE,
+ DatabaseContract.BooksTable.AUTHOR,
+ DatabaseContract.BooksTable.DESCRIPTION,
+ DatabaseContract.BooksTable.COVER,
+ DatabaseContract.BooksTable.YEAR,
+ DatabaseContract.BooksTable.ISBN
+ };
public BooksListActivityFragment() {
}
@@ -41,7 +77,7 @@ public Loader onCreateLoader(int i, Bundle bundle) {
return new CursorLoader(
getActivity(),
DatabaseContract.BooksTable.CONTENT_URI,
- DatabaseContract.BOOK_COLUMNS,
+ BOOK_COLUMNS,
null,
null,
null
@@ -58,15 +94,15 @@ public void onLoaderReset(Loader cursorLoader) {
booksListAdapter_.swapCursor(null);
}
+
@Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_books_list, container, false);
- helper_ = new LibraryDatabaseHelper(getActivity());
listView_ = (ListView) rootView.findViewById(R.id.books_list_view);
- booksListAdapter_ = new BooksListAdapter(this.getActivity(), null, 0);
+ booksListAdapter_ = new BooksListAdapter(getActivity(), null, 0);
listView_.setAdapter(booksListAdapter_);
// Set ContextMenu for listView
@@ -114,6 +150,10 @@ public boolean onContextItemSelected(MenuItem item) {
booksListAdapter_.notifyDataSetChanged();
break;
+ case R.id.share_in_twitter:
+ statusBuilder(cursor);
+ launchPrompt(getActivity());
+
default:
return super.onContextItemSelected(item);
}
@@ -125,7 +165,7 @@ public boolean onContextItemSelected(MenuItem item) {
*/
public void updateBook(Book book) {
Intent intent = new Intent(getActivity(), AddBookActivity.class);
- intent.putExtra(EXTRA_ID, book.getId());
+ intent.putExtra(ID, book.getId());
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
}
@@ -136,4 +176,109 @@ public void deleteBook(Book book) {
getActivity().getContentResolver().delete(bookWithIdUri, null, null);
}
+ // Returns the typed message
+ public String getStatus() {
+ return status_;
+ }
+
+ public void statusBuilder(Cursor cursor){
+ Book book = LibraryDatabaseHelper.getBook(cursor);
+ status_ = I_HAVE_BOOK + SPACE + book.getTitle() + SPACE + book.getYear() + SPACE + book.getAuthor() + SPACE + AND_WANT_TO_LET_KNOW;
+ }
+
+
+ // Set up subwindow, where user can type the message
+ public void launchPrompt(Context context) {
+ LayoutInflater layoutInflater = LayoutInflater.from(context);
+ View promptView = layoutInflater.inflate(R.layout.prompt, null);
+ AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
+ alertDialogBuilder.setView(promptView);
+
+ final TextView info = (TextView)promptView.findViewById(R.id.length_info);
+
+ final EditText inputText = (EditText) promptView.findViewById(R.id.share_input);
+ inputText.setText(status_);
+
+ inputText.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ int accessibleLength = 140 - inputText.getText().toString().length();
+ info.setText( Integer.toString(accessibleLength));
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ if (!inputText.getText().toString().equalsIgnoreCase("")){
+ int accessibleLength = 140 - inputText.getText().toString().length();
+ if ((accessibleLength<140)&&(accessibleLength>10)) {
+ info.setTextColor(Color.GREEN);
+ info.setText(Integer.toString(accessibleLength));
+ } else {
+ info.setTextColor(Color.RED);
+ info.setText(Integer.toString(accessibleLength));
+ }
+
+ }
+ }
+ });
+
+
+ // setup a dialog window
+ alertDialogBuilder.setCancelable(false)
+ .setPositiveButton("OK", new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+
+ // get user input and set it to result
+ status_ = (inputText.getText().toString());
+ if (status_.length() > 140) {
+ Toast.makeText(getActivity(), "The length of tweet must be less 140", Toast.LENGTH_LONG).show();
+ } else if (status_.length()>0){
+ logIn();
+ } else Toast.makeText(getActivity(), "Please fill the field", Toast.LENGTH_LONG).show();
+ }
+ })
+ .setNegativeButton("Cancel",
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ dialog.cancel();
+ }
+ });
+
+
+ // create an alert dialog
+ AlertDialog alertDialog = alertDialogBuilder.create();
+ alertDialog.show();
+ }
+
+ private void logIn() {
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
+ if (!sharedPreferences.getBoolean(ConstantValues.PREFERENCE_TWITTER_IS_LOGGED_IN, false)) {
+ new TwitterAuthenticateTask().execute();
+ } else {
+ new TwitterUpdateStatusTask().execute(getStatus());
+ }
+ }
+
+ class TwitterAuthenticateTask extends AsyncTask {
+
+ @Override
+ protected void onPostExecute(RequestToken requestToken) {
+ if (requestToken != null) {
+ Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(requestToken.getAuthenticationURL()));
+ startActivity(intent);
+ }
+ }
+
+ @Override
+ protected RequestToken doInBackground(String... params) {
+ return TwitterUtil.getInstance().getRequestToken();
+ }
+ }
+
+
}
diff --git a/app/src/main/java/com/example/admin/personallibrarycatalogue/ConstantValues.java b/app/src/main/java/com/example/admin/personallibrarycatalogue/ConstantValues.java
new file mode 100644
index 0000000..cbf524a
--- /dev/null
+++ b/app/src/main/java/com/example/admin/personallibrarycatalogue/ConstantValues.java
@@ -0,0 +1,15 @@
+package com.example.admin.personallibrarycatalogue;
+
+/**
+ * Created by Mikhail Valuyskiy on 08.06.2015.
+ */
+public class ConstantValues {
+ public static String TWITTER_CONSUMER_KEY = "RO9WR8PmKG5G8IUFDruZjf4CX";
+ public static String TWITTER_CONSUMER_SECRET = "zfXLmbBb1LjrOyugs5nRyxTz0CWbRdv8XPclsXigV3ThH41ZY7";
+ public static String TWITTER_CALLBACK_URL = "app://ruswizaradlab.com";
+ public static String URL_PARAMETER_TWITTER_OAUTH_VERIFIER = "oauth_verifier";
+ public static String PREFERENCE_TWITTER_OAUTH_TOKEN="TWITTER_OAUTH_TOKEN";
+ public static String PREFERENCE_TWITTER_OAUTH_TOKEN_SECRET="TWITTER_OAUTH_TOKEN_SECRET";
+ public static String PREFERENCE_TWITTER_IS_LOGGED_IN="TWITTER_IS_LOGGED_IN";
+ public static String STRING_EXTRA_AUTHENCATION_URL = "AuthencationUrl";
+}
diff --git a/app/src/main/java/com/example/admin/personallibrarycatalogue/TwitterGetAccessTokenTask.java b/app/src/main/java/com/example/admin/personallibrarycatalogue/TwitterGetAccessTokenTask.java
new file mode 100644
index 0000000..e599be1
--- /dev/null
+++ b/app/src/main/java/com/example/admin/personallibrarycatalogue/TwitterGetAccessTokenTask.java
@@ -0,0 +1,60 @@
+package com.example.admin.personallibrarycatalogue;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.AsyncTask;
+import android.preference.PreferenceManager;
+
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+import twitter4j.auth.AccessToken;
+import twitter4j.auth.RequestToken;
+
+/**
+ * Created by Mikhail Valuyskiy on 16.06.2015.
+ */
+class TwitterGetAccessTokenTask extends AsyncTask {
+
+ @Override
+ protected void onPostExecute(String status) {
+ new TwitterUpdateStatusTask().execute(status);
+ }
+
+ @Override
+ protected String doInBackground(String... params) {
+
+ Context context = BooksListActivity.getContextOfApplication();
+
+ Twitter twitter = TwitterUtil.getInstance().getTwitter();
+ RequestToken requestToken = TwitterUtil.getInstance().getRequestToken();
+ if ((params[0]!=null)) {
+ try {
+
+ AccessToken accessToken = twitter.getOAuthAccessToken(requestToken, params[0]);
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ editor.putString(ConstantValues.PREFERENCE_TWITTER_OAUTH_TOKEN, accessToken.getToken());
+ editor.putString(ConstantValues.PREFERENCE_TWITTER_OAUTH_TOKEN_SECRET, accessToken.getTokenSecret());
+ editor.putBoolean(ConstantValues.PREFERENCE_TWITTER_IS_LOGGED_IN, true);
+ editor.commit();
+
+ return params[1];
+ } catch (TwitterException e) {
+ e.printStackTrace();
+ }
+ } else {
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
+ String accessTokenString = sharedPreferences.getString(ConstantValues.PREFERENCE_TWITTER_OAUTH_TOKEN, "");
+ String accessTokenSecret = sharedPreferences.getString(ConstantValues.PREFERENCE_TWITTER_OAUTH_TOKEN_SECRET, "");
+ AccessToken accessToken = new AccessToken(accessTokenString, accessTokenSecret);
+ try {
+ TwitterUtil.getInstance().setTwitterFactory(accessToken);
+ return params[1];
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/app/src/main/java/com/example/admin/personallibrarycatalogue/TwitterUpdateStatusTask.java b/app/src/main/java/com/example/admin/personallibrarycatalogue/TwitterUpdateStatusTask.java
new file mode 100644
index 0000000..26c62c7
--- /dev/null
+++ b/app/src/main/java/com/example/admin/personallibrarycatalogue/TwitterUpdateStatusTask.java
@@ -0,0 +1,50 @@
+package com.example.admin.personallibrarycatalogue;
+
+/**
+ * Created by Mikhail Valuyskiy on 16.06.2015.
+ */
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.AsyncTask;
+import android.preference.PreferenceManager;
+import android.widget.Toast;
+
+import twitter4j.TwitterException;
+import twitter4j.auth.AccessToken;
+
+/**
+ * Created by Mikhail on 15.06.2015.
+ */
+class TwitterUpdateStatusTask extends AsyncTask {
+
+ @Override
+ protected void onPostExecute(Boolean result) {
+ Context context = BooksListActivity.getContextOfApplication();
+ if (result)
+ Toast.makeText(context, "Tweet successfully", Toast.LENGTH_SHORT).show();
+ else
+ Toast.makeText(context, "Tweet failed", Toast.LENGTH_SHORT).show();
+ }
+
+ @Override
+ protected Boolean doInBackground(String... params) {
+
+ Context context = BooksListActivity.getContextOfApplication();
+ try {
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
+ String accessTokenString = sharedPreferences.getString(ConstantValues.PREFERENCE_TWITTER_OAUTH_TOKEN, "");
+ String accessTokenSecret = sharedPreferences.getString(ConstantValues.PREFERENCE_TWITTER_OAUTH_TOKEN_SECRET, "");
+
+ if ((accessTokenString!=null) && accessTokenSecret!=null) {
+ AccessToken accessToken = new AccessToken(accessTokenString, accessTokenSecret);
+ twitter4j.Status status = TwitterUtil.getInstance().getTwitterFactory().getInstance(accessToken).updateStatus(params[0]);
+ return true;
+ }
+
+ } catch (TwitterException e) {
+ e.printStackTrace();
+ }
+ return false;
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/admin/personallibrarycatalogue/TwitterUtil.java b/app/src/main/java/com/example/admin/personallibrarycatalogue/TwitterUtil.java
new file mode 100644
index 0000000..610e53e
--- /dev/null
+++ b/app/src/main/java/com/example/admin/personallibrarycatalogue/TwitterUtil.java
@@ -0,0 +1,63 @@
+package com.example.admin.personallibrarycatalogue;
+
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+import twitter4j.TwitterFactory;
+import twitter4j.auth.AccessToken;
+import twitter4j.auth.RequestToken;
+import twitter4j.conf.ConfigurationBuilder;
+
+/**
+ * Created by Mikhail on 15.06.2015.
+ */
+public final class TwitterUtil {
+
+ private RequestToken requestToken_ = null;
+ private TwitterFactory twitterFactory_ = null;
+ private Twitter twitter_;
+
+ private TwitterUtil() {
+ ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
+ configurationBuilder.setOAuthConsumerKey(ConstantValues.TWITTER_CONSUMER_KEY);
+ configurationBuilder.setOAuthConsumerSecret(ConstantValues.TWITTER_CONSUMER_SECRET);
+ twitter4j.conf.Configuration configuration = configurationBuilder.build();
+ twitterFactory_ = new TwitterFactory(configuration);
+ twitter_ = twitterFactory_.getInstance();
+ }
+
+ public TwitterFactory getTwitterFactory()
+ {
+ return twitterFactory_;
+ }
+
+ public void setTwitterFactory(AccessToken accessToken)
+ {
+ twitter_ = twitterFactory_.getInstance(accessToken);
+ }
+
+ public Twitter getTwitter()
+ {
+ return twitter_;
+ }
+ public RequestToken getRequestToken() {
+ if (requestToken_ == null) {
+ try {
+ requestToken_ = twitterFactory_.getInstance().getOAuthRequestToken(ConstantValues.TWITTER_CALLBACK_URL);
+ } catch (TwitterException e) {
+ e.printStackTrace();
+ }
+ }
+ return requestToken_;
+ }
+
+ static TwitterUtil instance = new TwitterUtil();
+
+ public static TwitterUtil getInstance() {
+ return instance;
+ }
+
+
+ public void reset() {
+ instance = new TwitterUtil();
+ }
+}
diff --git a/app/src/main/res/layout/prompt.xml b/app/src/main/res/layout/prompt.xml
new file mode 100644
index 0000000..67b2127
--- /dev/null
+++ b/app/src/main/res/layout/prompt.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/context_menu.xml b/app/src/main/res/menu/context_menu.xml
index df07304..13f62af 100644
--- a/app/src/main/res/menu/context_menu.xml
+++ b/app/src/main/res/menu/context_menu.xml
@@ -12,4 +12,10 @@
android:orderInCategory="100"
app:showAsAction="never" />
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 0bd62bd..723e2e9 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -19,5 +19,4 @@
0dp
0dp
-
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 8c8271b..bb6075d 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -27,6 +27,12 @@
Menu
Edit
Delete
+ Share in twitter
+
+
+ Let your friends know what\'s going on!
+ Please write less then 140 symbols
+
Title