moved package, image download fix

This commit is contained in:
nuclearfog 2022-01-14 11:05:49 +01:00
parent 996ce859fd
commit 803683691e
No known key found for this signature in database
GPG Key ID: AA0271FBE406DB98
19 changed files with 129 additions and 59 deletions

View File

@ -24,7 +24,7 @@ import androidx.appcompat.app.AppCompatActivity;
import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.backend.ListUpdater; import org.nuclearfog.twidda.backend.ListUpdater;
import org.nuclearfog.twidda.backend.holder.ListHolder; import org.nuclearfog.twidda.backend.api.holder.ListHolder;
import org.nuclearfog.twidda.model.UserList; import org.nuclearfog.twidda.model.UserList;
import org.nuclearfog.twidda.backend.utils.AppStyles; import org.nuclearfog.twidda.backend.utils.AppStyles;
import org.nuclearfog.twidda.backend.utils.ErrorHandler; import org.nuclearfog.twidda.backend.utils.ErrorHandler;

View File

@ -43,6 +43,7 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Locale;
/** /**
* This activity is a superclass to all activities who need permission to take actions * This activity is a superclass to all activities who need permission to take actions
@ -63,7 +64,6 @@ public abstract class MediaActivity extends AppCompatActivity implements Locatio
private static final String MIME_ALL_READ = "*/*"; private static final String MIME_ALL_READ = "*/*";
private static final String MIME_IMAGE_READ = "image/*"; private static final String MIME_IMAGE_READ = "image/*";
private static final String MIME_VIDEO_READ = "video/*"; private static final String MIME_VIDEO_READ = "video/*";
private static final String MIME_IMAGE_WRITE = "image/jpeg";
/** /**
* mime types for videos and images * mime types for videos and images
@ -190,21 +190,26 @@ public abstract class MediaActivity extends AppCompatActivity implements Locatio
imageTask.execute(src, dest); imageTask.execute(src, dest);
} else { } else {
// use scoped storage // use scoped storage
String ext = selectedImage.getLastPathSegment();
ext = ext.substring(ext.indexOf('.') + 1).toLowerCase(Locale.ENGLISH);
String mime = "image/" + ext;
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
values.put(DISPLAY_NAME, imageName); values.put(DISPLAY_NAME, imageName);
values.put(DATE_TAKEN, System.currentTimeMillis()); values.put(DATE_TAKEN, System.currentTimeMillis());
values.put(RELATIVE_PATH, DIRECTORY_PICTURES); values.put(RELATIVE_PATH, DIRECTORY_PICTURES);
values.put(MIME_TYPE, MIME_IMAGE_WRITE); values.put(MIME_TYPE, mime);
Uri imageUri = getContentResolver().insert(EXTERNAL_CONTENT_URI, values); Uri imageUri = getContentResolver().insert(EXTERNAL_CONTENT_URI, values);
if (imageUri != null) { if (imageUri != null) {
InputStream source = getContentResolver().openInputStream(selectedImage);
OutputStream dest = getContentResolver().openOutputStream(imageUri); OutputStream dest = getContentResolver().openOutputStream(imageUri);
imageTask = new ImageSaver(this); imageTask = new ImageSaver(this);
imageTask.execute(selectedImage, dest); imageTask.execute(source, dest);
} }
} }
} }
} catch (FileNotFoundException err) { } catch (Exception err) {
err.printStackTrace(); err.printStackTrace();
onError();
} }
} }

View File

@ -54,12 +54,12 @@ public class MediaViewer extends MediaActivity implements OnImageClickListener,
OnPreparedListener, OnInfoListener, OnErrorListener, OnClickListener, OnTouchListener { OnPreparedListener, OnInfoListener, OnErrorListener, OnClickListener, OnTouchListener {
/** /**
* Key for online media files * Key for a string array with http links
*/ */
public static final String KEY_MEDIA_LINK = "media_link"; public static final String KEY_MEDIA_LINK = "media_link";
/** /**
* key for local media files * key for an Uri array with local links
*/ */
public static final String KEY_MEDIA_URI = "media_uri"; public static final String KEY_MEDIA_URI = "media_uri";
@ -73,28 +73,29 @@ public class MediaViewer extends MediaActivity implements OnImageClickListener,
* cache folder name * cache folder name
*/ */
public static final String CACHE_FOLDER = "imagecache"; public static final String CACHE_FOLDER = "imagecache";
/** /**
* setup media viewer for images from twitter * value for {@link #KEY_MEDIA_TYPE} to show images
*/ */
public static final int MEDIAVIEWER_IMAGE = 0x997BCDCE; public static final int MEDIAVIEWER_IMAGE = 0x997BCDCE;
/** /**
* setup media viewer for videos * value for {@link #KEY_MEDIA_TYPE} to show a video
*/ */
public static final int MEDIAVIEWER_VIDEO = 0x500C9A42; public static final int MEDIAVIEWER_VIDEO = 0x500C9A42;
/** /**
* setup media viewer for GIF animation * value for {@link #KEY_MEDIA_TYPE} to show an animated image
*/ */
public static final int MEDIAVIEWER_ANGIF = 0x6500EDB0; public static final int MEDIAVIEWER_ANGIF = 0x6500EDB0;
/** /**
* refresh time for video progress update * refresh time for video progress updatein milliseconds
*/ */
private static final int PROGRESS_UPDATE = 1000; private static final int PROGRESS_UPDATE = 1000;
/** /**
* speed factor for fast forward or backward * speed factor for fast forward or fast backward
*/ */
private static final int SPEED_FACTOR = 6; private static final int SPEED_FACTOR = 6;
@ -505,8 +506,10 @@ public class MediaViewer extends MediaActivity implements OnImageClickListener,
private void clearCache() { private void clearCache() {
File cacheFolder = new File(getExternalCacheDir(), CACHE_FOLDER); File cacheFolder = new File(getExternalCacheDir(), CACHE_FOLDER);
File[] files = cacheFolder.listFiles(); File[] files = cacheFolder.listFiles();
for (File file : files) { if (files != null && files.length > 0) {
file.delete(); for (File file : files) {
file.delete();
}
} }
} }
} }

View File

@ -23,7 +23,7 @@ import androidx.annotation.Nullable;
import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.backend.MessageUpdater; import org.nuclearfog.twidda.backend.MessageUpdater;
import org.nuclearfog.twidda.backend.holder.DirectmessageHolder; import org.nuclearfog.twidda.backend.api.holder.DirectmessageHolder;
import org.nuclearfog.twidda.backend.utils.AppStyles; import org.nuclearfog.twidda.backend.utils.AppStyles;
import org.nuclearfog.twidda.backend.utils.ErrorHandler; import org.nuclearfog.twidda.backend.utils.ErrorHandler;
import org.nuclearfog.twidda.dialog.ConfirmDialog; import org.nuclearfog.twidda.dialog.ConfirmDialog;

View File

@ -37,7 +37,7 @@ import com.squareup.picasso.Picasso;
import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.backend.UserUpdater; import org.nuclearfog.twidda.backend.UserUpdater;
import org.nuclearfog.twidda.backend.holder.ProfileHolder; import org.nuclearfog.twidda.backend.api.holder.ProfileHolder;
import org.nuclearfog.twidda.model.User; import org.nuclearfog.twidda.model.User;
import org.nuclearfog.twidda.backend.utils.AppStyles; import org.nuclearfog.twidda.backend.utils.AppStyles;
import org.nuclearfog.twidda.backend.utils.ErrorHandler; import org.nuclearfog.twidda.backend.utils.ErrorHandler;

View File

@ -27,7 +27,7 @@ import androidx.annotation.Nullable;
import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.backend.TweetUpdater; import org.nuclearfog.twidda.backend.TweetUpdater;
import org.nuclearfog.twidda.backend.holder.TweetHolder; import org.nuclearfog.twidda.backend.api.holder.TweetHolder;
import org.nuclearfog.twidda.backend.utils.AppStyles; import org.nuclearfog.twidda.backend.utils.AppStyles;
import org.nuclearfog.twidda.backend.utils.ErrorHandler; import org.nuclearfog.twidda.backend.utils.ErrorHandler;
import org.nuclearfog.twidda.backend.utils.StringTools; import org.nuclearfog.twidda.backend.utils.StringTools;

