diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fd45b12 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +*.iml +.gradle +/local.properties +/.idea/caches/build_file_checksums.ser +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +.DS_Store +/build +/captures +.externalNativeBuild diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..30aa626 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..7ac24c7 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..e0d5b93 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..eb9dfe0 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,42 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 28 + defaultConfig { + applicationId "com.alpha.devster.backkk" + minSdkVersion 18 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + sourceSets { + main { + res.srcDirs = + [ + 'src/main/res/layout', + 'src/main/res/menu', + 'src/main/res', + + ] + + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'com.android.support:appcompat-v7:28.0.0' + + implementation 'com.android.support.constraint:constraint-layout:1.1.3' + implementation 'com.android.support:design:28.0.0' + implementation 'org.greenrobot:eventbus:3.0.0' + + +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..23302b2 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses myWebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..a084389 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/alpha/devster/backkk/BASE.java b/app/src/main/java/com/alpha/devster/backkk/BASE.java new file mode 100644 index 0000000..4cfd96a --- /dev/null +++ b/app/src/main/java/com/alpha/devster/backkk/BASE.java @@ -0,0 +1,131 @@ +package com.alpha.devster.backkk; + + +import android.app.Notification; +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.os.Build; +import android.provider.Settings; + +import com.alpha.devster.backkk.Services.BackkService; +import com.alpha.devster.backkk.Services.GhostModeService1; +import com.alpha.devster.backkk.Services.MediaPlayerServices; + +import static android.content.Context.CONNECTIVITY_SERVICE; + +public class BASE { + + + static boolean isPermission(Context context){ + if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M) { + if (Settings.canDrawOverlays(context)) + return true; + else + return false; + }else + return true; + } + + static boolean isServiceRunning() { + return BackkService.isServiceCreated(); + } + + public static boolean isNetworkAvailable(Context context) { + ConnectivityManager cm = (ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE); + NetworkInfo netInfo = cm.getActiveNetworkInfo(); + return (netInfo!=null && netInfo.isConnected()); + } + + + public static class CONSTANTS{ + // Request for Overlay over other apps + final static int OVERLAY_PERMISSION_REQ_BACKTO_ACT = 2345; + final static Class playerServiceClass=MediaPlayerServices.class; + final static String URL="https://www.youtube.com/"; + public static final String CHANNELID="Backk"; + //Type of player + //myWebView player = 0 + static int playerType = 0; + + //Repeat + //if repeatType = 0 --> no repeatType + //if repeatType = 1 --> repeatType complete + //if repeatType = 2 --> repeatType single + public static int repeatType = 0; + public static int noOfRepeats = 0; + + //Finish service on end video + static boolean finishOnEnd = false; + + + //Actions + public interface ACTION { + String EXPAND_MODE = "com.alpha.devster.expandmode"; + String PREV_ACTION = "com.alpha.devster.action.prev"; + String PAUSE_PLAY_ACTION = "com.alpha.devster.action.play"; + String NEXT_ACTION = "com.alpha.devster.action.next"; + String STARTFOREGROUND_WEB_ACTION = "com.alpha.devster.playingweb"; + String STOPFOREGROUND_WEB_ACTION = "com.alpha.devster.stopplayingweb"; + + } + + //Notification Id + public interface NOTIFICATION_ID { + int FOREGROUND_SERVICE = 1; + } + public static Notification notification; + + public static class STRINGS{ + public static String VID_URL = ""; + public static void setVid(String vid_url) { STRINGS.VID_URL = vid_url; } + public static String getVideoHTML() { + return "\n" + + "\n" + + " \n" + + " \n" + + " " + + " \n" + + "\n" + + " \n" + + " \n" + + " \n" + + "\n" + + "\n" + + ""; + } + + + } + + } + + +} diff --git a/app/src/main/java/com/alpha/devster/backkk/Backk.java b/app/src/main/java/com/alpha/devster/backkk/Backk.java new file mode 100644 index 0000000..1638dcf --- /dev/null +++ b/app/src/main/java/com/alpha/devster/backkk/Backk.java @@ -0,0 +1,102 @@ +package com.alpha.devster.backkk; + +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.support.v4.app.NotificationCompat; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.widget.RemoteViews; + +import com.alpha.devster.backkk.Services.GhostModeService1; + +public class Backk extends AppCompatActivity { + + private static final String TAG=Backk.class.getName(); + public static final String CHANNELID="Backk"; + + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + SharedPreferences sharedPref=getApplicationContext().getSharedPreferences(getString(R.string.FileName), Context.MODE_PRIVATE); + Log.d(TAG,"***---------------------------------------------------------"); + Log.d(TAG,"***backkk-> onCreate()"); + createNotificationChannel(); + SharedPreferences.Editor editor=sharedPref.edit(); + if(!sharedPref.contains(getString(R.string.init))){ + Log.d(TAG,"***backkk-> sharedPreference Initializing...."); + + + //Setting sharedPreference as initialized + editor.putBoolean(getString(R.string.init),true); + editor.putBoolean(getString(R.string.firsttime),false); + + //Repeat + //if repeatType = 0 --> no repeatType + //if repeatType = 1 --> repeatType complete + //if repeatType = 2 --> repeatType single + editor.putInt(getString(R.string.repeat_type), 0); + editor.putInt(getString(R.string.no_of_repeats), 5); + + //Type of player + //myWebView player = 0 + editor.putInt(getString(R.string.player_type), 0); + + editor.apply(); + + } + + + + + if (BASE.isServiceRunning()) { + Log.d("***backkk : ", "Service & App Already Running! ExpandMode"); + startActivity(new Intent(Backk.this,MainActivity.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_SINGLE_TOP)); + finish(); + return; + } + + if (BASE.isPermission(this)) { + Log.d(TAG,"***Permission Already granted, starting MainActivity"); + finish(); + startActivity(new Intent(this, MainActivity.class)); + + } else { + Log.d(TAG,"***Starting GetPermission Activity"); + Intent i = new Intent(this, + GetPermission.class); + finish(); + startActivity(i); + + } + + } + + + private void createNotificationChannel() { + if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){ + NotificationChannel medialChannel=new NotificationChannel(CHANNELID + ,"Channel1" + ,NotificationManager.IMPORTANCE_DEFAULT); + medialChannel.setDescription("Backk"); + NotificationManager manager=getSystemService(NotificationManager.class); + manager.createNotificationChannel(medialChannel); + } + + } + + @Override + protected void onDestroy() { + super.onDestroy(); + Log.d(TAG,"***classbackk onDestroy()"); + + } +} diff --git a/app/src/main/java/com/alpha/devster/backkk/Callbacks/UpdateUI.java b/app/src/main/java/com/alpha/devster/backkk/Callbacks/UpdateUI.java new file mode 100644 index 0000000..794e0c2 --- /dev/null +++ b/app/src/main/java/com/alpha/devster/backkk/Callbacks/UpdateUI.java @@ -0,0 +1,72 @@ +package com.alpha.devster.backkk.Callbacks; + +public class UpdateUI { + + private static boolean exitApp = false; + private static boolean replay = false; + private static boolean pause = false; + private static boolean play = false; + private static boolean next = false; + private static boolean prev = false; + + //-------------------------------------------------------------------------- Getters + public boolean isReplay() { + return replay; + } + + public boolean isPause() { + return pause; + } + + public boolean isPlay() { + return play; + } + + public boolean isNext() { + return next; + } + + public boolean isPrev() { + return prev; + } + + public boolean isExit() { + return exitApp; + } + + //-----------------------------------------------------------------------------Setters + public void ExitApp(boolean exit) { + UpdateUI.exitApp = exit; + } + + public void replay(boolean replay) { + UpdateUI.replay = replay; + } + + public void pause(boolean pause) { + UpdateUI.pause = pause; + } + + public void play(boolean play) { + UpdateUI.play = play; + } + + public void next(boolean next) { + UpdateUI.next = next; + } + + public void prev(boolean prev) { + UpdateUI.prev = prev; + } + + + public void setDefault() { + exitApp = false; + replay = false; + pause = false; + play = false; + next = false; + prev = false; + } + +} diff --git a/app/src/main/java/com/alpha/devster/backkk/GetPermission.java b/app/src/main/java/com/alpha/devster/backkk/GetPermission.java new file mode 100644 index 0000000..ad71e3e --- /dev/null +++ b/app/src/main/java/com/alpha/devster/backkk/GetPermission.java @@ -0,0 +1,97 @@ +package com.alpha.devster.backkk; + +import android.annotation.TargetApi; +import android.content.DialogInterface; +import android.content.Intent; +import android.net.Uri; +import android.os.Build; +import android.provider.Settings; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.Button; + +public class GetPermission extends AppCompatActivity { + + private static final String TAG=GetPermission.class.getName(); + Button btn_getPermission; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_get_permission); + Log.d(TAG,"---------------------------------------------------------"); + Log.d(TAG,"***GetPermission-> onCreate()"); + + btn_getPermission=findViewById(R.id.btn_get_permission); + btn_getPermission.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Log.d(TAG,"***GetPermission-> AskingPermission for code "+BASE.CONSTANTS.OVERLAY_PERMISSION_REQ_BACKTO_ACT); + askPermission(); + } + }); + } + + private void askPermission() { + if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.M) { + Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, + Uri.parse("package:" + getPackageName())); + startActivityForResult(intent, BASE.CONSTANTS.OVERLAY_PERMISSION_REQ_BACKTO_ACT); + } + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + Log.d(TAG,"***GetPermission-> onActivityResult() + resultCode "+requestCode); + if(requestCode==BASE.CONSTANTS.OVERLAY_PERMISSION_REQ_BACKTO_ACT && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ){ + if(!Settings.canDrawOverlays(this)){ + Log.d(TAG,"***GetPermission-> Not granted, show dialog"); + needPermissionDialog(requestCode); + } + else{ + Log.d(TAG,"***GetPermission-> Permission Granted()"); + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + } + + @TargetApi(23) + private void needPermissionDialog(int resultCode) { + + if(resultCode==BASE.CONSTANTS.OVERLAY_PERMISSION_REQ_BACKTO_ACT){ + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setMessage("You need to grant the permission."); + builder.setPositiveButton("OK", + new android.content.DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + // TODO Auto-generated method stub + Intent i = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, + Uri.parse("package:" + getPackageName())); + startActivityForResult(i, BASE.CONSTANTS.OVERLAY_PERMISSION_REQ_BACKTO_ACT); + } + }); + builder.setNegativeButton("Cancel", new android.content.DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + // TODO Auto-generated method stub + + } + }); + + builder.setCancelable(false); + builder.show(); + + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + Log.d(TAG,"***GetPermission-> onDestroy()"); + } +} diff --git a/app/src/main/java/com/alpha/devster/backkk/JSController.java b/app/src/main/java/com/alpha/devster/backkk/JSController.java new file mode 100644 index 0000000..fac357f --- /dev/null +++ b/app/src/main/java/com/alpha/devster/backkk/JSController.java @@ -0,0 +1,72 @@ +package com.alpha.devster.backkk; + +/** + * Created by zain on 19/1/19. + */ +public class JSController { + + public static String loadVideoScript(String vId){ + return "javascript:player.loadVideoById(\"" + vId + "\");"; + } + + public static String playVideoScript() { + return "javascript:player.playVideo();"; + } + + public static String pauseVideoScript() { + return "javascript:player.pauseVideo();"; + } + + public static String onPlayerStateChangeListener() { + return "javascript:" + + "player.addEventListener(\"onStateChange\", \"onPlayerStateChange\");"+ + "function onPlayerStateChange(event) {\n" + + " window.Interface.showPlayerState(player.getPlayerState());\n" + + " }"; + } + + public static String loadPlaylistScript(String pId) { + return "javascript:player.loadPlaylist({list:\"" + pId + "\"});"; + } + + public static String nextVideo() { + return "javascript:player.nextVideo()"; + } + + public static String prevVideo() { + return "javascript:player.previousVideo()"; + } + + public static String getVidUpdateNotiContent() { + return "javascript:window.Interface.showVID(player.getVideoData()['video_id']);"; + } + + public static String seekToZero() { + return "javascript:player.seekTo(0)"; + } + + public static String setLoopPlaylist() { + return "javascript:player.setLoop(true)"; + } + + public static String unsetLoopPlaylist() { + return "javascript:player.setLoop(false)"; + } + + public static String replayPlaylistScript() { + return "javascript:player.playVideoAt(0)"; + } + + public static String isPlaylistEnded() { + return "javascript:window.Interface.playlistItems(player.getPlaylist());" + + "window.Interface.currVidIndex(player.getPlaylistIndex());"; + } + + public static String resetPlaybackQuality(String quality) { + return "javascript:player.setPlaybackQuality(\"" + quality + "\");"; + } + + public static String getVideosInPlaylist() { + return "javascript:window.Interface.videosInPlaylist(player.getPlaylist());"; + } +} diff --git a/app/src/main/java/com/alpha/devster/backkk/JavaScriptInterface.java b/app/src/main/java/com/alpha/devster/backkk/JavaScriptInterface.java new file mode 100644 index 0000000..356f6ca --- /dev/null +++ b/app/src/main/java/com/alpha/devster/backkk/JavaScriptInterface.java @@ -0,0 +1,50 @@ +package com.alpha.devster.backkk; + +import android.content.Context; +import android.os.Handler; +import android.util.Log; +import android.webkit.JavascriptInterface; + +import com.alpha.devster.backkk.Services.BackkService; +import com.alpha.devster.backkk.Services.GhostModeService1; + +/** + * Created by shyam on 18/2/16. + */ +class JavaScriptInterface { + private Context context; + private static Handler handlerForJavascriptInterface = new Handler(); + + public JavaScriptInterface(BackkService backkService) { + Log.d("***","Interface Set"); + this.context = backkService; + } + + @JavascriptInterface + public void showPlayerState (final int status) { + Log.d("Player Status ", String.valueOf(status)); + handlerForJavascriptInterface.post(new Runnable() { + @Override + public void run() { + BackkService.setPlayingStatus(status); + } + }); + } + @JavascriptInterface + public void showVID (final String vId) { + Log.d("New Video Id ", vId); + handlerForJavascriptInterface.post(new Runnable() { + @Override + public void run() { + BackkService.setTitleAuthuImage(vId); + } + }); + } + + @JavascriptInterface + public void currVidIndex (final int index) { + Log.d("Current Video Index ", String.valueOf(index)); + BackkService.setCurrVideoIndex(index); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/alpha/devster/backkk/MainActivity.java b/app/src/main/java/com/alpha/devster/backkk/MainActivity.java new file mode 100644 index 0000000..f6dfa8f --- /dev/null +++ b/app/src/main/java/com/alpha/devster/backkk/MainActivity.java @@ -0,0 +1,444 @@ +package com.alpha.devster.backkk; + +import android.annotation.SuppressLint; +import android.annotation.TargetApi; +import android.app.Activity; + +import android.content.Intent; +import android.content.res.Configuration; +import android.graphics.Bitmap; +import android.graphics.PixelFormat; +import android.os.AsyncTask; +import android.os.Build; +import android.os.Handler; +import android.os.RemoteException; +import android.provider.Settings; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.design.widget.NavigationView; +import android.support.v4.widget.DrawerLayout; +import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.app.ActionBarDrawerToggle; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.util.Log; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewStub; +import android.view.WindowManager; +import android.webkit.WebResourceRequest; +import android.webkit.WebResourceResponse; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.widget.ImageButton; + +import android.widget.Toast; + +import com.alpha.devster.backkk.Callbacks.UpdateUI; +import com.alpha.devster.backkk.Services.BackkService; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import java.net.ConnectException; + +public class MainActivity extends AppCompatActivity implements View.OnClickListener, NavigationView.OnNavigationItemSelectedListener { + + private static final String TAG = MainActivity.class.getName(); + private Activity mainAct; + + private String currUrl; + private boolean exit = false; + + //----------------------------------------------------------------------------------- + private WebView myoutube; + private DrawerLayout mdrawerLayout; + private ActionBarDrawerToggle mdrawerToggle; + + private SwipeRefreshLayout swipeRefreshLayout; + + //------------------------------------------------------------------------------------ + private int LAYOUT_FLAG; + private static WindowManager windowManager; + private DrawerLayout windowMain; + private static WindowManager.LayoutParams expandParams, ghostParams; + private static boolean ghostMode = false; + //--------------------------------------------------------------------------------Lvl 1 Creation + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Log.d(TAG, "***ClassMain---------------------------------------------------------"); + Log.d(TAG, "***-> onCreate"); + EventBus.getDefault().register(this); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; + } else { + LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE; + } + + mainAct = this; + currUrl = BASE.CONSTANTS.URL; + initializeViewgroup(); + windowManager.addView(windowMain, expandParams); + if (myoutube != null) { + myoutube.loadUrl(currUrl); + myoutube.addJavascriptInterface(new JavaScriptInterface(new BackkService()), "Interface"); + + } + + + } + + + @Override + protected void onResume() { + super.onResume(); + Log.d(TAG, "***-> onResume()"); + expandMode(); + this.moveTaskToBack(true); + } + + @Override + protected void onStop() { + Log.d(TAG, "***-> onStop()"); + super.onStop(); + } + + //---------------------------------------------------------------------------------Lvl2 Features + private void expandMode() { + if (ghostMode && BASE.isServiceRunning()) + windowManager.updateViewLayout(windowMain, expandParams); + ghostMode = false; + } + + private void startGhostMode() { + ghostMode = true; + windowManager.updateViewLayout(windowMain, ghostParams); + + } + + + //------------------------------------------------------------------------------Lvl3 ClickEvents + @Override + public void onClick(View v) { + + switch (v.getId()) { + case R.id.btn_ghostmode: + Toast.makeText(MainActivity.this, "Ghost Mode", Toast.LENGTH_SHORT).show(); + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + startGhostMode(); + + } else if (Settings.canDrawOverlays(this)) { + startGhostMode(); + + } else { + + Toast.makeText(this, "You need System Alert Window Permission to do this", Toast.LENGTH_SHORT).show(); + } + + break; + case R.id.btn_exit: + myoutube.loadUrl(myoutube.getUrl()); + //exitApp(); + break; + case R.id.btn: + if (mdrawerLayout.isDrawerOpen(Gravity.START)) { + mdrawerLayout.closeDrawer(Gravity.START); + }else + mdrawerLayout.openDrawer(Gravity.START); + break; + + case R.id.btn_Retry: + mainAct.recreate(); + + } + } + + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) { + int id = menuItem.getItemId(); + switch (id) { + case R.id.navigation_item_1: + startActivity(new Intent(MainActivity.this, MainActivity.class)); + break; + case R.id.navigation_item_2: + startActivity(new Intent(MainActivity.this, MainActivity.class)); + break; + } + return false; + } + + @Override + public void onPostCreate(Bundle savedInstanceState) { + super.onPostCreate(savedInstanceState); + if (mdrawerToggle != null) + mdrawerToggle.syncState(); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + if (mdrawerToggle != null) + mdrawerToggle.onConfigurationChanged(newConfig); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (mdrawerToggle != null) { + if (mdrawerToggle.onOptionsItemSelected(item)) + return true; + } + + return super.onOptionsItemSelected(item); + } + + @SuppressWarnings("unused") + @Subscribe + public void onEvent(UpdateUI state) { + if (state.isExit()) { + exitApp(); + state.setDefault(); + return; + } + if (state.isPause()) { + Log.d(TAG, "***Pause Video"); + myoutube.loadUrl(JSController.pauseVideoScript()); + } + + + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + if(intent.getAction()!=null){ + if(intent.getAction().equals(BASE.CONSTANTS.ACTION.EXPAND_MODE)) + Log.d(TAG, "***-> ExpandMode on From notification"); + } + } + + private void addStateChangeListener() { + myoutube.loadUrl(JSController.onPlayerStateChangeListener()); + } + + //------------------------------------------------------------------------------------Lvl4 Inits + + private void initParams() { + expandParams = new WindowManager.LayoutParams( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.MATCH_PARENT, + LAYOUT_FLAG, + WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON, + PixelFormat.TRANSLUCENT); + expandParams.gravity = Gravity.START | Gravity.TOP; + expandParams.x = 0; + expandParams.y = 0; + + ghostParams = new WindowManager.LayoutParams( + 0, + 0, + LAYOUT_FLAG, + WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON | + WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, + PixelFormat.TRANSPARENT); + ghostParams.gravity = Gravity.START | Gravity.TOP; + ghostParams.x = 0; + ghostParams.y = 0; + + } + private void initializeViewgroup() { + //Initializing Windows Params + initParams(); + //Window + windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); + LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); + DrawerLayout wrapper=new DrawerLayout(this){ + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + if(event.getKeyCode()==KeyEvent.KEYCODE_BACK){ + if(event.getAction()==KeyEvent.ACTION_DOWN){ + Log.d(TAG, "***expandMode-> onBackPressed "); + if(exit) + exitApp(); + else{ + if (mdrawerLayout.isDrawerOpen(Gravity.START)) + mdrawerLayout.closeDrawer(Gravity.START); + else if (!ghostMode && myoutube != null) { + if (myoutube.canGoBack()) { + Log.d(TAG, "***webview-> going back"); + myoutube.goBack(); + } + } + + } + } + return true; + } + return super.dispatchKeyEvent(event); } + }; + windowMain = (DrawerLayout) inflater.inflate(R.layout.activity_main, wrapper); + + initializeView(); + } + private void initializeView() { + + ImageButton btn_ghost,btn_exit, btn_menuu; + + //------------------------------------------------------------------------------------- + ViewStub viewStub = windowMain.findViewById(R.id.view_stub); + viewStub.setLayoutResource(R.layout.content_main_webview); + viewStub.inflate(); + //------------------------------------------------------------------Views + myoutube = windowMain.findViewById(R.id.wv_youtube); + btn_ghost = windowMain.findViewById(R.id.btn_ghostmode); + btn_exit=windowMain.findViewById(R.id.btn_exit); + btn_menuu = windowMain.findViewById(R.id.btn); + + //-------------------------------------------------------------NavigationTab + NavigationView mnavigation = windowMain.findViewById(R.id.navigation_view); + mdrawerLayout = windowMain.findViewById(R.id.drawer); + mdrawerToggle = new ActionBarDrawerToggle(MainActivity.this, mdrawerLayout, R.string.app_name, R.string.app_name); + + + btn_ghost.setOnClickListener(this); + btn_exit.setOnClickListener(this); + btn_menuu.setOnClickListener(this); + mdrawerLayout.addDrawerListener(mdrawerToggle); + mnavigation.setNavigationItemSelectedListener(this); + + //----------------------------------------------------------------Settings + + settingWebview(); + //Swipe Refresh myWebView + swipeRefreshLayout = windowMain.findViewById(R.id.swipe_refresh); + swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { +// myoutube.post(new Runnable() { +// @Override +// public void run() { +// myoutube.loadUrl(myoutube.getUrl()); +// } +// }); + new Handler().post(new Runnable() { + @Override + public void run() { + + myoutube.loadUrl(myoutube.getUrl()); + + } + }); + } + + + }); + + // after initialization + swipeRefreshLayout.setOnChildScrollUpCallback(new SwipeRefreshLayout.OnChildScrollUpCallback() { + @Override + public boolean canChildScrollUp(@NonNull SwipeRefreshLayout swipeRefreshLayout, @Nullable View view) { + return myoutube.getScrollY() > 0; + } + }); + + + if (!BASE.isServiceRunning()) { + final Intent intent = new Intent(MainActivity.this, BackkService.class); + intent.setAction(BASE.CONSTANTS.ACTION.STARTFOREGROUND_WEB_ACTION); + startService(intent); + } + + } + + @SuppressLint("SetJavaScriptEnabled") + private void settingWebview() { + + myoutube.getSettings().setLoadsImagesAutomatically(true); + myoutube.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); + myoutube.getSettings().setBuiltInZoomControls(false); + myoutube.getSettings().setLoadsImagesAutomatically(true); + myoutube.getSettings().setMediaPlaybackRequiresUserGesture(true); + myoutube.getSettings().setJavaScriptEnabled(true); + myoutube.setWebViewClient(new Myyoutube()); + } + + //--------------------------------------------------------------------------------Lvl5 Destroy + + @Override + protected void onDestroy() { + super.onDestroy(); + Log.d(TAG, "*** onDestroy()"); + ghostMode = false; + } + + private void exitApp() { + Log.d(TAG, "*** Exit from App."); + windowManager.removeView(windowMain); + if(BASE.isServiceRunning()) + stopService(new Intent(MainActivity.this,BackkService.class)); + finish(); + } + + //---------------------------------------------------------------------------Lvl6 Infernal Hell + private class Myyoutube extends WebViewClient { + + @Override + public void onPageStarted(WebView view, String url, Bitmap favicon) { + super.onPageStarted(view, url, favicon); + Log.d(TAG, "***classmain-> webview refreshing "+url); + + swipeRefreshLayout.setRefreshing(true); + exit=false; + currUrl = url; + + + } + + @Override + public void onPageFinished(WebView view, String url) { + super.onPageFinished(view, url); + Log.d(TAG, "***classmain-> webview is refreshed "+url); + swipeRefreshLayout.setRefreshing(false); + currUrl = url; + addStateChangeListener(); + + } + + + @Override + public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) + { + Log.d(TAG,"*** ErrorLoading "+description+" ErrorCode "+errorCode); + swipeRefreshLayout.setRefreshing(false); + exit=true; + } + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + return false; + } + + @TargetApi(21) + @Override + public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { + + if (String.valueOf(request.getUrl()).contains("http://m.youtube.com/watch?") || + String.valueOf(request.getUrl()).contains("https://m.youtube.com/watch?")) { + currUrl = String.valueOf(request.getUrl()); + + //Video Id + String VID_ID = currUrl.substring(currUrl.indexOf("?v=") + 3, currUrl.indexOf('&')); + Log.d(TAG, "***classmain-> URL is " + currUrl); + Log.d(TAG, "***classmain-> VID is " + VID_ID); + + } + return super.shouldInterceptRequest(view, request); + } + } + +} diff --git a/app/src/main/java/com/alpha/devster/backkk/Services/BackkService.java b/app/src/main/java/com/alpha/devster/backkk/Services/BackkService.java new file mode 100644 index 0000000..8966046 --- /dev/null +++ b/app/src/main/java/com/alpha/devster/backkk/Services/BackkService.java @@ -0,0 +1,282 @@ +package com.alpha.devster.backkk.Services; + +import android.annotation.SuppressLint; +import android.annotation.TargetApi; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.content.res.Configuration; +import android.graphics.Bitmap; +import android.graphics.PixelFormat; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.IBinder; +import android.provider.Settings; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.design.widget.NavigationView; +import android.support.v4.app.NotificationCompat; +import android.support.v4.widget.DrawerLayout; +import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.app.ActionBarDrawerToggle; +import android.util.Log; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewStub; +import android.view.WindowManager; +import android.webkit.WebResourceRequest; +import android.webkit.WebResourceResponse; +import android.webkit.WebSettings; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.widget.Button; +import android.widget.ImageButton; +import android.widget.RemoteViews; +import android.widget.Toast; + +import com.alpha.devster.backkk.BASE; +import com.alpha.devster.backkk.Callbacks.UpdateUI; +import com.alpha.devster.backkk.JSController; +import com.alpha.devster.backkk.MainActivity; +import com.alpha.devster.backkk.R; + +import org.greenrobot.eventbus.EventBus; +import org.json.JSONException; +import org.json.JSONObject; + +import java.net.MalformedURLException; +import java.util.concurrent.ExecutionException; + +public class BackkService extends Service { + private static final String TAG = BackkService.class.getName(); + private static BackkService mInstance = null; + //--------------------------------------------------------------------------------------- + private static String currUrl = ""; + private static int currVideoIndex; + private static String VID_ID = ""; + private static String VID_TITLE = ""; + private static String VID_AUTHUR = ""; + private static NotificationManager notificationManager; + private static Notification notification; + private static RemoteViews notifbar; + //----------------------------------------------------------------------------------------- + private static boolean nextVid = false; + private static boolean isVideoPlaying = true; + //Replay Video if it's ended + private static boolean replayVid = false; + + + public BackkService() { } + + public static boolean isServiceCreated() { + return mInstance != null; + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public void onCreate() { + super.onCreate(); + Log.d(TAG, "*** Service Is created"); + + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + if (mInstance == null) + mInstance = this; + else + Log.d(TAG, "*** Service Is Already Running"); + + final String action = intent.getAction(); + if (action != null) { + UpdateUI ui = new UpdateUI(); + switch (action) { + case BASE.CONSTANTS.ACTION.STARTFOREGROUND_WEB_ACTION: + Log.d(TAG, "*** Action to start the service"); + startNotification(); + break; + case BASE.CONSTANTS.ACTION.STOPFOREGROUND_WEB_ACTION: + Log.d(TAG, "*** Action to stop the service"); + mInstance = null; + stopForeground(true); + stopSelf(); + stopService(new Intent(this, BackkService.class)); + ui.ExitApp(true); + EventBus.getDefault().post(ui); + break; + + case BASE.CONSTANTS.ACTION.PAUSE_PLAY_ACTION: + Log.d(TAG, "*** Action for pause/play/replay action"); + if (isVideoPlaying) { + if (replayVid) { + Log.d(TAG, "*** Replay Video"); + replayVid = false; + ui.replay(true); + EventBus.getDefault().post(ui); + + } else { + + ui.pause(true); + EventBus.getDefault().post(ui); + + } + } else { + Log.d(TAG, "***Play Video"); + ui.play(true); + EventBus.getDefault().post(ui); + + } + break; + + + } + } + + + return START_NOT_STICKY; + } + + @TargetApi(28) + private void startNotification() { + notifbar = new RemoteViews( + this.getPackageName(), + R.layout.layout_notification); + notification = new NotificationCompat.Builder(this, BASE.CONSTANTS.CHANNELID) + .setSmallIcon(R.mipmap.logo_app1) + .setCustomContentView(notifbar) + .setCustomBigContentView(notifbar) + .setBadgeIconType(R.mipmap.logo_app1) + .setPriority(Notification.PRIORITY_MAX) + .setPriority(Notification.PRIORITY_HIGH) + .setAutoCancel(false) + .build(); + + notification.flags |= Notification.FLAG_ONGOING_EVENT; + BASE.CONSTANTS.notification = notification; + + + //Intent to do things + Intent doThings = new Intent(this, BackkService.class); + + //stop Service using doThings Intent + notifbar.setOnClickPendingIntent(R.id.stop_ghostmode, + PendingIntent.getService(getApplicationContext(), 0, + doThings.setAction(BASE.CONSTANTS.ACTION.STOPFOREGROUND_WEB_ACTION), 0)); + + //Pause, Play Video using doThings Intent + notifbar.setOnClickPendingIntent(R.id.pause_play_video, + PendingIntent.getService(getApplicationContext(), 0, + doThings.setAction(BASE.CONSTANTS.ACTION.PAUSE_PLAY_ACTION), 0)); + + //Next Video using doThings Intent + notifbar.setOnClickPendingIntent(R.id.next_video, + PendingIntent.getService(getApplicationContext(), 0, + doThings.setAction(BASE.CONSTANTS.ACTION.NEXT_ACTION), 0)); + + //Previous Video using doThings Intent + notifbar.setOnClickPendingIntent(R.id.previous_video, + PendingIntent.getService(getApplicationContext(), 0, + doThings.setAction(BASE.CONSTANTS.ACTION.PREV_ACTION), 0)); + + //Expand Mode using doThings Intent + Intent intent = new Intent(this, MainActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP + | Intent.FLAG_ACTIVITY_SINGLE_TOP); + notifbar.setOnClickPendingIntent(R.id.expand_mode, + PendingIntent.getActivity(getApplicationContext(), 0, + intent.setAction(BASE.CONSTANTS.ACTION.EXPAND_MODE), PendingIntent.FLAG_UPDATE_CURRENT)); + + notificationManager = + (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.notify(BASE.CONSTANTS.NOTIFICATION_ID.FOREGROUND_SERVICE, notification); + + startForeground(1, notification); + } + + public static void setTitleAuthuImage(String vId) { + try { + + String details = new LoadDetailsTask( + "https://youtube.com/get_video_info?video_id=" + VID_ID + "&format=json") + .execute().get(); + JSONObject detailsJson = new JSONObject(details); + VID_TITLE = detailsJson.getString("title"); + VID_AUTHUR = detailsJson.getString("authur"); + Log.d(TAG, "***Video Title " + VID_TITLE + " " + "VID Authur +" + VID_AUTHUR); + notifbar.setTextViewText(R.id.title, VID_TITLE); + notifbar.setTextViewText(R.id.authur, VID_AUTHUR); + notificationManager.notify(BASE.CONSTANTS.NOTIFICATION_ID.FOREGROUND_SERVICE, notification); + + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + + } + + public static void setCurrVideoIndex(int currVideIndex) { + BackkService.currVideoIndex = currVideIndex; + } + + public static void setPlayingStatus(int playingStatus) { + if (playingStatus == -1) { + nextVid = true; + } + if (playingStatus == 1) { + isVideoPlaying = true; + notifbar.setImageViewResource(R.id.pause_play_video, R.mipmap.icon_pause); + notificationManager.notify(BASE.CONSTANTS.NOTIFICATION_ID.FOREGROUND_SERVICE, notification); + if (nextVid) { + nextVid = false; + //loadScript(JavaScript.getVidUpdateNotiContent()); + } + + + } else if (playingStatus == 2) { + isVideoPlaying = false; + notifbar.setImageViewResource(R.id.pause_play_video, R.mipmap.icon_play); + + notificationManager.notify(BASE.CONSTANTS.NOTIFICATION_ID.FOREGROUND_SERVICE, notification); + } else if (playingStatus == 0) { + Log.d(TAG, "*** Repeat type" + BASE.CONSTANTS.repeatType + ""); + + //webPlayer.loadScript(JavaScript.prevVideo()); + + replayVid = true; + //notifbar.setImageViewResource(R.id.pause_play_video, R.drawable.ic_replay); + + notificationManager.notify(BASE.CONSTANTS.NOTIFICATION_ID.FOREGROUND_SERVICE, notification); + + } + + + } + + + @Override + public void onDestroy() { + super.onDestroy(); + Log.d(TAG, "***Service is destroyed."); + isVideoPlaying=true; + mInstance = null; + stopForeground(true); + stopSelf(); + stopService(new Intent(this, BackkService.class)); + } + + +} diff --git a/app/src/main/java/com/alpha/devster/backkk/Services/GhostModeService1.java b/app/src/main/java/com/alpha/devster/backkk/Services/GhostModeService1.java new file mode 100644 index 0000000..9a7cace --- /dev/null +++ b/app/src/main/java/com/alpha/devster/backkk/Services/GhostModeService1.java @@ -0,0 +1,328 @@ +package com.alpha.devster.backkk.Services; + +import android.annotation.TargetApi; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.graphics.PixelFormat; +import android.os.Build; +import android.os.Bundle; +import android.os.IBinder; +import android.support.v4.app.NotificationCompat; +import android.util.Log; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.WindowManager; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RemoteViews; + +import com.alpha.devster.backkk.BASE; +import com.alpha.devster.backkk.JSController; +import com.alpha.devster.backkk.MainActivity; +import com.alpha.devster.backkk.R; +import com.alpha.devster.backkk.myWebView; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.net.MalformedURLException; +import java.util.concurrent.ExecutionException; + +import static com.alpha.devster.backkk.Backk.CHANNELID; + +public class GhostModeService1 extends Service implements View.OnClickListener { + + private static final String TAG=GhostModeService1.class.getName(); + private static int noItemsInPlaylist, currVideoIndex; + private static GhostModeService1 mInstance=null; + + //---------------------------------------------------------------------------------- + private static WindowManager windowManager; + private static WindowManager.LayoutParams headParams; + private LinearLayout ghostHead,ghostViewlayout; + private FrameLayout ghostPlayerFrame; + private ImageView ghostheadImage; + //---------------------------------------------------------------------------------- + + private static String VID_URL=""; + private static String VID_ID=""; + private static String VID_TITLE=""; + private static NotificationManager notificationManager; + private static Notification notification; + private static RemoteViews notifbar; + private int LAYOUT_FLAG; + //----------------------------------------------------------------------------------- + private static myWebView myoutubewv; + private static boolean nextVid = false; + private static boolean isVideoPlaying = true; + //Replay Video if it's ended + private static boolean replayVid = false; + + + public GhostModeService1(){ } + public static boolean isServiceCreated(){ + return mInstance!=null; + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public boolean onUnbind(Intent intent) { + return super.onUnbind(intent); + } + + @Override + public void onCreate() { + super.onCreate(); + Log.d(TAG,"***ghostservice-> onCreate()"); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; + } else { + LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE; + } + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + + Log.d(TAG,"***ghostservice-> onStartCommand()"); + if(mInstance==null) + mInstance=this; + if(intent.getAction()!=null){ + if (intent.getAction().equals(BASE.CONSTANTS.ACTION.STARTFOREGROUND_WEB_ACTION)){ + ghostModeOn(intent); + } + else if(intent.getAction().equals(BASE.CONSTANTS.ACTION.STOPFOREGROUND_WEB_ACTION)){ + Log.i(TAG, "***classghost -> trying to stop service"); + stopForeground(true); + stopSelf(); + stopService(new Intent(this, GhostModeService1.class)); + } else if(intent.getAction().equals(BASE.CONSTANTS.ACTION.PAUSE_PLAY_ACTION)){ + if (isVideoPlaying) { + if (replayVid) { + Log.i(TAG, "*** Replay Video"); + myoutubewv.loadScript(JSController.playVideoScript()); + replayVid = false; + + } else { + Log.i(TAG , "***Pause Video"); + myoutubewv.loadScript(JSController.pauseVideoScript()); + } + } else { + Log.i(TAG, "***Play Video"); + myoutubewv.loadScript(JSController.playVideoScript()); + } + } + else if(intent.getAction().equals(BASE.CONSTANTS.ACTION.NEXT_ACTION)){ + Log.d(TAG, "***Tryinh to Play Next"); + myoutubewv.loadScript(JSController.nextVideo()); + nextVid = true; + + } + else if(intent.getAction().equals(BASE.CONSTANTS.ACTION.PREV_ACTION)){ + Log.d(TAG, "***Trying to Play Previous"); + myoutubewv.loadScript(JSController.prevVideo()); + nextVid = true; + + } + + } + + return START_NOT_STICKY; + } + + private void ghostModeOn(Intent intent) { + Bundle b=intent.getExtras(); + if(b!=null){ + Log.d(TAG,"***classghost "+" bundle not null"); + GhostModeService1.VID_URL=b.getString("VID_URL"); + GhostModeService1.VID_ID=b.getString("VID_ID"); + } + else + Log.d(TAG,"***classghost "+" bundle null"); + foregroundNotification(); + + //startForeground(BASE.CONSTANTS.NOTIFICATION_ID.FOREGROUND_SERVICE,BASE.CONSTANTS.notification); + + //View + windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); + //Initializing Windows Params + initParams(); + LayoutInflater inflater = (LayoutInflater) this.getSystemService + (Context.LAYOUT_INFLATER_SERVICE); + + ghostHead =(LinearLayout) inflater.inflate(R.layout.ghost_head,null); + ghostheadImage=(ImageView) ghostHead.findViewById(R.id.img_ghost_head); + headParams.gravity = Gravity.BOTTOM | Gravity.END; + headParams.x = 0; + headParams.y = 0; + windowManager.addView(ghostHead, headParams); + + //Player View + ghostViewlayout = (LinearLayout) inflater.inflate(R.layout.layout_ghostmode, null, false); + ghostPlayerFrame = (FrameLayout) ghostViewlayout.findViewById(R.id.ghost_player_frame); + + myoutubewv=new myWebView(this); + BASE.CONSTANTS.STRINGS.VID_URL=GhostModeService1.VID_ID; + + + ghostPlayerFrame.addView(myoutubewv); + myoutubewv.loadScript(VID_URL); + + //handeling GhostHeadImage Click + ghostheadImage.setOnClickListener(this); + + } + + + public static void startNoti(){ + } + + @TargetApi(28) + protected void foregroundNotification() { + notifbar = new RemoteViews( + this.getPackageName(), + R.layout.layout_notification); + notification = new NotificationCompat.Builder(this,CHANNELID) + .setSmallIcon(R.mipmap.logo_app1) + .setContentIntent(notificationIntent()) + .setCustomContentView(notifbar) + .setCustomBigContentView(notifbar) + .setBadgeIconType(R.mipmap.logo_app1) + .setPriority(Notification.PRIORITY_MAX) + .setPriority(Notification.PRIORITY_HIGH) + .setDefaults(Notification.DEFAULT_ALL) + .setAutoCancel(false) + .build(); + + notification.flags |= Notification.FLAG_ONGOING_EVENT; + + setTitle(VID_ID); + + //Intent to do things + Intent doThings = new Intent(this, GhostModeService1.class); + + //stop Service using doThings Intent + notifbar.setOnClickPendingIntent(R.id.stop_ghostmode, + PendingIntent.getService(getApplicationContext(), 0, + doThings.setAction(BASE.CONSTANTS.ACTION.STOPFOREGROUND_WEB_ACTION), 0)); + + //Pause, Play Video using doThings Intent + notifbar.setOnClickPendingIntent(R.id.pause_play_video, + PendingIntent.getService(getApplicationContext(), 0, + doThings.setAction(BASE.CONSTANTS.ACTION.PAUSE_PLAY_ACTION) , 0)); + + //Next Video using doThings Intent + notifbar.setOnClickPendingIntent(R.id.next_video, + PendingIntent.getService(getApplicationContext(), 0, + doThings.setAction(BASE.CONSTANTS.ACTION.NEXT_ACTION) , 0)); + + //Previous Video using doThings Intent + notifbar.setOnClickPendingIntent(R.id.previous_video, + PendingIntent.getService(getApplicationContext(), 0, + doThings.setAction(BASE.CONSTANTS.ACTION.PREV_ACTION), 0)); + + notificationManager = + (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.notify(BASE.CONSTANTS.NOTIFICATION_ID.FOREGROUND_SERVICE,notification); + startForeground(BASE.CONSTANTS.NOTIFICATION_ID.FOREGROUND_SERVICE,notification); + } + private PendingIntent notificationIntent() { + Intent intent = new Intent(this, MainActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP + | Intent.FLAG_ACTIVITY_SINGLE_TOP); + + return PendingIntent.getActivity(this, 0, intent, + PendingIntent.FLAG_UPDATE_CURRENT); + + } + private void initParams() { + //Service Head Params + headParams = new WindowManager.LayoutParams( + WindowManager.LayoutParams.WRAP_CONTENT, + WindowManager.LayoutParams.WRAP_CONTENT, + LAYOUT_FLAG, + WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, + PixelFormat.TRANSLUCENT + ); + } + + public static void startVID(String vurl,String vId) { + Log.d(TAG,"***classghost -> Already service running, Starting Video"); + GhostModeService1.VID_URL = vurl; + GhostModeService1.VID_ID=vId; + if(vurl != null && vId!=null) { + setTitle(vId); + myoutubewv.loadUrl(vurl); + } + } + + public static void setTitle(String vId) { + try { + + String details = new LoadDetailsTask( + "https://youtube.com/get_video_info?video_id=" + VID_ID + "&format=json") + .execute().get(); + JSONObject detailsJson = new JSONObject(details); + VID_TITLE = detailsJson.getString("title"); + Log.d(TAG,"***classghost-> Video Title "+VID_TITLE); + notifbar.setTextViewText(R.id.title, VID_TITLE); + notificationManager.notify(BASE.CONSTANTS.NOTIFICATION_ID.FOREGROUND_SERVICE, notification); + + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + + } + + public static void addStateChangeListener() { + myoutubewv.loadScript(JSController.onPlayerStateChangeListener()); + } + public static void setCurrVideoIndex(int currVideoIndex) { + GhostModeService1.currVideoIndex = currVideoIndex; + } + //Update Image of Repeat Type Button +// private void updateRepeatTypeImage() { +// if(BASE.CONSTANTS.repeatType == 0){ +// repeatTypeImg.setImageDrawable(getResources().getDrawable(R.drawable.ic_repeat_none)); +// } +// else if(BASE.CONSTANTS.repeatType == 1){ +// repeatTypeImg.setImageDrawable(getResources().getDrawable(R.drawable.ic_repeat)); +// } +// else if(BASE.CONSTANTS.repeatType == 2){ +// repeatTypeImg.setImageDrawable(getResources().getDrawable(R.drawable.ic_repeat_one)); +// } +// } + + + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.img_ghost_head: + + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + Log.d(TAG,"***ghostservice-> onDestroy()"); + mInstance=null; + stopSelf(); + } +} diff --git a/app/src/main/java/com/alpha/devster/backkk/Services/LoadDetailsTask.java b/app/src/main/java/com/alpha/devster/backkk/Services/LoadDetailsTask.java new file mode 100644 index 0000000..6da1c32 --- /dev/null +++ b/app/src/main/java/com/alpha/devster/backkk/Services/LoadDetailsTask.java @@ -0,0 +1,57 @@ +package com.alpha.devster.backkk.Services; + +import android.os.AsyncTask; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +/** + * Created by shyam on 23/2/16. + */ +public class LoadDetailsTask extends AsyncTask { + + private HttpURLConnection urlConnection; + private URL url; + + LoadDetailsTask(String url) throws MalformedURLException { + this.url = new URL(url); + } + + @Override + protected String doInBackground(String... args) { + + StringBuilder result = new StringBuilder(); + + try { + urlConnection = (HttpURLConnection) url.openConnection(); + InputStream in = new BufferedInputStream(urlConnection.getInputStream()); + + BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + + String line; + while ((line = reader.readLine()) != null) { + result.append(line); + } + + }catch( Exception e) { + e.printStackTrace(); + } + finally { + urlConnection.disconnect(); + } + + + return result.toString(); + } + + @Override + protected void onPostExecute(String result) { + super.onPostExecute(result); + + } +} diff --git a/app/src/main/java/com/alpha/devster/backkk/Services/MediaPlayerServices.java b/app/src/main/java/com/alpha/devster/backkk/Services/MediaPlayerServices.java new file mode 100644 index 0000000..fd371f3 --- /dev/null +++ b/app/src/main/java/com/alpha/devster/backkk/Services/MediaPlayerServices.java @@ -0,0 +1,53 @@ +package com.alpha.devster.backkk.Services; + +import android.app.Service; +import android.content.Intent; +import android.media.MediaPlayer; +import android.media.session.MediaController; +import android.media.session.MediaSession; +import android.media.session.MediaSessionManager; +import android.os.IBinder; + +public class MediaPlayerServices extends Service { + + private static MediaPlayerServices mInstance=null; + private MediaSession mSession; + + private static final String ACTION_PLAY="action_play"; + private static final String ACTION_PAUSE="action_pause"; + private static final String ACTION_NEXT="action_next"; + private static final String ACTION_PREV="action_prev"; + private static final String ACTION_EXIT="action_exit"; + + private MediaSessionManager mManager; + private MediaPlayer mPlayer; + private MediaController mController; + + + public static boolean isServiceCreated(){ + return mInstance!=null; + } + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public boolean onUnbind(Intent intent) { + //mSession.release(); + return super.onUnbind(intent); + } + + @Override + public void onCreate() { + super.onCreate(); + mInstance=this; + } + + @Override + public void onDestroy() { + super.onDestroy(); + mInstance=null; + stopSelf(); + } +} diff --git a/app/src/main/java/com/alpha/devster/backkk/SplashActivity.java b/app/src/main/java/com/alpha/devster/backkk/SplashActivity.java new file mode 100644 index 0000000..9a86566 --- /dev/null +++ b/app/src/main/java/com/alpha/devster/backkk/SplashActivity.java @@ -0,0 +1,13 @@ +package com.alpha.devster.backkk; + +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; + +public class SplashActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_splash); + } +} diff --git a/app/src/main/java/com/alpha/devster/backkk/myWebView.java b/app/src/main/java/com/alpha/devster/backkk/myWebView.java new file mode 100644 index 0000000..9a0df67 --- /dev/null +++ b/app/src/main/java/com/alpha/devster/backkk/myWebView.java @@ -0,0 +1,73 @@ +package com.alpha.devster.backkk; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.os.Build; +import android.util.AttributeSet; +import android.util.Log; +import android.webkit.WebChromeClient; +import android.webkit.WebView; +import android.webkit.WebViewClient; + +import com.alpha.devster.backkk.Services.BackkService; +import com.alpha.devster.backkk.Services.GhostModeService1; + +/** + * Created by shyam on 15/3/16. + */ +public class myWebView extends WebView{ + + private Context context; + + public myWebView(Context ctxt) { + super(ctxt); + context = ctxt; + initView(); + } + + public myWebView(Context ctxt, AttributeSet attrs){ + super(ctxt,attrs); + } + + @SuppressLint("SetJavaScriptEnabled") + public void initView() { + + this.getSettings().setJavaScriptEnabled(true); + this.setWebChromeClient(new WebChromeClient()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + this.getSettings().setMediaPlaybackRequiresUserGesture(false); + } + //myoutube.getSettings().setUserAgentString("Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:21.0.0) Gecko/20121011 Firefox/21.0.0"); + + //----------------------------To get Player Id------------------------------------------- + + this.addJavascriptInterface(new JavaScriptInterface((BackkService) context), "Interface"); + this.setWebViewClient(new WebViewClient() { + @Override + public boolean shouldOverrideUrlLoading(android.webkit.WebView view, String url) { + Log.d("***Ghost Webview","URl LOad"); + return false; + } + + @Override + public void onPageFinished(android.webkit.WebView view, String url) { + Log.d("***Ghost Webview","URl LOad finished"); + GhostModeService1.addStateChangeListener(); + } + } + ); + } + + public void loadScript(String s) { + this.loadUrl(s); + } + + + public void destroyWV() { + this.destroy(); + } + + public void loadDataWithUrl(String baseUrl, String videoHTML, String mimeType, String encoding, String historyUrl) { + this.loadDataWithBaseURL(baseUrl, videoHTML, mimeType, encoding, historyUrl); + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..1f6bb29 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..0d025f9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/notification_bar_gradient.xml b/app/src/main/res/drawable/notification_bar_gradient.xml new file mode 100644 index 0000000..34db6c7 --- /dev/null +++ b/app/src/main/res/drawable/notification_bar_gradient.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..4ddaf89 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_splash.xml b/app/src/main/res/layout/activity_splash.xml new file mode 100644 index 0000000..66de2f3 --- /dev/null +++ b/app/src/main/res/layout/activity_splash.xml @@ -0,0 +1,28 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/ghost_head.xml b/app/src/main/res/layout/ghost_head.xml new file mode 100644 index 0000000..db79b9a --- /dev/null +++ b/app/src/main/res/layout/ghost_head.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout/activity_get_permission.xml b/app/src/main/res/layout/layout/activity_get_permission.xml new file mode 100644 index 0000000..d681cc1 --- /dev/null +++ b/app/src/main/res/layout/layout/activity_get_permission.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + +