diff --git a/app/src/main/java/com/naman14/arcade/MainActivity.java b/app/src/main/java/com/naman14/arcade/MainActivity.java index b6bbade..62fd0ff 100644 --- a/app/src/main/java/com/naman14/arcade/MainActivity.java +++ b/app/src/main/java/com/naman14/arcade/MainActivity.java @@ -3,6 +3,7 @@ import android.Manifest; import android.animation.ArgbEvaluator; import android.animation.ObjectAnimator; +import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.database.Cursor; @@ -17,6 +18,7 @@ import android.os.Handler; import android.preference.PreferenceManager; import android.provider.MediaStore; +import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; @@ -33,6 +35,7 @@ import com.naman14.arcade.library.Arcade; import com.naman14.arcade.library.ArcadeBuilder; +import com.naman14.arcade.library.ArcadeUtils; import com.naman14.arcade.library.listeners.IterationListener; import com.naman14.arcade.library.listeners.ProgressListener; import com.nostra13.universalimageloader.core.DisplayImageOptions; @@ -70,6 +73,8 @@ public class MainActivity extends AppCompatActivity implements EasyPermissions.P private static final int STATE_BEGIN_STYLING = 3; private static final int STATE_STYLING = 4; + public boolean downloadingModel = false; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -92,6 +97,7 @@ protected void onCreate(Bundle savedInstanceState) { styleRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)); builder = new ArcadeBuilder(MainActivity.this); + checkModelExists(); style.setOnClickListener(new View.OnClickListener() { @Override @@ -118,11 +124,13 @@ public void onClick(View v) { start.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - currentState = STATE_STYLING; - animateViewVisiblity(styleImagePreview, false); - animateViewVisiblity(start, false); - animateForegroundView(Color.parseColor("#88000000"), Color.parseColor("#11000000")); - beginStyling(); + if (checkModelExists()) { + currentState = STATE_STYLING; + animateViewVisiblity(styleImagePreview, false); + animateViewVisiblity(start, false); + animateForegroundView(Color.parseColor("#88000000"), Color.parseColor("#11000000")); + beginStyling(); + } } }); @@ -219,6 +227,7 @@ public void onBackPressed() { } + @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); @@ -475,6 +484,62 @@ private boolean checkPermission() { } else return true; } + private boolean checkModelExists() { + boolean b = ArcadeUtils.modelExists() && Utils.getModelsDownloaded(this); + if (!b) { + Utils.setModelsDownloaded(this, false); + if (!downloadingModel) + showModelDownloadDialog(); + else + Toast.makeText(MainActivity.this, "Models are being downloaded", Toast.LENGTH_SHORT).show(); + } + return b; + } + + private void showModelDownloadDialog() { + AlertDialog.Builder dialog = new AlertDialog.Builder(this); + dialog.setTitle("Download required models"); + dialog.setMessage("Arcade will need to download additional file models to work.\n(Size ~ 30MB)"); + dialog.setCancelable(true); + dialog.setPositiveButton("Download", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + + if (checkPermission()) { + new AsyncTask() { + @Override + protected Void doInBackground(Void... params) { + try { + downloadingModel = true; + new ModelDownloader().run(MainActivity.this); + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(MainActivity.this, "Downloading models", Toast.LENGTH_SHORT).show(); + } + }); + + } catch (Exception e) { + downloadingModel = false; + e.printStackTrace(); + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(MainActivity.this, "Error downloading models", Toast.LENGTH_SHORT).show(); + } + }); + } + return null; + } + + }.execute(); + } + } + }); + dialog.create().show(); + + } + @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); diff --git a/app/src/main/java/com/naman14/arcade/ModelDownloader.java b/app/src/main/java/com/naman14/arcade/ModelDownloader.java index a23cfa1..cf0e5ee 100644 --- a/app/src/main/java/com/naman14/arcade/ModelDownloader.java +++ b/app/src/main/java/com/naman14/arcade/ModelDownloader.java @@ -2,11 +2,9 @@ import android.app.Notification; import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.BroadcastReceiver; import android.content.Context; -import android.content.Intent; import android.support.v4.app.NotificationCompat; +import android.util.Log; import com.naman14.arcade.library.ArcadeUtils; import com.squareup.okhttp.Call; @@ -34,23 +32,25 @@ public final class ModelDownloader { - private static final String MODEL_URL = "https://doc-0s-34-docs.googleusercontent.com/docs/securesc/ha0ro937gcuc7l7deffksulhg5h7mbp1/95032gs550lk93d936h1g9vn3m510q7u/1462996800000/03260806549380044353/*/0B0IedYUunOQIdGRWOG5kRXpldFk?e=download"; - private static final String PROTO_URL = "https://drive.google.com/uc?id=0B0IedYUunOQIcTBtTzAxaU1GZUE&export=download"; + private static final String MODEL_URL = "https://dl.dropbox.com/s/b9mmzkke7rst94y/nin_imagenet_conv.caffemodel?dl=1"; + private static final String PROTO_URL = "https://drive.google.com/uc?export=download&id=0ByTrPZ8aLNaddklKTUozZFBKTlE"; - private Call modelCall; - private Call protoCall; - public void run(Context context) throws Exception { + public void run(final Context context) throws Exception { - final Notificationhelper notificationhelper = new Notificationhelper(context, "Downloading models"); + Utils.deleteModels(); + final Notificationhelper notificationhelper = new Notificationhelper(context); final ProgressListener progressListener = new ProgressListener() { @Override public void update(long bytesRead, long contentLength, boolean done) { if (done) { notificationhelper.completed(); + Utils.setModelsDownloaded(context, true); + Log.d("lol","here"); + ((MainActivity) context).downloadingModel = false; } - notificationhelper.progressUpdate((int) bytesRead, (int) contentLength); + notificationhelper.progressUpdate((int) bytesRead / 1024, (int) contentLength / 1024); } }; @@ -69,9 +69,9 @@ public Response intercept(Chain chain) throws IOException { .url(PROTO_URL) .build(); - notificationhelper.createNotification(1232, "Downlaoding models"); + notificationhelper.createNotification(1232, "Downloading models"); - protoCall = new OkHttpClient().newCall(request1); + Call protoCall = new OkHttpClient().newCall(request1); Response response1 = protoCall.execute(); if (!response1.isSuccessful()) throw new IOException("Unexpected code " + response1); @@ -86,8 +86,8 @@ public Response intercept(Chain chain) throws IOException { .build(); notificationhelper.clearNotification(); - notificationhelper.createNotification(1232, "Downlaoding models"); - modelCall = client.newCall(request2); + notificationhelper.createNotification(1332, "Downloading models"); + Call modelCall = client.newCall(request2); Response response2 = modelCall.execute(); if (!response1.isSuccessful()) throw new IOException("Unexpected code " + response2); @@ -101,7 +101,7 @@ private void writeToFile(File file, InputStream inputStream) { FileOutputStream fileOutputStream = new FileOutputStream(file); OutputStream stream = new BufferedOutputStream(fileOutputStream); - int bufferSize = 1024; + int bufferSize = 1024 * 50; byte[] buffer = new byte[bufferSize]; int len = 0; while ((len = inputStream.read(buffer)) != -1) { @@ -156,13 +156,22 @@ public BufferedSource source() { private Source source(Source source) { return new ForwardingSource(source) { long totalBytesRead = 0L; + long lastByteRead = 0L; @Override public long read(Buffer sink, long byteCount) throws IOException { long bytesRead = super.read(sink, byteCount); // read() returns the number of bytes read, or -1 if this source is exhausted. totalBytesRead += bytesRead != -1 ? bytesRead : 0; - progressListener.update(totalBytesRead, responseBody.contentLength(), bytesRead == -1); + + if (bytesRead == -1) { + progressListener.update(totalBytesRead, responseBody.contentLength(), true); + } else { + if (totalBytesRead - lastByteRead > 1024 * 150) { + progressListener.update(totalBytesRead, responseBody.contentLength(), false); + lastByteRead = totalBytesRead; + } + } return bytesRead; } }; @@ -177,18 +186,11 @@ private class Notificationhelper { private Context mContext; private int NOTIFICATION_ID = 1; - private NotificationCompat mNotification; private NotificationManager mNotificationManager; - private PendingIntent mContentIntent; - private CharSequence mContentTitle; NotificationCompat.Builder builder; - private String title; - CharSequence tickerText; - int icon; - public Notificationhelper(Context context, String title) { + public Notificationhelper(Context context) { mContext = context; - this.title = title; } public void createNotification(int newtask, String title) { @@ -199,20 +201,10 @@ public void createNotification(int newtask, String title) { builder = new NotificationCompat.Builder(mContext); - Intent intent = new Intent(mContext, MainActivity.class); - PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 1, intent, 0); - - Intent buttonIntent = new Intent(mContext, ButtonReceiver.class); - buttonIntent.putExtra("notificationId", NOTIFICATION_ID); - - PendingIntent btPendingIntent = PendingIntent.getBroadcast(mContext, 0, buttonIntent, 0); - builder.setAutoCancel(false); builder.setContentTitle(title); builder.setSmallIcon(R.mipmap.ic_launcher); - builder.setContentIntent(pendingIntent); - builder.addAction(R.drawable.ic_close_black_24dp, "Cancel", btPendingIntent); - builder.setOngoing(true); + builder.setOngoing(false); builder.setWhen(Calendar.getInstance().getTimeInMillis()); builder.build(); @@ -229,7 +221,9 @@ public void progressUpdate(int progress, int total) { public void completed() { builder.setContentTitle("Download completed"); + builder.setContentText("Models have been downloaded"); builder.setOngoing(false); + builder.mActions.clear(); builder.setProgress(100, 100, false); mNotificationManager.notify(NOTIFICATION_ID, builder.build()); } @@ -238,22 +232,4 @@ public void clearNotification() { mNotificationManager.cancel(NOTIFICATION_ID); } } - - public class ButtonReceiver extends BroadcastReceiver { - - @Override - public void onReceive(Context context, Intent intent) { - - int notificationId = intent.getIntExtra("notificationId", 0); - - if (!protoCall.isCanceled()) { - protoCall.cancel(); - } - if (!modelCall.isCanceled()) { - modelCall.cancel(); - } - NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); - manager.cancel(notificationId); - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/naman14/arcade/Utils.java b/app/src/main/java/com/naman14/arcade/Utils.java index 1040591..afbc518 100644 --- a/app/src/main/java/com/naman14/arcade/Utils.java +++ b/app/src/main/java/com/naman14/arcade/Utils.java @@ -1,14 +1,14 @@ package com.naman14.arcade; import android.content.Context; -import android.graphics.Bitmap; -import android.os.AsyncTask; -import android.os.Environment; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; import android.util.Log; +import com.naman14.arcade.library.ArcadeUtils; + import java.io.BufferedReader; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -50,5 +50,25 @@ public static String loadAssetTextAsString(Context context, String name) { return null; } + public static void deleteModels() { + File dir = new File(ArcadeUtils.getModelsDirectory()); + if (dir.isDirectory()) { + String[] children = dir.list(); + for (int i = 0; i < children.length; i++) { + new File(dir, children[i]).delete(); + } + } + } + + public static void setModelsDownloaded(Context context, boolean downloaded) { + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); + preferences.edit().putBoolean("models_downloaded", downloaded).apply(); + } + + public static boolean getModelsDownloaded(Context context) { + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); + return preferences.getBoolean("models_downloaded", false); + } + }