View File

@ -18,7 +18,8 @@ import java.io.InputStream;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
/** /**
* background async to download images to a cache folder * This AsyncTask class downloads images to a local cache folder
* and creates Uri of the images.
* *
* @author nuclearfog * @author nuclearfog
* @see MediaViewer * @see MediaViewer
@ -40,6 +41,7 @@ public class ImageLoader extends AsyncTask<Uri, Uri, Boolean> {
super(); super();
callback = new WeakReference<>(activity); callback = new WeakReference<>(activity);
twitter = Twitter.get(activity); twitter = Twitter.get(activity);
// create cache folder if not exists
cache = new File(activity.getExternalCacheDir(), MediaViewer.CACHE_FOLDER); cache = new File(activity.getExternalCacheDir(), MediaViewer.CACHE_FOLDER);
cache.mkdirs(); cache.mkdirs();
} }
@ -48,10 +50,12 @@ public class ImageLoader extends AsyncTask<Uri, Uri, Boolean> {
@Override @Override
protected Boolean doInBackground(Uri[] links) { protected Boolean doInBackground(Uri[] links) {
try { try {
// create cache folder if not exists
// download imaged to a local cache folder // download imaged to a local cache folder
for (Uri link : links) { for (Uri link : links) {
File file = new File(cache, StringTools.getRandomString()); // create temp file for the image
String end = link.getLastPathSegment();
String ext = end.substring(end.indexOf('.'));
File file = new File(cache, StringTools.getRandomString() + ext);
file.createNewFile(); file.createNewFile();
FileOutputStream os = new FileOutputStream(file); FileOutputStream os = new FileOutputStream(file);
InputStream input = twitter.downloadImage(link.toString()); InputStream input = twitter.downloadImage(link.toString());

View File

@ -9,7 +9,7 @@ import java.io.OutputStream;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
/** /**
* background task to save an image to the external storage * This AsyncTask class moves a cached image to the destiny folder
* *
* @author nuclearfog * @author nuclearfog
* @see MediaActivity * @see MediaActivity

View File

@ -5,7 +5,7 @@ import android.os.AsyncTask;
import org.nuclearfog.twidda.activities.ListEditor; import org.nuclearfog.twidda.activities.ListEditor;
import org.nuclearfog.twidda.backend.api.Twitter; import org.nuclearfog.twidda.backend.api.Twitter;
import org.nuclearfog.twidda.backend.api.TwitterException; import org.nuclearfog.twidda.backend.api.TwitterException;
import org.nuclearfog.twidda.backend.holder.ListHolder; import org.nuclearfog.twidda.backend.api.holder.ListHolder;
import org.nuclearfog.twidda.model.UserList; import org.nuclearfog.twidda.model.UserList;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;

View File

@ -7,7 +7,7 @@ import androidx.annotation.NonNull;
import org.nuclearfog.twidda.activities.MessageEditor; import org.nuclearfog.twidda.activities.MessageEditor;
import org.nuclearfog.twidda.backend.api.Twitter; import org.nuclearfog.twidda.backend.api.Twitter;
import org.nuclearfog.twidda.backend.api.TwitterException; import org.nuclearfog.twidda.backend.api.TwitterException;
import org.nuclearfog.twidda.backend.holder.DirectmessageHolder; import org.nuclearfog.twidda.backend.api.holder.DirectmessageHolder;
import org.nuclearfog.twidda.backend.utils.ErrorHandler; import org.nuclearfog.twidda.backend.utils.ErrorHandler;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
@ -47,8 +47,7 @@ public class MessageUpdater extends AsyncTask<Void, Void, Boolean> {
// upload media if any // upload media if any
long mediaId = -1; long mediaId = -1;
if (message.getMediaStream() != null) { if (message.getMediaStream() != null) {
mediaId = twitter.uploadMedia(message.getMediaStream(), message.getMimeType()); mediaId = twitter.uploadMedia(message.getMediaStream());
message.getMediaStream().close();
} }
// upload message and media ID if defined // upload message and media ID if defined
if (!isCancelled()) { if (!isCancelled()) {
@ -59,6 +58,8 @@ public class MessageUpdater extends AsyncTask<Void, Void, Boolean> {
this.twException = twException; this.twException = twException;
} catch (Exception err) { } catch (Exception err) {
err.printStackTrace(); err.printStackTrace();
} finally {
message.getMediaStream().close();
} }
return false; return false;
} }

View File

@ -5,7 +5,8 @@ import android.os.AsyncTask;
import org.nuclearfog.twidda.activities.TweetEditor; import org.nuclearfog.twidda.activities.TweetEditor;
import org.nuclearfog.twidda.backend.api.Twitter; import org.nuclearfog.twidda.backend.api.Twitter;
import org.nuclearfog.twidda.backend.api.TwitterException; import org.nuclearfog.twidda.backend.api.TwitterException;
import org.nuclearfog.twidda.backend.holder.TweetHolder; import org.nuclearfog.twidda.backend.api.holder.MediaStream;
import org.nuclearfog.twidda.backend.api.holder.TweetHolder;
import org.nuclearfog.twidda.backend.utils.ErrorHandler; import org.nuclearfog.twidda.backend.utils.ErrorHandler;
import java.io.InputStream; import java.io.InputStream;
@ -48,12 +49,12 @@ public class TweetUpdater extends AsyncTask<Void, Void, Boolean> {
mediaIds = new long[mediaStreams.length]; mediaIds = new long[mediaStreams.length];
for (int pos = 0; pos < mediaStreams.length; pos++) { for (int pos = 0; pos < mediaStreams.length; pos++) {
// upload media file and save media ID // upload media file and save media ID
mediaIds[pos] = twitter.uploadMedia(mediaStreams[pos], mimeTypes[pos]); MediaStream mediaStream = new MediaStream(mediaStreams[pos], mimeTypes[pos]);
mediaIds[pos] = twitter.uploadMedia(mediaStream);
// close stream after upload // close stream after upload
mediaStreams[pos].close(); mediaStreams[pos].close();
} }
} }
// upload tweet // upload tweet
if (!isCancelled()) { if (!isCancelled()) {
double[] coordinates = null; double[] coordinates = null;

View File

@ -7,7 +7,7 @@ import androidx.annotation.Nullable;
import org.nuclearfog.twidda.activities.ProfileEditor; import org.nuclearfog.twidda.activities.ProfileEditor;
import org.nuclearfog.twidda.backend.api.Twitter; import org.nuclearfog.twidda.backend.api.Twitter;
import org.nuclearfog.twidda.backend.api.TwitterException; import org.nuclearfog.twidda.backend.api.TwitterException;
import org.nuclearfog.twidda.backend.holder.ProfileHolder; import org.nuclearfog.twidda.backend.api.holder.ProfileHolder;
import org.nuclearfog.twidda.backend.utils.ErrorHandler; import org.nuclearfog.twidda.backend.utils.ErrorHandler;
import org.nuclearfog.twidda.model.User; import org.nuclearfog.twidda.model.User;
import org.nuclearfog.twidda.database.AppDatabase; import org.nuclearfog.twidda.database.AppDatabase;

View File

@ -7,6 +7,7 @@ import android.os.Build;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.nuclearfog.twidda.backend.api.holder.MediaStream;
import org.nuclearfog.twidda.backend.lists.Directmessages; import org.nuclearfog.twidda.backend.lists.Directmessages;
import org.nuclearfog.twidda.backend.lists.UserLists; import org.nuclearfog.twidda.backend.lists.UserLists;
import org.nuclearfog.twidda.backend.lists.Users; import org.nuclearfog.twidda.backend.lists.Users;
@ -1137,16 +1138,16 @@ public class Twitter {
/** /**
* upload medida file to twitter and generate a media ID * upload medida file to twitter and generate a media ID
* *
* @param uploadStream path to the local file * @param mediaStream inputstream with MIME type of the media
* @return media ID * @return media ID
*/ */
public long uploadMedia(InputStream uploadStream, String mime) throws TwitterException { public long uploadMedia(MediaStream mediaStream) throws TwitterException {
List<String> params = new ArrayList<>(4); List<String> params = new ArrayList<>(4);
try { try {
// step 1 INIT // step 1 INIT
params.add("command=INIT"); params.add("command=INIT");
params.add("media_type=" + mime); params.add("media_type=" + mediaStream.getMimeType());
params.add("total_bytes=" + uploadStream.available()); params.add("total_bytes=" + mediaStream.available());
Response response = post(MEDIA_UPLOAD, params); Response response = post(MEDIA_UPLOAD, params);
if (response.code() < 200 || response.code() >= 300 || response.body() == null) if (response.code() < 200 || response.code() >= 300 || response.body() == null)
throw new TwitterException(response); throw new TwitterException(response);
@ -1158,7 +1159,7 @@ public class Twitter {
params.add("command=APPEND"); params.add("command=APPEND");
params.add("segment_index=0"); params.add("segment_index=0");
params.add("media_id=" + mediaId); params.add("media_id=" + mediaId);
response = post(MEDIA_UPLOAD, params, uploadStream, "media"); response = post(MEDIA_UPLOAD, params, mediaStream.getStream(), "media");
if (response.code() < 200 || response.code() >= 300) if (response.code() < 200 || response.code() >= 300)
throw new TwitterException(response); throw new TwitterException(response);

View File

@ -1,10 +1,11 @@
package org.nuclearfog.twidda.backend.holder; package org.nuclearfog.twidda.backend.api.holder;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -18,8 +19,7 @@ public class DirectmessageHolder {
private String name; private String name;
private String text; private String text;
private String mimeType = ""; private MediaStream mediaStream;
private InputStream fileStream;
public DirectmessageHolder(String name, String text) { public DirectmessageHolder(String name, String text) {
@ -36,8 +36,9 @@ public class DirectmessageHolder {
public void addMedia(Context context, @NonNull Uri uri) { public void addMedia(Context context, @NonNull Uri uri) {
ContentResolver resolver = context.getContentResolver(); ContentResolver resolver = context.getContentResolver();
try { try {
fileStream = resolver.openInputStream(uri); String mimeType = resolver.getType(uri);
mimeType = resolver.getType(uri); InputStream fileStream = resolver.openInputStream(uri);
mediaStream = new MediaStream(fileStream, mimeType);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -61,21 +62,14 @@ public class DirectmessageHolder {
return text; return text;
} }
/** /**
* get inputstream of the media file * get inputstream of the media file
* *
* @return input stream * @return input stream
*/ */
public InputStream getMediaStream() { @Nullable
return fileStream; public MediaStream getMediaStream() {
} return mediaStream;
/**
* get MIME type of the media file
*
* @return mime type string
*/
public String getMimeType() {
return mimeType;
} }
} }

View File

@ -1,4 +1,4 @@
package org.nuclearfog.twidda.backend.holder; package org.nuclearfog.twidda.backend.api.holder;
/** /**
* This class stores information about an user list * This class stores information about an user list
@ -80,6 +80,6 @@ public class ListHolder {
* @return true if list exists * @return true if list exists
*/ */
public boolean exists() { public boolean exists() {
return listId != -1; return listId != NEW_LIST;
} }
} }

View File

@ -0,0 +1,52 @@
package org.nuclearfog.twidda.backend.api.holder;
import java.io.IOException;
import java.io.InputStream;
/**
* this class collects information about a media file to upload
*
* @author nuclearfog
*/
public class MediaStream {
private InputStream inputStream;
private String mimeType;
public MediaStream(InputStream inputStream, String mimeType) {
this.inputStream = inputStream;
this.mimeType = mimeType;
}
/**
* @return input stream of the media file
*/
public InputStream getStream() {
return inputStream;
}
/**
* @return MIME type of the stream
*/
public String getMimeType() {
return mimeType;
}
/**
* @return remaining bytes of the stream
*/
public int available() throws IOException {
return inputStream.available();
}
/**
* close stream
*/
public void close() {
try {
inputStream.close();
} catch (IOException e) {
// ignore
}
}
}

View File

@ -1,8 +1,9 @@
package org.nuclearfog.twidda.backend.holder; package org.nuclearfog.twidda.backend.api.holder;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import java.io.IOException; import java.io.IOException;
@ -37,7 +38,7 @@ public class ProfileHolder {
* @param context context used to resolve Uri * @param context context used to resolve Uri
* @param profileImgUri Uri of the local image file * @param profileImgUri Uri of the local image file
*/ */
public void addImageUri(Context context, @Nullable Uri profileImgUri) { public void addImageUri(Context context, @NonNull Uri profileImgUri) {
try { try {
profileImgStream = context.getContentResolver().openInputStream(profileImgUri); profileImgStream = context.getContentResolver().openInputStream(profileImgUri);
} catch (IOException e) { } catch (IOException e) {
@ -51,7 +52,7 @@ public class ProfileHolder {
* @param context context used to resolve Uri * @param context context used to resolve Uri
* @param bannerImgUri Uri of the local image file * @param bannerImgUri Uri of the local image file
*/ */
public void addBannerUri(Context context, @Nullable Uri bannerImgUri) { public void addBannerUri(Context context, @NonNull Uri bannerImgUri) {
try { try {
bannerImgStream = context.getContentResolver().openInputStream(bannerImgUri); bannerImgStream = context.getContentResolver().openInputStream(bannerImgUri);
} catch (IOException e) { } catch (IOException e) {
@ -90,6 +91,7 @@ public class ProfileHolder {
/** /**
* @return filestream of the profile image * @return filestream of the profile image
*/ */
@Nullable
public InputStream getProfileImageStream() { public InputStream getProfileImageStream() {
return profileImgStream; return profileImgStream;
} }
@ -97,6 +99,7 @@ public class ProfileHolder {
/** /**
* @return filestream of the banner image * @return filestream of the banner image
*/ */
@Nullable
public InputStream getBannerImageStream() { public InputStream getBannerImageStream() {
return bannerImgStream; return bannerImgStream;
} }

View File

@ -1,4 +1,4 @@
package org.nuclearfog.twidda.backend.holder; package org.nuclearfog.twidda.backend.api.holder;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
@ -6,6 +6,7 @@ import android.location.Location;
import android.net.Uri; import android.net.Uri;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
@ -97,6 +98,7 @@ public class TweetHolder {
* *
* @return media type * @return media type
*/ */
@Nullable
public String[] getMimeTypes() { public String[] getMimeTypes() {
return mimeTypes; return mimeTypes;
} }
@ -106,6 +108,7 @@ public class TweetHolder {
* *
* @return array of media paths * @return array of media paths
*/ */
@Nullable
public InputStream[] getMediaStreams() { public InputStream[] getMediaStreams() {
return mediaStreams; return mediaStreams;
} }

View File

@ -11,7 +11,7 @@ import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
import java.util.UUID; import java.util.Random;
import javax.crypto.Mac; import javax.crypto.Mac;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
@ -27,6 +27,8 @@ public final class StringTools {
private static final SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.US); private static final SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.US);
private static final long DEFAULT_TIME = 0x61D99F64; private static final long DEFAULT_TIME = 0x61D99F64;
private static Random rand = new Random();
private StringTools() { private StringTools() {
} }
@ -171,8 +173,9 @@ public final class StringTools {
* @return random percentaged string * @return random percentaged string
*/ */
public static String getRandomString() { public static String getRandomString() {
String rand = UUID.randomUUID().toString(); byte[] randomBytes = new byte[16];
return new String(Base64.encode(rand.getBytes(), Base64.NO_PADDING | Base64.NO_WRAP)); rand.nextBytes(randomBytes);
return new String(Base64.encode(randomBytes, Base64.URL_SAFE | Base64.NO_PADDING | Base64.NO_WRAP));
} }
/** /**