This commit is contained in:
nuclearfog 2022-01-27 22:50:05 +01:00
parent db3253453e
commit 8d0971b284
No known key found for this signature in database
GPG Key ID: AA0271FBE406DB98
10 changed files with 158 additions and 125 deletions

View File

@ -107,7 +107,7 @@ public class MessageEditor extends MediaActivity implements OnClickListener, OnC
messageAsync.cancel(true);
loadingCircle.dismiss();
if (holder != null) {
holder.closeMediaStream();
holder.close();
}
super.onDestroy();
}
@ -204,9 +204,9 @@ public class MessageEditor extends MediaActivity implements OnClickListener, OnC
String username = receiver.getText().toString();
String message = this.message.getText().toString();
if (!username.trim().isEmpty() && (!message.trim().isEmpty() || holder.getMediaUri() != null)) {
if (holder.initMedia(getContentResolver())) {
holder.addName(username);
holder.addText(message);
if (holder.prepare(getContentResolver())) {
holder.setName(username);
holder.setText(message);
messageAsync = new MessageUpdater(this, holder);
messageAsync.execute();
if (!loadingCircle.isShowing()) {

View File

@ -13,6 +13,7 @@ import android.graphics.Point;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.util.Patterns;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
@ -159,7 +160,7 @@ public class ProfileEditor extends MediaActivity implements OnClickListener, OnP
String userLoc = loc.getText().toString();
String userBio = bio.getText().toString();
if (user != null && username.equals(user.getUsername()) && userLink.equals(user.getProfileUrl())
&& userLoc.equals(user.getLocation()) && userBio.equals(user.getDescription()) && holder.imageAdded()) {
&& userLoc.equals(user.getLocation()) && userBio.equals(user.getDescription()) && !holder.imageAdded()) {
finish();
} else if (username.isEmpty() && userLink.isEmpty() && userLoc.isEmpty() && userBio.isEmpty()) {
finish();
@ -195,7 +196,7 @@ public class ProfileEditor extends MediaActivity implements OnClickListener, OnP
protected void onMediaFetched(int resultType, @NonNull Uri uri) {
// Add image as profile image
if (resultType == REQUEST_PROFILE) {
if (holder.addImageUri(this, uri)) {
if (holder.setImage(this, uri)) {
profile_image.setImageURI(uri);
} else {
Toast.makeText(this, R.string.error_adding_media, Toast.LENGTH_SHORT).show();
@ -203,7 +204,7 @@ public class ProfileEditor extends MediaActivity implements OnClickListener, OnP
}
// Add image as banner image
else if (resultType == REQUEST_BANNER) {
if (holder.addBannerUri(this, uri)) {
if (holder.setBanner(this, uri)) {
Point displaySize = new Point();
getWindowManager().getDefaultDisplay().getSize(displaySize);
picasso.load(uri).resize(displaySize.x, displaySize.x / 3).centerCrop(Gravity.TOP).into(profile_banner, this);
@ -300,12 +301,12 @@ public class ProfileEditor extends MediaActivity implements OnClickListener, OnP
if (username.trim().isEmpty()) {
String errMsg = getString(R.string.error_empty_name);
name.setError(errMsg);
} else if (!userLink.isEmpty() && userLink.contains(" ")) {// todo add URL validator
} else if (!userLink.isEmpty() && !Patterns.WEB_URL.matcher(userLink).matches()) {
String errMsg = getString(R.string.error_invalid_link);
link.setError(errMsg);
} else if (editorAsync == null || editorAsync.getStatus() != RUNNING) {
holder.setProfileInformation(username, userLink, userBio, userLoc);
if (holder.initMedia(getContentResolver())) {
holder.setProfile(username, userLink, userBio, userLoc);
if (holder.prepare(getContentResolver())) {
editorAsync = new UserUpdater(this, holder);
editorAsync.execute();
if (!loadingCircle.isShowing()) {

View File

@ -89,7 +89,7 @@ public class TweetEditor extends MediaActivity implements OnClickListener, OnPro
private EditText tweetText;
private View locationPending;
private TweetUpdate tweetUpdate;
private TweetUpdate tweetUpdate = new TweetUpdate();
private int selectedFormat = MEDIA_NONE;
@ -121,7 +121,7 @@ public class TweetEditor extends MediaActivity implements OnClickListener, OnPro
long inReplyId = data.getLongExtra(KEY_TWEETPOPUP_REPLYID, 0);
String prefix = data.getStringExtra(KEY_TWEETPOPUP_TEXT);
tweetUpdate = new TweetUpdate(inReplyId);
tweetUpdate.setReplyId(inReplyId);
if (prefix != null) {
tweetText.append(prefix);
}
@ -244,7 +244,7 @@ public class TweetEditor extends MediaActivity implements OnClickListener, OnPro
@Override
protected void onAttachLocation(@Nullable Location location) {
if (location != null) {
tweetUpdate.addLocation(location);
tweetUpdate.setLocation(location);
Toast.makeText(this, R.string.info_gps_attached, LENGTH_LONG).show();
} else {
Toast.makeText(this, R.string.error_gps, LENGTH_LONG).show();
@ -374,10 +374,10 @@ public class TweetEditor extends MediaActivity implements OnClickListener, OnPro
*/
private void updateTweet() {
// first initialize filestreams of the media files
if (tweetUpdate.initMedia(getContentResolver())) {
if (tweetUpdate.prepare(getContentResolver())) {
String tweetStr = tweetText.getText().toString();
// add media
tweetUpdate.addText(tweetStr);
tweetUpdate.setText(tweetStr);
// send tweet
uploaderAsync = new TweetUpdater(this);
uploaderAsync.execute(tweetUpdate);

View File

@ -54,7 +54,7 @@ public class MessageUpdater extends AsyncTask<Void, Void, Boolean> {
twitter.sendDirectmessage(id, message.getText(), mediaId);
}
// close mediastream
message.closeMediaStream();
message.close();
return true;
} catch (TwitterException twException) {
this.twException = twException;

View File

@ -38,8 +38,9 @@ public class TweetUpdater extends AsyncTask<TweetUpdate, Void, Boolean> {
@Override
protected Boolean doInBackground(TweetUpdate... tweets) {
try {
TweetUpdate update = tweets[0];
// upload media first
MediaStream[] mediaStreams = tweets[0].getMediaStreams();
MediaStream[] mediaStreams = update.getMediaStreams();
long[] mediaIds = new long[mediaStreams.length];
for (int pos = 0; pos < mediaStreams.length; pos++) {
// upload media file and save media ID
@ -47,12 +48,10 @@ public class TweetUpdater extends AsyncTask<TweetUpdate, Void, Boolean> {
}
// upload tweet
if (!isCancelled()) {
twitter.uploadTweet(tweets[0], mediaIds);
}
// close all mediastreams
for (MediaStream mediaStream : mediaStreams) {
mediaStream.close();
twitter.uploadTweet(update, mediaIds);
}
// close inputstreams
update.close();
return true;
} catch (TwitterException twException) {
this.twException = twException;

View File

@ -53,7 +53,7 @@ public class UserUpdater extends AsyncTask<Void, Void, User> {
// save new user information
db.storeUser(user);
// close image streams
profile.closeStreams();
profile.close();
return user;
} catch (TwitterException twException) {
this.twException = twException;

View File

@ -3,6 +3,7 @@ package org.nuclearfog.twidda.backend.api.holder;
import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@ -18,22 +19,22 @@ import java.io.InputStream;
*/
public class DirectmessageUpdate {
private String name;
private String text;
private Uri uri;
private MediaStream mediaStream;
private String name = "";
private String text = "";
/**
* @param name screen name of the user
*/
public void addName(String name) {
public void setName(String name) {
this.name = name;
}
/**
* @param text message text
*/
public void addText(String text) {
public void setText(String text) {
this.text = text;
}
@ -80,8 +81,13 @@ public class DirectmessageUpdate {
* @param uri uri of a local media file
*/
public boolean addMedia(Context context, @NonNull Uri uri) {
DocumentFile file = DocumentFile.fromSingleUri(context, uri);
if (file != null && file.exists() && file.canRead() && file.length() > 0) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
DocumentFile file = DocumentFile.fromSingleUri(context, uri);
if (file != null && file.exists() && file.canRead() && file.length() > 0) {
this.uri = uri;
return true;
}
} else {
this.uri = uri;
return true;
}
@ -93,7 +99,7 @@ public class DirectmessageUpdate {
*
* @return true if initialization succeded
*/
public boolean initMedia(ContentResolver resolver) {
public boolean prepare(ContentResolver resolver) {
if (uri == null)
return true;
try {
@ -112,7 +118,7 @@ public class DirectmessageUpdate {
/**
* close inputstream of media file
*/
public void closeMediaStream() {
public void close() {
if (mediaStream != null) {
mediaStream.close();
}

View File

@ -3,6 +3,7 @@ package org.nuclearfog.twidda.backend.api.holder;
import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@ -18,8 +19,8 @@ import java.io.InputStream;
*/
public class ProfileUpdate {
private Uri imageUrl, bannerUrl;
private InputStream profileImgStream, bannerImgStream;
private Uri[] imageUrls = new Uri[2];
private InputStream[] imageStreams = new InputStream[2];
private String name = "";
private String url = "";
@ -27,21 +28,14 @@ public class ProfileUpdate {
private String location = "";
/**
* add profile image Uri
* setup profile information
*
* @param context context used to resolve Uri
* @param imageUrl Uri of the local image file
* @param name username to update
* @param url profile url
* @param description description of the profile
* @param location location name
*/
public boolean addImageUri(Context context, @NonNull Uri imageUrl) {
DocumentFile file = DocumentFile.fromSingleUri(context, imageUrl);
if (file != null && file.exists() && file.canRead() && file.length() > 0) {
this.imageUrl = imageUrl;
return true;
}
return false;
}
public void setProfileInformation(String name, String url, String description, String location) {
public void setProfile(String name, String url, String description, String location) {
this.name = name;
this.url = url;
this.description = description;
@ -49,49 +43,43 @@ public class ProfileUpdate {
}
/**
* add banner image Uri
* add profile image Uri
*
* @param context context used to resolve Uri
* @param bannerUrl Uri of the local image file
* @param context context used to resolve Uri
* @param imageUrl Uri of the local image file
*/
public boolean addBannerUri(Context context, @NonNull Uri bannerUrl) {
DocumentFile file = DocumentFile.fromSingleUri(context, bannerUrl);
if (file != null && file.exists() && file.canRead() && file.length() > 0) {
this.bannerUrl = bannerUrl;
public boolean setImage(Context context, @NonNull Uri imageUrl) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
DocumentFile file = DocumentFile.fromSingleUri(context, imageUrl);
if (file != null && file.exists() && file.canRead() && file.length() > 0) {
imageUrls[0] = imageUrl;
return true;
}
} else {
imageUrls[0] = imageUrl;
return true;
}
return false;
}
/**
* initialize inputstreams of the image files
* add banner image Uri
*
* @return true if initialization succeded
* @param context context used to resolve Uri
* @param bannerUrl Uri of the local image file
*/
public boolean initMedia(ContentResolver resolver) {
try {
// open input streams
if (imageUrl != null) {
InputStream profileImgStream = resolver.openInputStream(imageUrl);
if (profileImgStream != null && profileImgStream.available() > 0) {
this.profileImgStream = profileImgStream;
} else {
return false;
}
public boolean setBanner(Context context, @NonNull Uri bannerUrl) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
DocumentFile file = DocumentFile.fromSingleUri(context, bannerUrl);
if (file != null && file.exists() && file.canRead() && file.length() > 0) {
imageUrls[1] = bannerUrl;
return true;
}
if (bannerUrl != null) {
InputStream bannerImgStream = resolver.openInputStream(bannerUrl);
if (bannerImgStream != null && bannerImgStream.available() > 0) {
this.bannerImgStream = bannerImgStream;
} else {
return false;
}
}
} catch (Exception e) {
e.printStackTrace();
return false;
} else {
imageUrls[1] = bannerUrl;
return true;
}
return true;
return false;
}
/**
@ -126,7 +114,7 @@ public class ProfileUpdate {
* @return true if any image is added
*/
public boolean imageAdded() {
return imageUrl != null || bannerUrl != null;
return imageUrls[0] != null || imageUrls[1] != null;
}
/**
@ -134,7 +122,7 @@ public class ProfileUpdate {
*/
@Nullable
public InputStream getProfileImageStream() {
return profileImgStream;
return imageStreams[0];
}
/**
@ -142,18 +130,43 @@ public class ProfileUpdate {
*/
@Nullable
public InputStream getBannerImageStream() {
return bannerImgStream;
return imageStreams[1];
}
/**
* initialize inputstreams of the image files
*
* @return true if initialization succeded
*/
public boolean prepare(ContentResolver resolver) {
try {
for (int i = 0 ; i < imageUrls.length ; i++) {
if (imageUrls[i] != null) {
InputStream profileImgStream = resolver.openInputStream(imageUrls[i]);
if (profileImgStream != null && profileImgStream.available() > 0) {
this.imageStreams[i] = profileImgStream;
} else {
return false;
}
}
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* close all image streams
*/
public void closeStreams() {
public void close() {
try {
if (profileImgStream != null)
profileImgStream.close();
if (bannerImgStream != null)
bannerImgStream.close();
for (InputStream imageStream : imageStreams) {
if (imageStream != null) {
imageStream.close();
}
}
} catch (IOException e) {
// ignore
}

View File

@ -4,6 +4,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.location.Location;
import android.net.Uri;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.documentfile.provider.DocumentFile;
@ -23,25 +24,24 @@ public class TweetUpdate {
private long replyId;
private double longitude;
private double latitude;
private List<Uri> mediaUris;
private MediaStream[] mediaStreams = {};
private List<Uri> mediaUris = new ArrayList<>(5);
private MediaStream[] mediaStreams = {};
private boolean hasLocation = false;
/**
* create a tweet holder
* set ID of the replied tweet
*
* @param replyId ID of the tweet to reply or 0 if this tweet is not a reply
* @param replyId Tweet ID
*/
public TweetUpdate(long replyId) {
public void setReplyId(long replyId) {
this.replyId = replyId;
mediaUris = new ArrayList<>(5);
}
/**
* add tweet text
*/
public void addText(String text) {
public void setText(String text) {
this.text = text;
}
@ -52,48 +52,25 @@ public class TweetUpdate {
* @return number of media attached to this holder or -1 if file is invalid
*/
public int addMedia(Context context, Uri mediaUri) {
DocumentFile file = DocumentFile.fromSingleUri(context, mediaUri);
if (file != null && file.exists() && file.canRead() && file.length() > 0) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
DocumentFile file = DocumentFile.fromSingleUri(context, mediaUri);
if (file != null && file.exists() && file.canRead() && file.length() > 0) {
mediaUris.add(mediaUri);
return mediaUris.size();
}
} else {
mediaUris.add(mediaUri);
return mediaUris.size();
}
return -1;
}
/**
* prepare media streams if media Uri is added
*
* @return true if success, false if an error occurs
*/
public boolean initMedia(ContentResolver resolver) {
if (mediaUris.isEmpty())
return true;
try {
// open input streams
mediaStreams = new MediaStream[mediaUris.size()];
for (int i = 0 ; i < mediaStreams.length ; i++) {
InputStream is = resolver.openInputStream(mediaUris.get(i));
String mime = resolver.getType(mediaUris.get(i));
// check if stream is valid
if (is != null && mime != null && is.available() > 0) {
mediaStreams[i] = new MediaStream(is, mime);
} else {
return false;
}
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* Add location to a tweet
*
* @param location location information
*/
public void addLocation(@NonNull Location location) {
public void setLocation(@NonNull Location location) {
this.latitude = location.getLatitude();
this.longitude = location.getLongitude();
hasLocation = true;
@ -171,6 +148,43 @@ public class TweetUpdate {
return mediaUris.size();
}
/**
* prepare media streams if media Uri is added
*
* @return true if success, false if an error occurs
*/
public boolean prepare(ContentResolver resolver) {
if (mediaUris.isEmpty())
return true;
try {
// open input streams
mediaStreams = new MediaStream[mediaUris.size()];
for (int i = 0 ; i < mediaStreams.length ; i++) {
InputStream is = resolver.openInputStream(mediaUris.get(i));
String mime = resolver.getType(mediaUris.get(i));
// check if stream is valid
if (is != null && mime != null && is.available() > 0) {
mediaStreams[i] = new MediaStream(is, mime);
} else {
return false;
}
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* close all open streams
*/
public void close() {
for (MediaStream mediaStream : mediaStreams) {
mediaStream.close();
}
}
@NonNull
@Override
public String toString() {

View File

@ -113,7 +113,7 @@
android:layout_height="wrap_content"
android:hint="@string/enter_username"
android:importantForAutofill="no"
android:inputType="text"
android:inputType="textNoSuggestions"
android:maxLength="@integer/editprofile_username_max_length"
android:singleLine="true"
style="@style/TextInput" />
@ -146,7 +146,7 @@
android:layout_height="wrap_content"
android:hint="@string/edit_hint_link"
android:importantForAutofill="no"
android:inputType="text"
android:inputType="textNoSuggestions"
android:singleLine="true"
style="@style/TextInput" />