added location info, bug fix
This commit is contained in:
parent
19e94ff9e6
commit
6b2009766f
|
@ -33,14 +33,12 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.material:material:1.0.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||
implementation 'androidx.exifinterface:exifinterface:1.0.0'
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
implementation 'androidx.vectordrawable:vectordrawable:1.1.0'
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
implementation 'com.google.android.material:material:1.0.0'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.0.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
|
||||
implementation 'org.twitter4j:twitter4j-core:4.0.7'
|
||||
implementation 'com.squareup.picasso:picasso:2.71828'
|
||||
|
|
|
@ -2,7 +2,9 @@ package org.nuclearfog.twidda.backend.items;
|
|||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import twitter4j.GeoLocation;
|
||||
import twitter4j.MediaEntity;
|
||||
import twitter4j.Place;
|
||||
import twitter4j.Status;
|
||||
import twitter4j.URLEntity;
|
||||
|
||||
|
@ -32,12 +34,27 @@ public class Tweet {
|
|||
private final boolean retweeted;
|
||||
private final boolean favored;
|
||||
|
||||
private final String locationName;
|
||||
private final String locationCoordinates;
|
||||
|
||||
|
||||
/**
|
||||
* Tweet Constructor
|
||||
*
|
||||
* @param status Twitter4J status
|
||||
*/
|
||||
public Tweet(Status status) {
|
||||
this(status, status.getRetweetCount(), status.isRetweeted(), status.getFavoriteCount(), status.isFavorited());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tweet constructor
|
||||
* @param status twitter4j status
|
||||
* @param retweetCount set retweet count
|
||||
* @param retweeted set if tweet is retweeted by current user
|
||||
* @param favoriteCount set favor count
|
||||
* @param favored set if tweet is favored by current user
|
||||
*/
|
||||
public Tweet(Status status, int retweetCount, boolean retweeted, int favoriteCount, boolean favored) {
|
||||
this.retweetCount = retweetCount;
|
||||
this.retweeted = retweeted;
|
||||
|
@ -57,6 +74,16 @@ public class Tweet {
|
|||
api = api.substring(0, api.indexOf('<'));
|
||||
source = api;
|
||||
|
||||
Place place = status.getPlace();
|
||||
GeoLocation geo = status.getGeoLocation();
|
||||
if (place != null)
|
||||
locationName = place.getFullName();
|
||||
else
|
||||
locationName = "";
|
||||
if (geo != null)
|
||||
locationCoordinates = geo.getLatitude() + "," + geo.getLongitude();
|
||||
else
|
||||
locationCoordinates = "";
|
||||
if (status.getInReplyToScreenName() == null)
|
||||
replyName = "";
|
||||
else
|
||||
|
@ -67,10 +94,29 @@ public class Tweet {
|
|||
embedded = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tweet constructor for database tweets
|
||||
* @param tweetID unique id of tweet
|
||||
* @param retweetCount number of retweets
|
||||
* @param favoriteCount number of favors
|
||||
* @param user tweet author
|
||||
* @param tweet tweet text
|
||||
* @param time time long format
|
||||
* @param replyName author's name of replied tweet
|
||||
* @param replyUserId quthor's ID of replied tweet
|
||||
* @param medias Media links attached to tweet
|
||||
* @param source used API of the tweet
|
||||
* @param replyID ID of replied tweet
|
||||
* @param embedded quoted tweet
|
||||
* @param myRetweetId ID of the current users retweeted tweet
|
||||
* @param retweeted tweet is retweeted by current user
|
||||
* @param favored tweet is favored by current user
|
||||
* @param coordinates location gps coordinates
|
||||
* @param place location full place name
|
||||
*/
|
||||
public Tweet(long tweetID, int retweetCount, int favoriteCount, TwitterUser user, String tweet, long time,
|
||||
String replyName, long replyUserId, String[] medias, String source, long replyID,
|
||||
Tweet embedded, long myRetweetId, boolean retweeted, boolean favored) {
|
||||
Tweet embedded, long myRetweetId, boolean retweeted, boolean favored, String place, String coordinates) {
|
||||
this.tweetID = tweetID;
|
||||
this.user = user;
|
||||
this.retweetCount = retweetCount;
|
||||
|
@ -86,6 +132,8 @@ public class Tweet {
|
|||
this.favored = favored;
|
||||
this.myRetweetId = myRetweetId;
|
||||
this.replyUserId = replyUserId;
|
||||
this.locationName = place;
|
||||
this.locationCoordinates = coordinates;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -233,6 +281,24 @@ public class Tweet {
|
|||
return favored;
|
||||
}
|
||||
|
||||
/**
|
||||
* get location of tweet if any
|
||||
*
|
||||
* @return full location name
|
||||
*/
|
||||
public String getLocationName() {
|
||||
return locationName;
|
||||
}
|
||||
|
||||
/**
|
||||
* get location coordinate
|
||||
*
|
||||
* @return latitude and longitude
|
||||
*/
|
||||
public String getLocationCoordinates() {
|
||||
return locationCoordinates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param status Twitter4J status
|
||||
* @return Array of Medialinks
|
||||
|
|
|
@ -545,6 +545,10 @@ public class AppDatabase {
|
|||
String source = cursor.getString(index);
|
||||
index = cursor.getColumnIndex("media");
|
||||
String medialinks = cursor.getString(index);
|
||||
index = cursor.getColumnIndex("place");
|
||||
String place = cursor.getString(index);
|
||||
index = cursor.getColumnIndex("geo");
|
||||
String geo = cursor.getString(index);
|
||||
index = cursor.getColumnIndex("replyUserID");
|
||||
long replyUserId = cursor.getLong(index);
|
||||
index = cursor.getColumnIndex("statusregister");
|
||||
|
@ -559,7 +563,7 @@ public class AppDatabase {
|
|||
if (retweetId > 1)
|
||||
embeddedTweet = getStatus(retweetId);
|
||||
return new Tweet(tweetId, retweet, favorit, user, tweettext, time, replyname, replyUserId, medias,
|
||||
source, replyStatusId, embeddedTweet, retweeterId, retweeted, favorited);
|
||||
source, replyStatusId, embeddedTweet, retweeterId, retweeted, favorited, place, geo);
|
||||
}
|
||||
|
||||
|
||||
|
@ -691,6 +695,9 @@ public class AppDatabase {
|
|||
status.put("favorite", tweet.getFavorCount());
|
||||
status.put("retweeterID", tweet.getMyRetweetId());
|
||||
status.put("replyUserID", tweet.getReplyUserId());
|
||||
status.put("place", tweet.getLocationName());
|
||||
status.put("geo", tweet.getLocationCoordinates());
|
||||
status.put("replyUserID", tweet.getReplyUserId());
|
||||
if (tweet.getReplyUserId() > 0)
|
||||
status.put("replyname", tweet.getReplyName());
|
||||
storeUser(user, db, CONFLICT_IGNORE);
|
||||
|
|
|
@ -14,17 +14,18 @@ import static android.content.Context.MODE_PRIVATE;
|
|||
*/
|
||||
public class DatabaseAdapter {
|
||||
|
||||
private static final int DB_VERSION = 2;
|
||||
private static final String DB_NAME = "database.db";
|
||||
|
||||
private static final String TABLE_USER = "CREATE TABLE IF NOT EXISTS user (" +
|
||||
"userID INTEGER PRIMARY KEY,username VARCHAR(50),scrname VARCHAR(15)," +
|
||||
"userID INTEGER PRIMARY KEY,username TEXT,scrname TEXT," +
|
||||
"pbLink TEXT,banner TEXT,bio TEXT,location TEXT,link TEXT,userregister INTEGER," +
|
||||
"createdAt INTEGER,following INTEGER,follower INTEGER,tweetCount INTEGER,favorCount INTEGER);";
|
||||
|
||||
private static final String TABLE_TWEET = "CREATE TABLE IF NOT EXISTS tweet (" +
|
||||
"tweetID INTEGER PRIMARY KEY,userID INTEGER,retweetID INTEGER,replyID INTEGER,retweeterID INTEGER," +
|
||||
"replyname TEXT,replyUserID INTEGER,time INTEGER,tweet TEXT,media TEXT,retweet INTEGER,favorite INTEGER," +
|
||||
"statusregister INTEGER,source VARCHAR(32),FOREIGN KEY (userID) REFERENCES user(userID));";
|
||||
"statusregister INTEGER,source TEXT,place TEXT,geo TEXT,FOREIGN KEY (userID) REFERENCES user(userID));";
|
||||
|
||||
private static final String TABLE_FAVORS = "CREATE TABLE IF NOT EXISTS favorit (" +
|
||||
"ownerID INTEGER,tweetID INTEGER," +
|
||||
|
@ -42,6 +43,9 @@ public class DatabaseAdapter {
|
|||
private static final String INDX_FAVOR = "CREATE INDEX IF NOT EXISTS idx_favor ON favorit(ownerID,tweetID);";
|
||||
private static final String INDX_TREND = "CREATE INDEX IF NOT EXISTS idx_trend ON trend(woeID);";
|
||||
|
||||
private static final String TABLE_TWEET_ADD_PLACE = "ALTER TABLE tweet ADD COLUMN place TEXT";
|
||||
private static final String TABLE_TWEET_ADD_GEO = "ALTER TABLE tweet ADD COLUMN geo TEXT";
|
||||
|
||||
private static DatabaseAdapter instance;
|
||||
|
||||
private final File databasePath;
|
||||
|
@ -53,6 +57,7 @@ public class DatabaseAdapter {
|
|||
databasePath = context.getDatabasePath(DB_NAME);
|
||||
db = context.openOrCreateDatabase(databasePath.toString(), MODE_PRIVATE, null);
|
||||
initTables();
|
||||
updateTable();
|
||||
}
|
||||
|
||||
|
||||
|
@ -78,6 +83,15 @@ public class DatabaseAdapter {
|
|||
}
|
||||
|
||||
|
||||
private void updateTable() {
|
||||
if (db.getVersion() < DB_VERSION) {
|
||||
db.execSQL(TABLE_TWEET_ADD_PLACE);
|
||||
db.execSQL(TABLE_TWEET_ADD_GEO);
|
||||
db.setVersion(DB_VERSION);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void initTables() {
|
||||
db.execSQL(TABLE_USER);
|
||||
db.execSQL(TABLE_TWEET);
|
||||
|
|
|
@ -25,10 +25,11 @@ public class MessageLoader extends AsyncTask<Long, Void, List<Message>> {
|
|||
DEL
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private TwitterException twException;
|
||||
private Mode mode;
|
||||
private WeakReference<MessageListFragment> ui;
|
||||
private TwitterEngine mTwitter;
|
||||
private TwitterException twException;
|
||||
private AppDatabase db;
|
||||
private MessageAdapter adapter;
|
||||
|
||||
|
|
|
@ -20,8 +20,9 @@ import twitter4j.TwitterException;
|
|||
|
||||
public class TrendLoader extends AsyncTask<Void, Void, List<String>> {
|
||||
|
||||
private WeakReference<TrendListFragment> ui;
|
||||
@Nullable
|
||||
private TwitterException twException;
|
||||
private WeakReference<TrendListFragment> ui;
|
||||
private TwitterEngine mTwitter;
|
||||
private AppDatabase db;
|
||||
private TrendAdapter adapter;
|
||||
|
|
|
@ -17,6 +17,9 @@ import java.util.List;
|
|||
import twitter4j.TwitterException;
|
||||
|
||||
|
||||
/**
|
||||
* Timeline loader Task
|
||||
*/
|
||||
public class TweetLoader extends AsyncTask<Object, Void, List<Tweet>> {
|
||||
|
||||
public enum Mode {
|
||||
|
@ -29,11 +32,12 @@ public class TweetLoader extends AsyncTask<Object, Void, List<Tweet>> {
|
|||
TWEET_SEARCH
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private TwitterException twException;
|
||||
private Mode mode;
|
||||
private WeakReference<TweetListFragment> ui;
|
||||
private TweetAdapter adapter;
|
||||
private TwitterEngine mTwitter;
|
||||
private TwitterException twException;
|
||||
private AppDatabase db;
|
||||
|
||||
|
||||
|
|
|
@ -18,6 +18,9 @@ import java.util.List;
|
|||
|
||||
import twitter4j.TwitterException;
|
||||
|
||||
/**
|
||||
* User list loader task
|
||||
*/
|
||||
public class UserLoader extends AsyncTask<Object, Void, List<TwitterUser>> {
|
||||
|
||||
public enum Mode {
|
||||
|
@ -28,10 +31,11 @@ public class UserLoader extends AsyncTask<Object, Void, List<TwitterUser>> {
|
|||
SEARCH
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private TwitterException twException;
|
||||
private Mode mode;
|
||||
private WeakReference<UserListFragment> ui;
|
||||
private TwitterEngine mTwitter;
|
||||
private TwitterException twException;
|
||||
private UserAdapter adapter;
|
||||
|
||||
|
||||
|
|
|
@ -9,7 +9,10 @@ import android.net.ConnectivityManager;
|
|||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextPaint;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.text.style.ClickableSpan;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
|
@ -51,6 +54,7 @@ import java.util.regex.Matcher;
|
|||
import java.util.regex.Pattern;
|
||||
|
||||
import static android.os.AsyncTask.Status.RUNNING;
|
||||
import static android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
|
||||
import static android.view.MotionEvent.ACTION_DOWN;
|
||||
import static android.view.MotionEvent.ACTION_UP;
|
||||
import static android.view.View.VISIBLE;
|
||||
|
@ -76,7 +80,7 @@ public class TweetDetail extends AppCompatActivity implements OnClickListener, O
|
|||
private static final Pattern linkPattern = Pattern.compile("/@?[\\w_]+/status/\\d{1,20}/?.*");
|
||||
|
||||
private View header, footer, videoButton, imageButton;
|
||||
private TextView tweet_api, tweetDate, tweetText, scrName, usrName;
|
||||
private TextView tweet_api, tweetDate, tweetText, scrName, usrName, tweetLoc;
|
||||
private Button rtwButton, favButton, replyName;
|
||||
private ImageView profile_img;
|
||||
|
||||
|
@ -123,6 +127,7 @@ public class TweetDetail extends AppCompatActivity implements OnClickListener, O
|
|||
tweetText = findViewById(R.id.tweet_detailed);
|
||||
tweetDate = findViewById(R.id.timedetail);
|
||||
tweet_api = findViewById(R.id.used_api);
|
||||
tweetLoc = findViewById(R.id.tweet_location);
|
||||
imageButton = findViewById(R.id.image_attach);
|
||||
videoButton = findViewById(R.id.video_attach);
|
||||
|
||||
|
@ -403,6 +408,30 @@ public class TweetDetail extends AppCompatActivity implements OnClickListener, O
|
|||
}
|
||||
if (settings.getImageLoad())
|
||||
Picasso.get().load(tweet.getUser().getImageLink() + "_bigger").into(profile_img);
|
||||
|
||||
SpannableStringBuilder locationText = new SpannableStringBuilder("");
|
||||
if (!tweet.getLocationName().isEmpty())
|
||||
locationText.append(tweet.getLocationName());
|
||||
if (!tweet.getLocationCoordinates().isEmpty()) {
|
||||
final int start = locationText.length();
|
||||
locationText.append(tweet.getLocationCoordinates());
|
||||
final int end = locationText.length() - 1;
|
||||
locationText.setSpan(new ClickableSpan() {
|
||||
@Override
|
||||
public void onClick(@NonNull View widget) {
|
||||
Intent locationIntent = new Intent(Intent.ACTION_VIEW);
|
||||
locationIntent.setData(Uri.parse("geo:" + tweet.getLocationCoordinates()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDrawState(@NonNull TextPaint ds) {
|
||||
ds.setColor(settings.getHighlightColor());
|
||||
ds.setUnderlineText(false);
|
||||
}
|
||||
}, start, end, SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
tweetLoc.setText(locationText);
|
||||
tweetLoc.setVisibility(VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -275,6 +275,8 @@ public class TweetPopup extends AppCompatActivity implements OnClickListener, Lo
|
|||
|
||||
@Override
|
||||
public void onProviderDisabled(String provider) {
|
||||
if (gpsLocation == null)
|
||||
Toast.makeText(this, R.string.error_gps, LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@
|
|||
android:paddingRight="@dimen/button_padding"
|
||||
android:background="@drawable/button"
|
||||
android:singleLine="true"
|
||||
android:textSize="@dimen/textsize_refer"
|
||||
android:textSize="@dimen/tweet_textsize_api"
|
||||
android:visibility="gone"
|
||||
style="@style/Widget.AppCompat.Button.Borderless" />
|
||||
|
||||
|
@ -103,13 +103,23 @@
|
|||
android:id="@+id/tweet_detailed"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
android:autoLink="web"
|
||||
android:fadeScrollbars="false"
|
||||
android:linksClickable="true"
|
||||
android:maxLines="@integer/text_tweet_lines"
|
||||
android:scrollbars="vertical"
|
||||
android:textSize="@dimen/textsize_tweet" />
|
||||
android:textSize="@dimen/textsize_tweet"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tweet_location"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:visibility="gone"
|
||||
android:textSize="@dimen/textsize_tweet_locale"
|
||||
app:drawableLeftCompat="@drawable/userlocation"
|
||||
app:drawableStartCompat="@drawable/userlocation" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/image_attach"
|
||||
|
@ -139,7 +149,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:linksClickable="false"
|
||||
android:singleLine="true"
|
||||
android:textSize="@dimen/textsize_refer" />
|
||||
android:textSize="@dimen/tweet_textsize_api" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -124,4 +124,5 @@
|
|||
<string name="error_cant_copy_clipboard">Link konnte nicht kopiert werden!</string>
|
||||
<string name="info_gps_attached">GPS Position hinzugefügt</string>
|
||||
<string name="info_get_location">starte GPS lokalisierung...</string>
|
||||
<string name="error_gps">GPS lokalisierung fehlgeschlagen!</string>
|
||||
</resources>
|
|
@ -28,12 +28,13 @@
|
|||
<dimen name="textsize_profileedit">18sp</dimen>
|
||||
<dimen name="textsize_count">18sp</dimen>
|
||||
<dimen name="textsize_tweet">18sp</dimen>
|
||||
<dimen name="textsize_tweet_locale">12sp</dimen>
|
||||
<dimen name="textsize_settings">18sp</dimen>
|
||||
<dimen name="textsize_profile">12sp</dimen>
|
||||
<dimen name="textsize_button">12sp</dimen>
|
||||
<dimen name="textsize_date">12sp</dimen>
|
||||
<dimen name="textsize_name">12sp</dimen>
|
||||
<dimen name="textsize_refer">12sp</dimen>
|
||||
<dimen name="tweet_textsize_api">12sp</dimen>
|
||||
<dimen name="textsize_checkbox">10sp</dimen>
|
||||
<integer name="text_tweet_lines">9</integer>
|
||||
<integer name="text_bio_lines">5</integer>
|
||||
|
|
|
@ -125,4 +125,5 @@
|
|||
<string name="error_cant_copy_clipboard">can\'t copy link to clipboard!</string>
|
||||
<string name="info_gps_attached">GPS position added</string>
|
||||
<string name="info_get_location">starting location...</string>
|
||||
<string name="error_gps">could not fetch GPS data!</string>
|
||||
</resources>
|
Loading…
Reference in New Issue