I have created an application that requires uploading video to the server using FTP. I have searched many options but once the file is uploaded it is not playing back. Can someone help me ?
Here is the data sender parts of my BackgroundSenderService
I used AndroidNetworking library.
My service triggers on some periods to check db that has unsent media file.
For the success and error results I updated db, but you can send Localbroadcasts to trigger some interface elements on UI.
private void checkDbForUpload() {
((MainApp) getApplicationContext()).setMediaSenderIsIdle(false);
MediaModel media = ((MainApp) getApplicationContext()).getFirstUnsendMedia(mContext);
if (media != null) {
if (((MainApp) getApplicationContext()).getHasMission() && ((MainApp) getApplicationContext()).getLastResponse().getCaseId().equals(media.getCaseId())) {
stopThisService();
return;
}
boolean canBeginUpload = ((MainApp) getApplicationContext()).canBeginMediaUpload(mContext);
if (canBeginUpload) {
Log.d(TAG, "checkDbForUpload: we have connected and we have file to upload");
startUploadingProcess(media);
} else {
((MainApp) getApplicationContext()).setMediaSenderIsIdle(true);
stopThisService();
}
} else {
((MainApp) getApplicationContext()).setMediaSenderIsIdle(true);
stopThisService();
}
}
private void startUploadingProcess(MediaModel media) {
int mediaStatus = media.getUploadStatus();
Log.d(TAG, "beginMediaUploadProcess: #" + media.getId() + " Status: " + mediaStatus);
if (media.getRetryCount() > Constants.UPLOAD_ERROR_RETRY_COUNT) {
media.setSessionId("");
saveMediaToDb(media);
}
switch (mediaStatus) {
case Constants.MEDIA_STATUS_UPLOADED:
deleteMediaFromDbAndDisk(media);
checkDbForUpload();
break;
case Constants.MEDIA_STATUS_UPLOADING:
case Constants.MEDIA_STATUS_WAITING:
case Constants.MEDIA_STATUS_ERROR:
if (media.getSessionId() != null && !media.getSessionId().equals("")) {
Log.d(TAG, "startUploadingProcess: has session");
startPutWithoutBody(media);
} else {
Log.d(TAG, "startUploadingProcess: no session");
getMediaEndpoint(media);
}
break;
}
}
private void startPostTask(MediaModel media) {
media.setSessionId("");
setMediaAsWaiting(media);
File file = new File(media.getFile());
String contentType = getMimeType(file.getPath());
setMediaAsUploading(media);
String postUrl = ENDPOINT + "?uploadType=resumable&name=" + createSendingFileName(media);
AndroidNetworking.post(postUrl)
.setTag("uploadRequest")
.setPriority(Priority.HIGH)
.addHeaders("X-Api-Key", Constants.API_KEY_UPLOAD)
.addHeaders("Content-Type", "application/json")
.addHeaders("X-Upload-Content-Type", contentType)
.addHeaders("X-Upload-Content-Length", String.valueOf(file.length()))
.addJSONObjectBody(prepareMetaData(media).toJSON())
.build()
.getAsJSONObject(new JSONObjectRequestListener() {
#Override
public void onResponse(JSONObject response) {
Log.d(TAG, "onResponse: " + response.toString());
UploadPostResponseModel responseModel = new UploadPostResponseModel(response);
if (responseModel.getStatusCode() == Constants.HTTP_STATUS_OK) {
media.setSessionId(responseModel.getId());
try {
startPutTask(media);
} catch (Exception e) {
e.printStackTrace();
}
} else {
setMediaUploadError(media);
}
}
#Override
public void onError(ANError anError) {
Log.d(TAG, "onError: " + anError.getErrorDetail());
setMediaUploadError(media);
}
});
}
private void startPutWithoutBody(MediaModel media) {
String putUrl = ENDPOINT + (ENDPOINT.contains("?") ? "&" : "?") + "upload_id=" + media.getSessionId();
AndroidNetworking.put(putUrl)
.setTag("putRequest")
.setPriority(Priority.HIGH)
.addHeaders("X-Api-Key", Constants.API_KEY_UPLOAD)
.addHeaders("Content-Range", getContentRangeString(media))
.build()
.getAsJSONObject(new JSONObjectRequestListener() {
#Override
public void onResponse(JSONObject response) {
Log.d(TAG, "onResponse: " + response.toString());
//UploadPostResponseModel responseModel = new UploadPostResponseModel(response);
}
#Override
public void onError(ANError anError) {
setMediaUploadError(media);
}
});
}
private void startPutTask(MediaModel media) {
if (!((MainApp) getApplicationContext()).canBeginMediaUpload(mContext)) {
setMediaAsWaiting(media);
stopThisService();
}
//if fails -> consider using this https://stackoverflow.com/a/54961878/1492681
try {
File tmpDir = mContext.getCacheDir();
File tmpFile = File.createTempFile("TMPFILE", media.getSessionId(), tmpDir);
File orgFile = new File(media.getFile());
int startIndex = (int) media.getUploadedBytes();
Log.d(TAG, "startIndex: " + startIndex);
int bytesLeft = (int) (orgFile.length() - startIndex);
Log.d(TAG, "bytesLeft: " + bytesLeft);
RandomAccessFile f = new RandomAccessFile(media.getFile(), "r");
int len = Constants.CHUNKSIZE;
if (Constants.CHUNKSIZE >= bytesLeft) {
len = bytesLeft;
}
Log.d(TAG, "len: " + len);
byte[] buffer = new byte[len];
f.seek(startIndex);
f.read(buffer, 0, len);
Log.d(TAG, "buffer: " + buffer.length);
int endIndex = startIndex + len;
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(tmpFile));
bos.write(buffer);
bos.flush();
bos.close();
//send chunk here
String putUrl = ENDPOINT + "?uploadType=resumable&upload_id=" + media.getSessionId();
AndroidNetworking.put(putUrl)
.setTag("putRequest")
.setPriority(Priority.HIGH)
.addHeaders("X-Api-Key", Constants.API_KEY_UPLOAD)
.addHeaders("Content-Range", getContentRangeString(media))
.addFileBody(tmpFile)
.build()
.getAsOkHttpResponse(new OkHttpResponseListener() {
#Override
public void onResponse(Response response) {
switch (response.code()) {
case Constants.HTTP_STATUS_CREATED:
case Constants.HTTP_STATUS_OK:
setMediaAsUploaded(media);
break;
case Constants.HTTP_STATUS_PERMANENT_REDIRECT:
case Constants.HTTP_STATUS_RANGENOTSATISFIABLE:
Log.d(TAG, "onResponse: " + response.toString());
long receivedBytes = parseRange(response);
Log.d(TAG, "uploaded: " + receivedBytes + " of " + orgFile.length());
media.setUploadedBytes(receivedBytes);
setMediaAsUploading(media);
Log.d(TAG, "onResponse: receivedBytesFromServer: " + receivedBytes);
try {
startPutTask(media);
} catch (Exception e) {
e.printStackTrace();
}
break;
default:
setMediaUploadError(media);
break;
}
}
#Override
public void onError(ANError anError) {
setMediaUploadError(media);
}
});
} catch (IOException | ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
setMediaUploadError(media);
}
}
private String getContentRangeString(MediaModel media) {
File file = new File(media.getFile());
long fileLength = file.length();
String contentRange = "bytes */" + fileLength;
Log.d(TAG, "getContentRangeString: " + contentRange);
return contentRange;
}
Related
I use multiple retrofit in a service and my ui freeze,
So I try with asyncTask executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
I try also with a Thread but I have the same problem.
I put only one retrofit function for example, the other function is similar.
I read this in other post : Retrofit already run in the background so it cannot block your UI. I assume it must be something else
I use the same function with socket and asyncTask and screen doesn't freeze.
So I don't find the problem
public class RestApiService extends Service {
private Retrofit retrofit;
private RetrofitInterface retrofitInterface;
private String BASE_URL = "http://******.com:8080";
****
#Override
public void onCreate() {
if (BuildConfig.DEBUG)
Log.v(Constants.TAG6,"onCreate");
retrofit = new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();
retrofitInterface = retrofit.create(RetrofitInterface.class);
session = new SessionManager(getApplicationContext());
postemanager = new PosteManager(getApplicationContext());
contactmanager = new ContactManager(getApplicationContext());
commentmanager = new CommentManager(getApplicationContext());
groupeManager = new GroupeManager(getApplicationContext());
notifHelp = new NotificationHelper(getApplicationContext());
tinydb = new TinyDB(YuYuApplication.getAppContext());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
/*GetLists getLists = new GetLists();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
getLists.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else
getLists.execute(); */
getListPosts();
getListCallbackReceivedPoste();
getListCallbackReceivedComment();
getListPostVu();
getListPostVuFromWeb();
getListCommentVu();
getListCommentVuFromWeb();
/* new Thread(new Runnable() {
#Override
public void run() {
getListPosts();
getListCallbackReceivedPoste();
getListCallbackReceivedComment();
getListPostVu();
getListPostVuFromWeb();
getListCommentVu();
getListCommentVuFromWeb();
}
}).start(); */
return Service.START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
class GetLists extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... voids) {
getListPosts();
getListCallbackReceivedPoste();
getListCallbackReceivedComment();
getListPostVu();
getListPostVuFromWeb();
getListCommentVu();
getListCommentVuFromWeb();
return null;
}
}
public void getListPosts(){
Call<ArrayList<PosteFromServer>> call = retrofitInterface.getListPosts(session.getPhoneSession());
call.enqueue(new Callback<ArrayList<PosteFromServer>>() {
#Override
public void onResponse(Call<ArrayList<PosteFromServer>> call, Response<ArrayList<PosteFromServer>> response) {
ArrayList<PosteFromServer> myDataList = response.body();
Poste poste = new Poste();
final JSONArray callbackList = new JSONArray();
for (int i = 0; i < myDataList.size(); i++) {
if (postemanager.CheckIsIdPostEmetAlreadyInDBorNot(myDataList.get(i).getIdPostEmet()) == false) {
int nbPostNotRead = session.getNumbrePostNotRead();
nbPostNotRead++;
int nbCmtNotRead = session.getNumbreCommentNotRead();
session.createNumbrePostNotRead(nbPostNotRead);
//Notification counter
try {
// Badges.removeBadge(getApplicationContext());
// Alternative way
Badges.setBadge(getApplicationContext(), nbPostNotRead + nbCmtNotRead);
if (BuildConfig.DEBUG) {
int Nb = nbPostNotRead + nbCmtNotRead;
if (BuildConfig.DEBUG) {
Log.v(Constants.TAG6, "Badges Poste ; CMT " + nbPostNotRead + " " + nbCmtNotRead);
Log.v(Constants.TAG6, "Badges Poste + CMT " + Nb);
}
}
} catch (BadgesNotSupportedException badgesNotSupportedException) {
if (BuildConfig.DEBUG) {
Log.d(Constants.TAG6, "getListPost BADGES MSG:" + badgesNotSupportedException.getMessage());
}
}
final JSONObject callback = new JSONObject();
try {
callback.put("app_id", myDataList.get(i).getApp_id());
if (BuildConfig.DEBUG) {
Log.v(Constants.TAG6, "getListPost app_id " + myDataList.get(i).getApp_id());
}
/* Contact cdest = new Contact();
ArrayList<Contact> cdestList = new ArrayList<>();
cdest.setPhone(session.getPhoneSession());
cdestList.add(cdest);
sendCallback.put("destPhone",cdestList); */
callback.put("destPhone", session.getPhoneSession());
callback.put("idPostEmet", myDataList.get(i).getIdPostEmet());
if (BuildConfig.DEBUG) {
Log.v(Constants.TAG6, "emmetteur" + myDataList.get(i).getEmetr_phone());
}
callback.put("emetr_phone", myDataList.get(i).getEmetr_phone());
callback.put("typeOfCallback", "callBackDevice");
} catch (JSONException e) {
e.printStackTrace();
}
if (BuildConfig.DEBUG) {
Log.v(Constants.TAG6, "called emit message");
}
if (BuildConfig.DEBUG) {
Log.d(Constants.TAG6, "Handling friendcall");
}
//Catching IdMessages
boolean checkGroupNotification = false;
try {
if (BuildConfig.DEBUG)
Log.d(Constants.TAG6, " GROUPES " + myDataList.get(i).getGroups());
groups = Utils.convertStringToDummyObject(myDataList.get(i).getGroups().toString());
//TODO idGroup exit in TinyDB for notification purpose
TinyDB tinydb = new TinyDB(YuYuApplication.getAppContext());
ArrayList<String> mIdArray = tinydb.getListString("ids");
for (int j = 0; j < mIdArray.size(); j++)
for (int k = 0; k < groups.size(); k++)
if (mIdArray.get(k).equals(groups.get(k).getId())) {
checkGroupNotification = true;
break;
}
} catch (Exception ex) {
groups = null;
}
//Catching IdMessages
boolean checkGroupSon = false;
try {
groups = Utils.convertStringToDummyObject(myDataList.get(i).getGroups().toString());
//TODO idGroup exit in TinyDB for notification purpose
TinyDB tinydb = new TinyDB(YuYuApplication.getAppContext());
ArrayList<String> mIdArraySon = tinydb.getListString("idGroupsSon");
for (int j = 0; j < mIdArraySon.size(); j++)
for (int k = 0; k < groups.size(); k++)
if (mIdArraySon.get(j).equals(groups.get(k).getId())) {
checkGroupSon = true;
break;
}
} catch (Exception ex) {
groups = null;
}
try {
if (myDataList.get(i).getSansPhoto() != null) {
final String emeteur_phone = myDataList.get(i).getEmetr_phone();
String emeteur_name = null;
if (myDataList.get(i).getEmetr_name() != null) {
emeteur_name = myDataList.get(i).getEmetr_name();
}
message = myDataList.get(i).getText();
destFromServer = myDataList.get(i).getDestinataires();
idPostEmet = myDataList.get(i).getIdPostEmet();
counterDest = Integer.toString(myDataList.get(i).getCounterDest());
typePoste = myDataList.get(i).getTypePoste();
//TODO idGroup exit in TinyDB
TinyDB tinydb = new TinyDB(YuYuApplication.getAppContext());
ArrayList<String> mIdArray = tinydb.getListString("ids");
if (groups != null) {
for (int j = 0; j < mIdArray.size(); j++)
for (int k = 0; k < groups.size(); k++)
if (mIdArray.get(j).equals(groups.get(k).getId())) {
checkGroupNotification = true;
break;
}
}
//Debut Test
// Session class instance
// session = new SessionManager(getApplicato());
try {
EmeteurPoste = contactmanager.getContactsByNbrPhone(Utils.AddCaractDest(emeteur_phone));
if (EmeteurPoste.getName().equals(EmeteurPoste.getPhone()) || EmeteurPoste.getName().equals("null") && emeteur_name != null) { // || !c.getName().equals(name) a utiliser pour changer le nom a mettre en place qd l emmet sera un contact et pas un string
EmeteurPoste.setName(emeteur_name);
contactmanager.updateContactName(EmeteurPoste);
}
} catch (Exception ex) {
Log.v(Constants.TAG6, ex.getMessage());
}
if (EmeteurPoste == null) {
EmeteurPoste = new Contact();
if (emeteur_name == null)
EmeteurPoste.setName(Utils.AddCaractDest(emeteur_phone));
else
EmeteurPoste.setName(emeteur_name);
EmeteurPoste.setPhone(Utils.AddCaractDest(emeteur_phone));
EmeteurPoste.setStatus(Constants.STATUS_INSCRIS_NON_ENRG_REPERTOIRE);
contactmanager.openForWrite();
EmeteurPoste.setId((int) contactmanager.createContact(EmeteurPoste));
contactmanager.close();
}
if (EmeteurPoste != null) {
if (BuildConfig.DEBUG) {
Log.v(Constants.TAG6, " getListPost 3 Contact EmetPost Name" + EmeteurPoste.getName() + "EmetPost Phone" + EmeteurPoste.getPhone());
}
emeteur = EmeteurPoste.getName();
} else {
if (BuildConfig.DEBUG) {
Log.v(Constants.TAG6, " getListPost EmetPost null");
}
emeteur = emeteur_phone;
}
// destinataires = Utils.convertStringToArray();
destinataires = contactmanager.updateAllNameAndIdDestinataireForPost(destFromServer);
if (BuildConfig.DEBUG) {
Log.v(Constants.TAG6, " getListPost destinataires " + destinataires);
}
//TEST L'icône sera une petite loupe
//TEST int icon = R.drawable.ic_launcher;
// Le premier titre affiché
//TEST CharSequence tickerText = "Titre de la notification";
// Daté de maintenant
long when = System.currentTimeMillis();
if (BuildConfig.DEBUG) {
Log.d(Constants.TAG6, " getListPost notification manager");
}
//Loading webView
/*if(Utils.linkScannerWebView(msg)!=null)
typePoste = String.valueOf(PosteAdapter.TYPE_WEB_VIEW);*/
if (BuildConfig.DEBUG) {
Log.v(Constants.TAG6, " getListPost 4 Before getLinkPreview idPostEmet " + idPostEmet + " myDataList.get(i).getIdPostEmet() " + myDataList.get(i).getIdPostEmet() + " message " + message + " data.getString(text).toString() " + myDataList.get(i).getText());
}
if (typePoste.equals(String.valueOf(Constants.TYPE_WEB_VIEW)) || typePoste.equals(String.valueOf(Constants.TYPE_WEB_VIEW_Retry))) {
final boolean checkGrNotif = checkGroupNotification;
final boolean checkGrSon = checkGroupSon;
LinkUtil.getInstance().getLinkPreview(getBaseContext(), Utils.linkScannerWebView(message), message, EmeteurPoste, emeteur_phone, idPostEmet, destinataires, counterDest, groups, new GetLinkPreviewListener() {
#Override
public void onSuccess(final LinkPreview linkPreview) {
String img = null;
Gson gson = new Gson();
File imgFile = linkPreview.getImageFile();
try {
if (imgFile != null && imgFile.exists()) {
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
if (myBitmap != null) {
img = Utils.SaveImage(getBaseContext(), myBitmap, true);
}
}
} catch (Exception ex) {
}
if (BuildConfig.DEBUG) {
Log.v(Constants.TAG6, " getListPost 5 after save image and description and BEFORE addLink idPostEmet " + idPostEmet + " Message " + gson.toJson(linkPreview));
}
// postemessage = addMessage(EmeteurPoste, emeteur_phone, linkPreview.getTextPoste(), destinataires, linkPreview.getIdPostEmet(), counterDest, String.valueOf(Constants.TYPE_WEB_VIEW), img, groups, checkGrNotif, checkGrSon); //gson.toJson(linkPreview)
postemessage = addLinkWebView(linkPreview, String.valueOf(Constants.TYPE_WEB_VIEW), img, checkGrNotif, checkGrSon); //gson.toJson(linkPreview)
if (BuildConfig.DEBUG) {
Log.v(Constants.TAG6, " 10 after save image and description and AFTER addMessage idPostEmet " + idPostEmet);
}
try {
if ((postemessage != null) && callback.getString("idPostEmet") == postemessage.getIdpostemet()) {
if (BuildConfig.DEBUG) {
Log.v(Constants.TAG6, " getListPost 11 called emit POST WEB VIEW link: " + gson.toJson(linkPreview));
}
// socket.emit("callBackDevice", sendCallback);
callbackList.put(callback);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onFailed(Exception var1) {
if (BuildConfig.DEBUG) {
Log.d(Constants.TAG6, " getListPost 5 after save image and description and BEFORE addMessage idPostEmet " + idPostEmet + " Message " + message);
}
postemessage = addMessage(EmeteurPoste, emeteur_phone, message, destinataires, idPostEmet, counterDest, "0", null, groups, checkGrNotif, checkGrSon);
if (BuildConfig.DEBUG) {
Log.d(Constants.TAG6, " getListPost 10 after save image and description and BEFORE addMessage idPostEmet " + idPostEmet + " Message " + message);
}
try {
if ((postemessage != null) && callback.getString("idPostEmet") == postemessage.getIdpostemet()) {
if (BuildConfig.DEBUG) {
Log.v(Constants.TAG6, " getListPost 11 called emit POST WEB VIEW FAILED message: " + message);
}
// socket.emit("callBackDevice", sendCallback);
callbackList.put(callback);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
} else {
postemessage = addMessage(EmeteurPoste, emeteur_phone, message, destinataires, idPostEmet, counterDest, "0", null, groups, checkGroupNotification, checkGroupSon);
try {
if ((postemessage != null) && callback.getString("idPostEmet") == postemessage.getIdpostemet()) {
if (BuildConfig.DEBUG) {
Log.v(Constants.TAG6, "getListPost called emit POST MESSAGE message: " + message);
}
// socket.emit("callBackDevice", sendCallback);
callbackList.put(callback);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
// Fin Test
}
} catch (Exception e) {
Log.d(Constants.TAG6, "getListPost friend call object cannot be parsed");
e.printStackTrace();
}
} else {
if (BuildConfig.DEBUG) {
Log.d(Constants.TAG6, " getListPostidPostEmet ALREADY EXIST");
}
//Sending callback if poste is already exist
JSONObject callback = new JSONObject();
try {
callback.put("app_id", myDataList.get(i).getApp_id());
/* Contact cdest = new Contact();
ArrayList<Contact> cdestList = new ArrayList<>();
cdest.setPhone(session.getPhoneSession());
cdestList.add(cdest);
callback.put("destPhone",cdestList); */
callback.put("destPhone", session.getPhoneSession());
callback.put("idPostEmet", myDataList.get(i).getIdPostEmet());
callback.put("emetr_phone", myDataList.get(i).getEmetr_phone());
callback.put("typeOfCallback", "callBackDevice");
} catch (JSONException e) {
e.printStackTrace();
}
if (BuildConfig.DEBUG) {
Log.v(Constants.TAG6, " getListPost post message called emit");
}
if (BuildConfig.DEBUG) {
Log.d(Constants.TAG6, "getListPost send callBackDevice callback " + callback.toString());
}
// socket.emit("callBackDevice",callback);
if (BuildConfig.DEBUG) {
Log.v(Constants.TAG6, " getListPost RECEIVE LISTPOSTS i " + i + " callback " + callback);
}
callbackList.put(callback);
}
/* } catch (JSONException e) {
e.printStackTrace();
if (BuildConfig.DEBUG) {
Log.d(Constants.TAG6,"3 try catch exception "+e.toString()+" myDataList.get(i).toString() "+myDataList.get(i).toString());
}
} */
}
if (BuildConfig.DEBUG) {
Log.v(Constants.TAG6, " getListPost END RECEIVE LISTPOSTS callbackList " + callbackList);
}
if(callbackList.length() > 0){
sendCallbackList(callbackList);
}else{
getListPostISentFromWeb();
}
}
#Override
public void onFailure(Call<ArrayList<PosteFromServer>> call, Throwable t) {
if (BuildConfig.DEBUG)
Log.v(Constants.TAG6, " getListPost onFailure " + t.getMessage());
}
});
}
I ran YouTube Data API's Android Quickstart code example and an error occurred: null from onCancelled() method. When I wrote a debug log, ChannelListResponse result did not executed. What can I do to solve problem?
#Override
protected List<String> doInBackground(Void... params) {
try {
return getDataFromApi();
} catch (Exception e) {
mLastError = e;
cancel(true);
return null;
}
}
private List<String> getDataFromApi() throws IOException {
Log.d(TAG, "inside getDataFromApi: " + mService);
// Get a list of up to 10 files.
List<String> channelInfo = new ArrayList<String>();
YouTube.Channels.List request = mService.channels()
.list("snippet,contentDetails,statistics");
ChannelListResponse result = request.setForUsername("GoogleDevelopers").execute();
Log.d(TAG, "getDataFromApi: " + request);
Log.d(TAG, "getDataFromApi: " + result);
List<Channel> channels = result.getItems();
if (channels != null) {
Channel channel = channels.get(0);
channelInfo.add("This channel's ID is " + channel.getId() + ". " +
"Its title is '" + channel.getSnippet().getTitle() + ", " +
"and it has " + channel.getStatistics().getViewCount() + " views.");
}
return channelInfo;
}
#Override
protected void onCancelled() {
mProgress.hide();
if (mLastError != null) {
if (mLastError instanceof GooglePlayServicesAvailabilityIOException) {
showGooglePlayServicesAvailabilityErrorDialog(
((GooglePlayServicesAvailabilityIOException) mLastError)
.getConnectionStatusCode());
} else if (mLastError instanceof UserRecoverableAuthIOException) {
startActivityForResult(
((UserRecoverableAuthIOException) mLastError).getIntent(),
MainActivity.REQUEST_AUTHORIZATION);
} else {
mOutputText.setText("The following error occurred:\n"
+ mLastError.getMessage());
}
} else {
mOutputText.setText("Request cancelled.");
}
}
I am trying to upload plain text and image to the api using RetroFit. I want make sure the request continues to execute on orientation change. To do this, I have encapsulated the RetroFit api call inside a Headless fragment. This works fine when I try to upload an image. The request stops and resumes on device rotation. However it just gets cancelled on a text upload.
The only difference between the two uploads is that for image upload I use execute() and for text I use enqueue(). However, if I try to use execute() with the text, it still does not work.
Below is some code :-
UpdateTaskHelper (Headless fragment)
public static class UploadTaskHelper extends Fragment
{
private UploadAsync uploadTask;
private ProgressDialog m_loadingp;
public static UploadTaskHelper newInstance()
{
return new UploadTaskHelper();
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public void onDestroy()
{
Log.d(getClass().getName(), "[onDestroy]");
super.onDestroy();
if (uploadTask != null)
{
uploadTask.cancel(true);
}
}
public void startUpload(ActionActivity actionActivity, boolean shouldTakePhoto, boolean isTextNote, String noteContent)
{
uploadTask = new UploadAsync(actionActivity, shouldTakePhoto, isText, noteContent);
uploadTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
private static class UploadAsync extends AsyncTask<Void, Void, Void>
{
private Bitmap m_bitmap = null;
private Pair<Boolean, String> m_errorPair;
private File m_uploadedFile = null;
private WeakReference<ActionActivity> m_weakActivity;
private boolean shouldTakePhoto;
private boolean isTextNote;
private java.io.File m_capturedImageFile;
UploadAsync(#NonNull ActionActivity activity, boolean shouldTakePhoto, boolean isTextNote, String textNoteContent)
{
this.m_weakActivity = new WeakReference<>(activity);
this.shouldTakePhoto = shouldTakePhoto;
this.isTextNote = isTextNote;
}
#Override
protected Void doInBackground(Void... params)
{
try
{
final ActionActivity activity = this.m_weakActivity.get();
activity.m_fileAPIWrapper = new FileAPIWrapper(new IHttpEventTracker<File>()
{
#Override
public void getCallProgress(int progress) {}
#Override
public void onCallFail(#NonNull String cause, #NonNull Throwable t, #Nullable ResponseBody responseBody)
{
m_errorPair = new Pair<>(true, t.getLocalizedMessage());
}
#Override
public void onCallSuccess(#NonNull RealmList<File> models)
{
m_errorPair = new Pair<>(false, AppConstants.EMPTY_STRING);
m_uploadedFile = models.get(0);
}
});
if(!isTextNote)
{
final java.io.File storageDir = new java.io.File(Environment.getExternalStorageDirectory()
.getAbsolutePath() + java.io.File.separator + activity.getPackageName()
+ java.io.File.separator + "-" + java.io.File.separator);
if (!storageDir.exists())
{
storageDir.mkdirs();
}
this.m_capturedImageFile = java.io.File.createTempFile("IMG_" + System.currentTimeMillis(), ".jpg", storageDir);
final FileOutputStream outStream = new FileOutputStream(this.m_capturedImageFile);
this.m_bitmap.compress(Bitmap.CompressFormat.JPEG, 50, outStream);
outStream.flush();
outStream.close();
final ByteArrayOutputStream stream = new ByteArrayOutputStream();
this.m_bitmap.compress(Bitmap.CompressFormat.JPEG, 50, stream);
activity.m_fileAPIWrapper.postImage(RequestBody.create(MediaType.parse("image/jpeg"), stream.toByteArray()));
stream.flush();
stream.close();
}
else
{
activity.m_fileAPIWrapper.postTextNote(RequestBody.create(MediaType.parse("multipart/raw"), activity.m_addContentNoteEdit.getText()
.toString()));
}
}
catch (Exception e)
{
e.printStackTrace();
this.m_errorPair = new Pair<>(true, e.toString());
}
return null;
}
#Override
protected void onPreExecute()
{
super.onPreExecute();
activity.m_loading.show();
}
#Override
protected void onPostExecute(Void aVoid)
{
super.onPostExecute(aVoid);
}
}
}
Network calls :-
public void postImage(#NonNull RequestBody reqFile) {
if (m_eventTracker != null) {
final ResponseToken token = NetworkUtil.getAccessToken();
if (getService() != null && m_httpOperationWrapper != null && token != null) {
m_call = getService().postImage(token.getTokenType() + " " + token.getAccessToken(), NetworkUtil.X_VERSION,
"filename=IMG_" + System.currentTimeMillis(), "image/jpeg", reqFile);
m_httpOperationWrapper.initCall(m_call, this, true);
} else {
m_eventTracker.onCallFail(AppConstants.BAD_REQUEST, new Throwable("Something went wrong, Try again later!"), null);
}
}
}
/**
* Execute HTTP call to post a new text note.
*/
public void postTextNote(#NonNull RequestBody requestBody) {
if (m_eventTracker != null) {
final ResponseToken token = NetworkUtil.getAccessToken();
if (getService() != null && m_httpOperationWrapper != null && token != null) {
m_call = getService().postFile(token.getTokenType() + " " + token.getAccessToken(), NetworkUtil.X_VERSION,
"filename=" + token.getOwnerId() + "_text_note_" + System.currentTimeMillis(), "text/plain",
requestBody);
m_httpOperationWrapper.initCall(m_call, this);
} else {
m_eventTracker.onCallFail(AppConstants.BAD_REQUEST, new Throwable("Something went wrong, Try again later!"), null);
}
}
}
public void initCall(#NonNull Call<ContentResponse> call, #NonNull IHttpOperationCallback callback, final boolean isSynchronousCall) {
m_callback = callback;
try {
if (NetworkUtil.isNetworkAvailable()) {
if (isSynchronousCall) {
m_executeRequest(call);
} else {
m_enqueueRequest(call);
}
} else {
m_callback.onFailure(call, new Throwable(AppConstants.NO_INTERNET), null);
}
} catch (Exception e) {
m_callback.onFailure(call, e.fillInStackTrace(), null);
}
}
private void m_enqueueRequest(#NonNull Call<ContentResponse> call) {
call.enqueue(new Callback<ContentResponse>() {
#SuppressWarnings("ConstantConditions")
#Override
public void onResponse(#NonNull Call<ContentResponse> call, #NonNull Response<ContentResponse> response) {
if (m_callback != null) {
if (!Util.isValidResponse(response)) {
String error = "Status: " + response.code() + " " + response.message();
m_callback.onFailure(call, new Throwable(
response.code() == HttpURLConnection.HTTP_UNAUTHORIZED ? AppConstants.UNAUTHORIZED : error), response.errorBody());
return;
}
m_callback.onSuccess(call, response.body());
}
}
#Override
public void onFailure(#NonNull Call<ContentResponse> call, #NonNull Throwable t) {
if (m_callback != null) {
m_callback.onFailure(call, t, null);
}
}
});
}
#WorkerThread
private void m_executeRequest(#NonNull Call<ContentResponse> call) {
try {
Response<ContentResponse> response = call.execute();
if (m_callback != null) {
if (!Util.isValidResponse(response)) {
String error = "Status: " + response.code() + " " + response.message();
m_callback.onFailure(call,
new Throwable(response.code() == HttpURLConnection.HTTP_UNAUTHORIZED ? AppConstants.UNAUTHORIZED : error),
response.errorBody());
return;
}
//noinspection ConstantConditions
m_callback.onSuccess(call, response.body());
}
} catch (IOException | RuntimeException e) {
e.printStackTrace();
if (m_callback != null) {
m_callback.onFailure(call, e.fillInStackTrace(), null);
}
}
}
How can I get the same behaviour for the text note? Any help is appreciated.
When you use enqueue your request sent async, and the orientation change destroys the activity and cancels your response code scope.
You should consider move the request code into a ViewModel class which is part of the MVVM architecture. The ViewModel would make the request even after orientation change and keep the data inside it, then you could access its data after the activity is re-created.
always returning the wrong value, before the request has been finish. The validation will already return the value without waiting for the response. I'am using retrofit for request then i put it on listener.
Thankyou for the help, suggestion is much accepted!.
this is my code, i have validation for the screen when it's true it will goes to another screen.
#Override
public boolean isValid() {
if (NetworkUtils.isConnected(getActivity())) {
final AtomicBoolean pass = new AtomicBoolean(false);
Thread simpleThread = new Thread() {
public void run() {
new ReprintOnlineHelper(rType, receiptNoEditText.getText().toString(), issuedDate, etTotalAmtPaid.getText().toString(), new ReprintOnlineHelper.ReceiptNoSearchListener() {
#Override
public boolean onServiceResponse(List<ReceiptNumber> receiptNumbers) {
Log.e("receiptNumbers", "" + receiptNumbers.get(0).getTPAYRECEIPTNO());
if (receiptNumbers.isEmpty()) {
returnValue = "eReceipt Number not found!";
val = true;
} else {
String pdates = null, ddates;
try {
if (!receiptNumbers.get(0).getTPAYISSUEDDATE().isEmpty()) {
Date periodFormat = df.parse(receiptNumbers.get(0).getTPAYISSUEDDATE());
pdates = sdf.format(periodFormat);
}
} catch (ParseException e) {
e.printStackTrace();
Log.e("ddd", "" + e.getMessage());
}
String tinNo = receiptNumbers.get(0).getTPTIN();
if (tinNo.contains("-")) {
tinNo = receiptNumbers.get(0).getTPTIN().replace("-", "");
}
Log.e("JAC", "" + receiptNumbers.get(0).getTPAYRECEIPTNO() + "---" + AlfonzoUtils.formatDate(DateUtils.simpledateToMillis(pdates, DateUtils.DateFormat.SIMPLE_DATE_5_FORMAT)) + "---" + MoneyEditText.toDouble(receiptNumbers.get(0).getTOTALPAID()) + "--" + AlfonzoUtils.formatDate(issuedDate) + "--" + receiptNoEditText.getText().toString() + "--" + tinNo + "--"+revenueCollection.getTpTin().replace("-", ""));
if (receiptNumbers.get(0).getTPAYRECEIPTNO().equals(receiptNoEditText.getText().toString()) &&
AlfonzoUtils.formatDate(DateUtils.simpledateToMillis(pdates, DateUtils.DateFormat.SIMPLE_DATE_5_FORMAT)).contentEquals(AlfonzoUtils.formatDate(issuedDate))
&& MoneyEditText.toDouble(receiptNumbers.get(0).getTOTALPAID()) == MoneyEditText2.toDouble(etTotalAmtPaid.getText().toString()) && tinNo.equals(revenueCollection.getTpTin().replace("-", ""))) {
pass.set(true);
returnValue = "success";
val = true;
showMessagePrompt(rType,returnValue);
return true;
} else if (!tinNo.equals(revenueCollection.getTpTin().replace("-", ""))) {
returnValue = "eReceipt Number was not issued to this TIN " + revenueCollection.getTpTin();
val = false;
} else if (!AlfonzoUtils.formatDate(DateUtils.simpledateToMillis(pdates, DateUtils.DateFormat.SIMPLE_DATE_5_FORMAT)).contentEquals(AlfonzoUtils.formatDate(issuedDate))) {
returnValue = "Issued date is not valid";
val = false;
} else if (MoneyEditText.toDouble(receiptNumbers.get(0).getTOTALPAID()) != MoneyEditText2.toDouble(etTotalAmtPaid.getText().toString())) {
returnValue = "Total amount paid is not valid";
val = false;
} else if (!receiptNumbers.get(0).getTPAYRECEIPTNO().equals(receiptNoEditText.getText().toString())) {
returnValue = "ReceiptNo is not valid";
val = false;
}
}
return false;
}
#Override
public void onErrorResponse(int err) {
}
}).reprintReceiptNo();
}
};
if (!receiptNoEditText.getText().toString().isEmpty() && issuedDate != 0 /*&& MoneyEditText2.toDouble(etTotalAmtPaid.getText().toString()) > 0*/) {
try {
simpleThread.start();
simpleThread.join();
pass.get();
Log.e("pass", "" + pass + "-" + pass.get() + val);
} catch (InterruptedException e) {
e.printStackTrace();
}
return pass.get();
}
}
return false;
}
this is my request in retrofit:
public void reprintReceiptNo() {
JSONObject jO = new JSONObject();
JSONObject result = new JSONObject();
JSONArray jsonArray = new JSONArray();
try {
jO.put("xReceipt", receiptTypeNo);
jO.put("xType", receipttype);
jsonArray.put(jO);
result.put("dataArray", jsonArray);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.e("dataArray", "----- " + result.toString());
ServiceInterface si = BaseRestClient.getClient();
Observable<List<ReceiptNumber>> call = si.getreprintReceiptNumber(result.toString());
call.subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<ReceiptNumber>>() {
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
}
#Override
public void onNext(List<ReceiptNumber> receiptNumbers) {
Log.e("receiptNumbers", "" + receiptNumbers.toString());
onReceiptNoSearchListener.onServiceResponse(receiptNumbers);
}
});
}
Its not possible for the isValid() method to wait for the service reponse if you have code outside the Thread you've created.
The method will execute the Thread, but while that Thread is executing, the rest of the code will be read, meaning the return pass.get(); or the return false; statments will be read, causing the the method to return before the server response.
The solution its to change the way this was done. You should check if you can call the server and then created your logic in the methods onServiceResponse() and onErrorResponse() based on how you want to proceed.
I want to get message in my chat activity without press back button in Quickblox instance chat
userData = new QBUser();
userData.setEmail(uNameStr);
userData.setPassword(uPwdStr);
userData.setId(user.getId());
You have to set listeners after the privateChat.sendMessage(chatMessage); so when you get success in listeners call notifydatasetchange method of the adapter.
private void sendMessage() {
// privateChatManager = chatService.getPrivateChatManager();
Log.d("PRIVATE", ">>>>> " + privateChatManager);
Log.d("INST", ">>>>> " + QBChatService.getInstance());
Log.d("CHAT ", "" + chatService);
Log.d("PRI", ">>>>> " + QBChatService.getInstance().getPrivateChatManager());
//login to chat firstly
if (messageEdt.length() > 0) {
privateChatMessageListener = new QBMessageListener<QBPrivateChat>() {
#Override
public void processMessage(QBPrivateChat privateChat, final QBChatMessage chatMessage) {
Log.e("privateChat ", " " + privateChat);
Log.e("chatMessage", "" + chatMessage);
chatListAdapter.notifyDataSetChanged();
}
#Override
public void processError(QBPrivateChat privateChat, QBChatException error, QBChatMessage originMessage) {
Log.e("privateChat ", " " + privateChat);
Log.e("QBChatMessage", "" + originMessage);
Log.e("error", "" + error);
}
};
privateChatManagerListener = new QBPrivateChatManagerListener() {
#Override
public void chatCreated(final QBPrivateChat privateChat, final boolean createdLocally) {
if (!createdLocally) {
privateChat.addMessageListener(privateChatMessageListener);
}
}
};
ChattingFragment.chatService.getPrivateChatManager().addPrivateChatManagerListener(privateChatManagerListener);
try {
QBChatMessage chatMessage = new QBChatMessage();
chatMessage.setBody(messageEdt.getText().toString());
chatMessage.setProperty("save_to_history", "1"); // Save a message to history
chatMessage.setProperty("notification_type", "1");
chatMessage.setSenderId(Integer.parseInt(Util.ReadSharePrefrence(getApplicationContext(), Constant.SHRED_PR.KEY_QB_USERID)));
chatMessage.setRecipientId(opponentId);
chatMessage.setMarkable(true);
privateChatManager = QBChatService.getInstance().getPrivateChatManager();
QBPrivateChat privateChat = privateChatManager.getChat(opponentId);
if (privateChat == null) {
privateChat = privateChatManager.createChat(opponentId, privateChatMessageListener);
}
// send message
privateChat.sendMessage(chatMessage);
privateChat.addMessageSentListener(privateChatMessageSentListener);
privateChat.addMessageListener(privateChatMessageListener);
} catch (SmackException.NotConnectedException e) {
Toast.makeText(PrivateChat.this, "Exception " + e, Toast.LENGTH_SHORT).show();
}
}
}
private QBMessageSentListener<QBPrivateChat> privateChatMessageSentListener = new QBMessageSentListener<QBPrivateChat>() {
#Override
public void processMessageSent(QBPrivateChat qbChat, QBChatMessage qbChatMessage) {
Log.d("MEHUL", "M " + qbChat);
Log.d("MSG", "MSG " + qbChatMessage);
hashmap = new HashMap<String, String>();
hashmap.put("id", "" + qbChatMessage.getId());
if (qbChatMessage.getBody() != null) {
hashmap.put("msg", "" + qbChatMessage.getBody());
} else {
hashmap.put("msg", "");
}
hashmap.put("recipient_id", "" + opponentId);
hashmap.put("sender_id", "" + user_id);
Collection<QBAttachment> collection = qbChatMessage.getAttachments();
if (collection != null && collection.size() > 0) {
for (QBAttachment attachment : collection) {
String imageid = attachment.getId();
String RecivedUrl = attachment.getUrl();
hashmap.put("url", "" + RecivedUrl);
}
//Here is the AsyncTask where I am trying to download image
//
}
String currentDateTimeString = DateFormat.getDateTimeInstance().format(new Date());
// textView is the TextView view that should display it
hashmap.put("updated_at", "" + currentDateTimeString);
chatArraylist.add(hashmap);
Toast.makeText(getApplicationContext(), "Message Sent Successfully", Toast.LENGTH_SHORT).show();
messageEdt.setText("");
chatListAdapter = new PrivateChatMsgListAdapter(getApplicationContext(), chatArraylist);
lvChatDetails.setAdapter(chatListAdapter);
lvChatDetails.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
lvChatDetails.setStackFromBottom(true);
chatListAdapter.notifyDataSetChanged();
scrollMyListViewToBottom();
}
#Override
public void processMessageFailed(QBPrivateChat qbChat, QBChatMessage qbChatMessage) {
Log.d("MEHUL", "M " + qbChat);
Log.d("MSG", "ERR " + qbChatMessage);
}
};