SketchfabActivity.java
Go to the documentation of this file.
1 package com.introlab.rtabmap;
2 
3 import java.io.File;
4 import java.io.IOException;
5 import java.util.List;
6 
7 import android.app.Activity;
8 import android.app.AlertDialog;
9 import android.app.Dialog;
10 import android.app.ProgressDialog;
11 import android.content.Context;
12 import android.content.DialogInterface;
13 import android.content.Intent;
14 import android.content.SharedPreferences;
15 import android.net.ConnectivityManager;
16 import android.net.NetworkInfo;
17 import android.os.AsyncTask;
18 import android.os.Bundle;
19 import android.preference.PreferenceManager;
20 import android.text.Editable;
21 import android.text.SpannableString;
22 import android.text.TextWatcher;
23 import android.text.method.LinkMovementMethod;
24 import android.text.util.Linkify;
25 import android.util.Log;
26 import android.view.View;
27 import android.view.View.OnClickListener;
28 import android.webkit.WebView;
29 import android.webkit.WebViewClient;
30 import android.widget.Button;
31 import android.widget.CheckBox;
32 import android.widget.EditText;
33 import android.widget.TextView;
34 import android.widget.Toast;
35 
36 public class SketchfabActivity extends Activity implements OnClickListener {
37 
38  private static final String AUTHORIZE_PATH = "https://sketchfab.com/oauth2/authorize";
39  private static final String CLIENT_ID = "RXrIJYAwlTELpySsyM8TrK9r3kOGQ5Qjj9VVDIfV";
40  private static final String REDIRECT_URI = "https://introlab.github.io/rtabmap/oauth2_redirect";
41 
42  ProgressDialog mProgressDialog;
43 
44  private Dialog mAuthDialog;
45 
46  private String mAuthToken;
47  private String mWorkingDirectory;
48 
49  EditText mFilename;
50  EditText mDescription;
51  EditText mTags;
52  CheckBox mDraft;
53  Button mButtonOk;
54 
55  private SketchfabActivity getActivity() {return this;}
56 
57  @Override
58  protected void onCreate(Bundle savedInstanceState) {
59  super.onCreate(savedInstanceState);
60  setContentView(R.layout.activity_sketchfab);
61 
62  mFilename = (EditText)findViewById(R.id.editText_filename);
63  mDescription = (EditText)findViewById(R.id.editText_description);
64  mTags = (EditText)findViewById(R.id.editText_tags);
65  mDraft = (CheckBox)findViewById(R.id.checkBox_draft);
66  mButtonOk = (Button)findViewById(R.id.button_ok);
67 
68  mProgressDialog = new ProgressDialog(this);
69  mProgressDialog.setCancelable(false);
70  mProgressDialog.setCanceledOnTouchOutside(false);
71 
72  mAuthToken = getIntent().getExtras().getString(RTABMapActivity.RTABMAP_AUTH_TOKEN_KEY);
73  mFilename.setText(getIntent().getExtras().getString(RTABMapActivity.RTABMAP_FILENAME_KEY));
74  mWorkingDirectory = getIntent().getExtras().getString(RTABMapActivity.RTABMAP_WORKING_DIR_KEY);
75 
76  SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
77  String tags = sharedPref.getString(getString(R.string.pref_key_tags), getString(R.string.pref_default_tags));
78  if(tags.isEmpty())
79  {
80  tags = getString(R.string.pref_default_tags);
81  }
82  mTags.setText(tags);
83 
84  mButtonOk.setEnabled(mFilename.getText().toString().length()>0);
85  mButtonOk.setOnClickListener(this);
86 
87  mFilename.addTextChangedListener(new TextWatcher() {
88 
89  @Override
90  public void afterTextChanged(Editable s) {}
91 
92  @Override
93  public void beforeTextChanged(CharSequence s, int start,
94  int count, int after) {
95  }
96 
97  @Override
98  public void onTextChanged(CharSequence s, int start,
99  int before, int count) {
100  mButtonOk.setEnabled(s.length() != 0);
101  }
102  });
103 
104  mFilename.setSelectAllOnFocus(true);
105  mFilename.requestFocus();
106  }
107 
108  @Override
109  public void onClick(View v) {
110  // Handle button clicks.
111  switch (v.getId()) {
112  case R.id.button_ok:
114  break;
115  default:
116  return;
117  }
118  }
119 
120  private void shareToSketchfab()
121  {
122  if(!mTags.getText().toString().isEmpty())
123  {
124  SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
125  SharedPreferences.Editor editor = sharedPref.edit();
126  editor.putString(getString(R.string.pref_key_tags), mTags.getText().toString());
127  // Commit the edits!
128  editor.commit();
129  }
130 
131  authorizeAndPublish(mFilename.getText().toString());
132  }
133 
134  private boolean isNetworkAvailable() {
135  ConnectivityManager connectivityManager
136  = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
137  NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
138  return activeNetworkInfo != null && activeNetworkInfo.isConnected();
139  }
140 
141  private void authorizeAndPublish(final String fileName)
142  {
143  if(!isNetworkAvailable())
144  {
145  // Visualize the result?
146  AlertDialog ad = new AlertDialog.Builder(this)
147  .setCancelable(false)
148  .setTitle("Sharing to Sketchfab...")
149  .setMessage("Network is not available. Make sure you have internet before continuing.")
150  .setPositiveButton("Try Again", new DialogInterface.OnClickListener() {
151  public void onClick(DialogInterface dialog, int which) {
152  authorizeAndPublish(fileName);
153  }
154  })
155  .setNeutralButton("Abort", new DialogInterface.OnClickListener() {
156  public void onClick(DialogInterface dialog, int which) {
157  }
158  })
159  .create();
160  ad.setCanceledOnTouchOutside(false);
161  ad.show();
162  return;
163  }
164 
165  // get token the first time
166  if(mAuthToken == null)
167  {
168  Log.i(RTABMapActivity.TAG,"We don't have the token, get it!");
169 
170  WebView web;
171  mAuthDialog = new Dialog(this);
172  mAuthDialog.setCancelable(true);
173  mAuthDialog.setCanceledOnTouchOutside(true);
174  mAuthDialog.setContentView(R.layout.auth_dialog);
175  web = (WebView)mAuthDialog.findViewById(R.id.webv);
176  web.setWebContentsDebuggingEnabled(!RTABMapActivity.DISABLE_LOG);
177  web.getSettings().setJavaScriptEnabled(true);
178  String auth_url = AUTHORIZE_PATH+"?redirect_uri="+REDIRECT_URI+"&response_type=token&client_id="+CLIENT_ID;
179  Log.i(RTABMapActivity.TAG, "Auhorize url="+auth_url);
180  web.setWebViewClient(new WebViewClient() {
181 
182  boolean authComplete = false;
183 
184  @Override
185  public void onPageFinished(WebView view, String url) {
186  super.onPageFinished(view, url);
187 
188  //Log.i(TAG,"onPageFinished url="+url);
189  if(url.contains("error=access_denied")){
190  Log.e(RTABMapActivity.TAG, "ACCESS_DENIED_HERE");
191  authComplete = true;
192  Toast.makeText(getApplicationContext(), "Error Occured", Toast.LENGTH_SHORT).show();
193  mAuthDialog.dismiss();
194  }
195  else if (url.startsWith(REDIRECT_URI) && url.contains("access_token") && authComplete != true) {
196  //Log.i(TAG,"onPageFinished received token="+url);
197  String[] sArray = url.split("access_token=");
198  mAuthToken = (sArray[1].split("&token_type=Bearer"))[0];
199  authComplete = true;
200 
201  mAuthDialog.dismiss();
202 
203  zipAndPublish(fileName);
204  }
205  }
206  });
207  mAuthDialog.show();
208  mAuthDialog.setTitle("Authorize RTAB-Map");
209  web.loadUrl(auth_url);
210  }
211  else
212  {
213  zipAndPublish(fileName);
214  }
215  }
216 
217  private void zipAndPublish(final String fileName)
218  {
219  mProgressDialog.setTitle("Upload to Sketchfab");
220  mProgressDialog.setMessage(String.format("Compressing the files..."));
221  mProgressDialog.setCancelable(false);
222  mProgressDialog.setCanceledOnTouchOutside(false);
223  mProgressDialog.show();
224 
225  Thread workingThread = new Thread(new Runnable() {
226  public void run() {
227  try{
228 
229  File tmpDir = new File(mWorkingDirectory + RTABMapActivity.RTABMAP_TMP_DIR);
230  tmpDir.mkdirs();
231  String[] fileNames = Util.loadFileList(mWorkingDirectory + RTABMapActivity.RTABMAP_TMP_DIR, false);
232  if(!RTABMapActivity.DISABLE_LOG) Log.i(RTABMapActivity.TAG, String.format("Deleting %d files in \"%s\"", fileNames.length, mWorkingDirectory + RTABMapActivity.RTABMAP_TMP_DIR));
233  for(int i=0; i<fileNames.length; ++i)
234  {
235  File f = new File(mWorkingDirectory + RTABMapActivity.RTABMAP_TMP_DIR + "/" + fileNames[i]);
236  if(f.delete())
237  {
238  if(!RTABMapActivity.DISABLE_LOG) Log.i(RTABMapActivity.TAG, String.format("Deleted \"%s\"", f.getPath()));
239  }
240  else
241  {
242  if(!RTABMapActivity.DISABLE_LOG) Log.i(RTABMapActivity.TAG, String.format("Failed deleting \"%s\"", f.getPath()));
243  }
244  }
245  File exportDir = new File(mWorkingDirectory + RTABMapActivity.RTABMAP_EXPORT_DIR);
246  exportDir.mkdirs();
247 
249  {
250  String[] files = new String[0];
251  // verify if we have all files
252 
253  fileNames = Util.loadFileList(mWorkingDirectory + RTABMapActivity.RTABMAP_TMP_DIR, false);
254  if(fileNames.length > 0)
255  {
256  files = new String[fileNames.length];
257  for(int i=0; i<fileNames.length; ++i)
258  {
259  files[i] = mWorkingDirectory + RTABMapActivity.RTABMAP_TMP_DIR + "/" + fileNames[i];
260  }
261  }
262  else
263  {
264  if(!RTABMapActivity.DISABLE_LOG) Log.i(RTABMapActivity.TAG, "Missing files!");
265  }
266 
267  if(files.length > 0)
268  {
269  final String[] filesToZip = files;
270  final String zipOutput = mWorkingDirectory+fileName+".zip";
271  Util.zip(filesToZip, zipOutput);
272  runOnUiThread(new Runnable() {
273  public void run() {
274  mProgressDialog.dismiss();
275 
276  File f = new File(zipOutput);
277 
278  // Continue?
279  AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
280  builder.setTitle("File(s) compressed and ready to upload!");
281 
282  final int fileSizeMB = (int)f.length()/(1024 * 1024);
283  final int fileSizeKB = (int)f.length()/(1024);
284  if(fileSizeMB == 0)
285  {
286  Log.i(RTABMapActivity.TAG, String.format("Zipped files = %d KB", fileSizeKB));
287  builder.setMessage(String.format("Total size to upload = %d KB. Do you want to continue?\n\n", fileSizeKB));
288  }
289  else
290  {
291  Log.i(RTABMapActivity.TAG, String.format("Zipped files = %d MB", fileSizeMB));
292  builder.setMessage(String.format("Total size to upload = %d MB. %sDo you want to continue?\n\n"
293  + "Tip: To reduce the model size, you can also look at the Settings->Exporting options.", fileSizeMB,
294  fileSizeMB>=50?"Note that for size over 50 MB, a Sketchfab PRO account is required, otherwise the upload may fail. ":""));
295  }
296 
297 
298  builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
299  public void onClick(DialogInterface dialog, int which) {
300  mProgressDialog.setTitle("Upload to Sketchfab");
301  if(fileSizeMB == 0)
302  {
303  mProgressDialog.setMessage(String.format("Uploading model \"%s\" (%d KB) to Sketchfab...", fileName, fileSizeKB));
304  }
305  else
306  {
307  mProgressDialog.setMessage(String.format("Uploading model \"%s\" (%d MB) to Sketchfab...", fileName, fileSizeMB));
308  }
309  mProgressDialog.show();
310  new uploadToSketchfabTask().execute(zipOutput, fileName);
311  }
312  });
313  builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
314  public void onClick(DialogInterface dialog, int which) {
315  // do nothing...
316  }
317  });
318  AlertDialog ad = builder.create();
319  ad.setCancelable(false);
320  ad.setCanceledOnTouchOutside(false);
321  ad.show();
322  }
323  });
324  }
325  }
326  else
327  {
328  runOnUiThread(new Runnable() {
329  public void run() {
330  mProgressDialog.dismiss();
331  Toast.makeText(getActivity(), String.format("Failed writing files!"), Toast.LENGTH_LONG).show();
332  }
333  });
334  }
335  }
336  catch(IOException ex) {
337  Log.e(RTABMapActivity.TAG, "Failed to zip", ex);
338  }
339  }
340  });
341 
342  workingThread.start();
343  }
344 
345  private class uploadToSketchfabTask extends AsyncTask<String, Void, Void>
346  {
347  String mModelUri;
348  String mModelFilePath;
349  String error = "";
350  String mFileName;
351 
352  protected void onPreExecute() {
353  //display progress dialog.
354  }
355 
356  @Override
357  protected void onPostExecute(Void result) {
358 
359  mProgressDialog.dismiss();
360  //Task you want to do on UIThread after completing Network operation
361  //onPostExecute is called after doInBackground finishes its task.
362  if(mModelFilePath!= null)
363  {
364  File f = new File(mModelFilePath);
365  f.delete(); // cleanup
366 
367  // See on sketchfab?
368  final SpannableString s = new SpannableString(
369  "Model \"" + mFileName + "\" is now processing on Sketchfab! You can click "
370  + "on the link below to see it on Sketchfab.\n\nhttps://sketchfab.com/models/"+mModelUri);
371  Linkify.addLinks(s, Linkify.WEB_URLS);
372  final AlertDialog d = new AlertDialog.Builder(getActivity())
373  .setTitle("Upload finished!")
374  .setCancelable(false)
375  .setMessage(s)
376  .setPositiveButton("Close", new DialogInterface.OnClickListener() {
377  public void onClick(DialogInterface dialog, int which) {
378  Intent resultIntent = new Intent();
379  resultIntent.putExtra(RTABMapActivity.RTABMAP_AUTH_TOKEN_KEY, mAuthToken);
380  setResult(Activity.RESULT_OK, resultIntent);
381  finish();
382  }
383  }).create();
384  d.setCanceledOnTouchOutside(false);
385  d.show();
386  ((TextView)d.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
387  }
388  else
389  {
390  Toast.makeText(getApplicationContext(), String.format("Upload failed! Error=\"%s\"", error), Toast.LENGTH_SHORT).show();
391  }
392  }
393 
394  @Override
395  protected Void doInBackground(String... files) {
396  String charset = "UTF-8";
397  File uploadFile = new File(files[0]);
398  mFileName = files[1];
399  String requestURL = "https://api.sketchfab.com/v3/models";
400 
401  Log.i(RTABMapActivity.TAG, "Uploading " + files[0]);
402 
403  try {
404  MultipartUtility multipart = new MultipartUtility(requestURL, mAuthToken, charset);
405 
406  multipart.addFormField("name", mFileName);
407  multipart.addFormField("description", mDescription.getText().toString());
408  multipart.addFormField("tags", mTags.getText().toString());
409  multipart.addFormField("source", "RTAB-Map");
410  multipart.addFormField("isPublished", mDraft.isChecked()?"false":"true");
411  multipart.addFilePart("modelFile", uploadFile);
412 
413  Log.i(RTABMapActivity.TAG, "Starting multipart request");
414  List<String> response = multipart.finish();
415 
416  Log.i(RTABMapActivity.TAG, "SERVER REPLIED:");
417 
418  for (String line : response) {
419  Log.i(RTABMapActivity.TAG, line);
420  //{"uri":"https:\/\/api.sketchfab.com\/v3\/models\/XXXXXXXXX","uid":"XXXXXXXXXX"}
421  if(line.contains("\"uid\":\""))
422  {
423  String[] sArray = line.split("\"uid\":\"");
424  mModelUri = (sArray[1].split("\""))[0];
425  mModelFilePath = files[0];
426 
427  //patch model for orientation
428  /*HttpClient httpClient = new DefaultHttpClient();
429  try {
430  String patchURL = "https://api.sketchfab.com/v3/models/"+ mModelUri +"/options";
431  HttpPatch request = new HttpPatch(patchURL);
432  String json =
433  "{\n"+
434  "uid: "+ mModelUri + "\n" +
435  "shading: shadeless\n"+
436  //"orientation:\n"+
437  //"{\n"+
438  // "axis : [1, 0, 0]\n"+
439  // "angle : 0\n"+
440  //"}\n"+
441  "}";
442 
443  request.setHeader("Authorization", "Bearer " + mAuthToken);
444  StringEntity params =new StringEntity(json, "UTF-8");
445  params.setContentType("application/json");
446  request.setEntity(params);
447  HttpResponse responsePatch = httpClient.execute(request);
448  int responseStatus = responsePatch.getStatusLine().getStatusCode();
449  Log.i(RTABMapActivity.TAG, "get data responseStatus: " + responseStatus);
450 
451  }catch (Exception e) {
452  Log.e(RTABMapActivity.TAG, "Error while patching model", e);
453  error = e.getMessage();
454  }*/
455  }
456  }
457  } catch (IOException ex) {
458  Log.e(RTABMapActivity.TAG, "Error while uploading", ex);
459  error = ex.getMessage();
460  }
461  return null;
462  }
463  }
464 }
d
f
static native boolean writeExportedMesh(long nativeApplication, String directory, String name)
static void zip(String file, String zipFile)
Definition: Util.java:23
void authorizeAndPublish(final String fileName)
void addFilePart(String fieldName, File uploadFile)
static String[] loadFileList(String directory, final boolean databasesOnly)
Definition: Util.java:58
void onCreate(Bundle savedInstanceState)
void run(ClassLoader *loader)
void zipAndPublish(final String fileName)
void addFormField(String name, String value)


rtabmap
Author(s): Mathieu Labbe
autogenerated on Mon Dec 14 2020 03:35:00