I want to detect screenshots inside a specific activity inside my app. I decided to use this ScreenShot Detector library but unfortunately this does not detect any screenshots for some reason.
I added some code to my activity to check if all the required permissions are grandent and it still doesn't work.
My Activity:
public class UserProfileActivity extends AppCompatActivity implements ScreenshotDetectionDelegate.ScreenshotDetectionListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_profile);
ActivityResultLauncher<String> requestPermissionLauncher =
registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
if (isGranted) {
Toast.makeText(this, "Permission ok", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Permission req", Toast.LENGTH_SHORT).show();
// Explain to the user that the feature is unavailable because the
// features requires a permission that the user has denied. At the
// same time, respect the user's decision. Don't link to system
// settings in an effort to convince the user to change their
// decision.
}
});
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
// You can use the API that requires the permission.
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE);
}
#Override
public void onBackPressed() {
super.onBackPressed();
finish();
CustomIntent.customType(UserProfileActivity.this, "right-to-left");
}
#Override
protected void onStart() {
super.onStart();
screenshotDetectionDelegate.startScreenshotDetection();
}
#Override
protected void onStop() {
super.onStop();
screenshotDetectionDelegate.stopScreenshotDetection();
}
#Override
protected void onResume() {
super.onResume();
screenshotDetectionDelegate.startScreenshotDetection();
}
#Override
public void onScreenCaptured(#NonNull String s) {
sendNotificationToUser("screenshot");
Toast.makeText(UserProfileActivity.this, "Profile Screenshotted", Toast.LENGTH_SHORT).show();
}
#Override
public void onScreenCapturedWithDeniedPermission() {
Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
}
}
Related
I want create a class called Permissions from below code and then call that in a click of a button. Because there is an #Override method in this activity and I don't know how to override methods inside a class. If I make a class for it the code would be much cleaner and easier to understand.
public class MainActivity extends AppCompatActivity {
TextView textView;
Button button;
final int REQUEST_CODE_FINE_LOCATION = 1234;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView);
button = findViewById(R.id.button);
// we are going to test weather the Location Permission is granted or not
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
textView.setText("Permission Granted...");
} else {
textView.setText("Permission is NOT granted");
}
}
public void requestPermission(View view) {
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// Permission is NOT granted
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)) {
new AlertDialog.Builder(MainActivity.this)
.setMessage("We need permission for fine location")
.setCancelable(false)
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
ActivityCompat.requestPermissions(MainActivity.this, new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_FINE_LOCATION);
}
})
.show();
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_FINE_LOCATION);
}
} else {
// Permission is Granted
textView.setText("Permission Granted");
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == REQUEST_CODE_FINE_LOCATION) {
if (grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Permission Granted
textView.setText("Permission is Granted");
} else {
//Permission NOT granted
if (!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)) {
//This block here means PERMANENTLY DENIED PERMISSION
new AlertDialog.Builder(MainActivity.this)
.setMessage("You have permanently denied this permission, go to settings to enable this permission")
.setPositiveButton("Go to settings", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
gotoApplicationSettings();
}
})
.setNegativeButton("Cancel", null)
.setCancelable(false)
.show();
} else {
//
textView.setText("Permission NOt granted");
}
}
}
}
private void gotoApplicationSettings() {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", this.getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}
}
Source: https://github.com/trulymittal/RuntimePermission
Use TedPermission Library which is very easy to use and easy to handle .
Make a Function in separate class and use it anywhere you want
implementation 'gun0912.ted:tedpermission:2.2.3'
public void checkPermissions(Context context) {
PermissionListener permissionlistener = new PermissionListener() {
#Override
public void onPermissionGranted() {
Toast.makeText(context, "Permission Granted", Toast.LENGTH_SHORT).show();
}
#Override
public void onPermissionDenied(List<String> deniedPermissions) {
Toast.makeText(context, "Permission Denied\n" + deniedPermissions.toString(), Toast.LENGTH_SHORT).show();
}
};
TedPermission.with(context)
.setPermissionListener(permissionlistener)
.setDeniedMessage("If you reject permission,you can not use this service\n\nPlease turn on permissions at [Setting] > [Permission]")
.setPermissions(Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
.check();
}
https://github.com/ParkSangGwon/TedPermission
You can make interface hold all the methods and create abstract class implement the interface then make any classes that inherit from the abstract class read about liskov and segregation principles
I started to get interested in Google mobile ads. Right now I am testing RewardedVideoAd functionality with Google given testing ad. Everything works fine, but I can't find the way how to disable ad closing while the ad is not finished.
Below is my abstract code which shows how I am using the RewardedVideoAd method:
public class TestPage extends AppCompatActivity implements RewardedVideoAdListener {
private Button button;
private final static String APP_ADMOB_ID = "[my_app_admob_id]";
private RewardedVideoAd mRewardedVideoAd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_page);
MobileAds.initialize(this, APP_ADMOB_ID);
mRewardedVideoAd = MobileAds.getRewardedVideoAdInstance(this);
mRewardedVideoAd.setRewardedVideoAdListener(this);
loadRewardedVideoAd();
button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mRewardedVideoAd.isLoaded()) {
mRewardedVideoAd.show();
}
}
});
}
private void loadRewardedVideoAd() {
mRewardedVideoAd.loadAd("ca-app-pub-3940256099942544/5224354917",
new AdRequest.Builder().build());
}
#Override
public void onRewardedVideoAdLoaded() {
Toast.makeText(this, "Video ad loaded",
Toast.LENGTH_SHORT).show();
}
#Override
public void onRewardedVideoAdOpened() {
Toast.makeText(this, "Video ad opened",
Toast.LENGTH_SHORT).show();
}
#Override
public void onRewardedVideoStarted() {
Toast.makeText(this, "Video ad started",
Toast.LENGTH_SHORT).show();
}
#Override
public void onRewardedVideoAdClosed() {
loadRewardedVideoAd();
}
#Override
public void onRewarded(RewardItem rewardItem) {
Toast.makeText(this, "onRewarded! currency: " + rewardItem.getType() + " amount: " +
rewardItem.getAmount(), Toast.LENGTH_LONG).show();
}
#Override
public void onRewardedVideoAdLeftApplication() {
Toast.makeText(this, "Left app during video ad",
Toast.LENGTH_LONG).show();
}
#Override
public void onRewardedVideoAdFailedToLoad(int i) {
Toast.makeText(this, "Failed to load video ad", Toast.LENGTH_LONG).show();
}
}
Now, when ad video is displayed user can press back button and then appears dialog box with message: Close video?. I want to disable this ability.
But I don't know how it could be done. I tried to #Override onBackPressed() method and inserted if statement with checks boolean value if it is able to do something or not. But it does not work.
So my main question is:
Is there any way to disable ad closing while video is running?
Thank you for any type of help.
P.S.: I have read all "AdMob for Android" instructions and I don't need link of it.
I want to get current location of user by using play service api. But always its calling onConnectionFailed() method. I have added google-services.json file with SHA-1 key. But its showing the Toast message written in onConnectionFailed() method. How can i fix it?
Here is my code -
public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private GoogleApiClient mGoogleApiClient;
private Location mLastLocation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
//setup GoogleApiClient
setupGoogleApiClient();
}
}
}
//setup GoogleApiClient object
private void setupGoogleApiClient() {
// Create an instance of GoogleAPIClient.
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
mGoogleApiClient.connect();
}
protected void onStart() {
super.onStart();
}
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Toast.makeText(this, "Connected with google play service", Toast.LENGTH_LONG).show();
}
#Override
public void onConnectionSuspended(int i) {
Toast.makeText(this, "Connection suspended with google play service", Toast.LENGTH_LONG).show();
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Toast.makeText(this, "Failed to connect with google play service", Toast.LENGTH_LONG).show();
}
}
Try changing play service version in your gradle file,
if you are using
compile 'com.google.android.gms:play-services:10.0.1'
try with
compile 'com.google.android.gms:play-services:8.x.x'
and other combination.
Note:- replace "x" with suitable values
When my Android app is running idle (i.e. doing nothing). The allocated memory slowly increases until there is no more 'Free' memory and when it hits the ceiling, the memory gets garbage collected I think.
Please look at the Image below.
MainActivity.class
public class MainActivity extends AppCompatActivity {
private final String TAG = "MainActivity";
// FIREBASE
private FirebaseAuth firebaseAuth;
private FirebaseAuth.AuthStateListener firebaseAuthListener;
// FACEBOOK
private CallbackManager FBcallbackManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize Firebase
firebaseAuth = FirebaseAuth.getInstance();
// Initialize Facebook Login button
FBcallbackManager = CallbackManager.Factory.create();
LoginButton loginButton = (LoginButton) findViewById(R.id.facebookButton);
loginButton.setReadPermissions("email", "public_profile");
loginButton.registerCallback(FBcallbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
handleFacebookAccessToken(loginResult.getAccessToken());
}
#Override
public void onCancel() {
}
#Override
public void onError(FacebookException error) {
}
});
final Intent intent = new Intent(MainActivity.this, NavigationActivity.class);
firebaseAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
Log.d(TAG, user.getDisplayName());
// User is signed in
// if so start next activty and close this one
Log.d(TAG, "User is logged in");
startActivity(intent);
finish();
} else {
// User is signed out
Log.d(TAG, "User is logged out");
}
}
};
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
FBcallbackManager.onActivityResult(requestCode, resultCode, data);
}
#Override
protected void onStart() {
super.onStart();
firebaseAuth.addAuthStateListener(firebaseAuthListener);
}
#Override
protected void onStop() {
super.onStop();
if (firebaseAuthListener != null) {
firebaseAuth.removeAuthStateListener(firebaseAuthListener);
}
}
private void handleFacebookAccessToken(AccessToken accessToken) {
final AuthCredential authCredential = FacebookAuthProvider.getCredential(accessToken.getToken());
firebaseAuth.signInWithCredential(authCredential).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Log.d(TAG, "Authentication successful");
} else {
Log.d(TAG, "Authentication not successful");
Log.d(TAG, task.getException().getMessage());
}
}
});
}
}
hprof
MAT give me these problems:
Problem Suspect 1
74.846 instances of "java.lang.String", loaded by "" occupy 6.777.960 (29,27%) bytes.
Problem Suspect 2
33 instances of "java.lang.DexCache", loaded by "" occupy 5.293.808 (22,86%) bytes.
Problem Suspect 3
19 instances of "long[]", loaded by "" occupy 3.970.432 (17,15%) bytes.
Problem Suspect 4
5.082 instances of "java.lang.Class", loaded by "" occupy 2.811.328 (12,14%) bytes.
No, that is not normal. Sounds like you're creating new objects all the time.
I'm starting with android studio and I was trying that the application check the connectivity before to start, for this I'm creating an splash screen, but I really don't find the way to calculate the time for checking the connectivity, my requirement is that the splash screen only stay visible while I'm checking the connectivity.
This is what I have in my onCreate method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int myTimer = 4000;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent i = new Intent(Splash.this, DashBoard.class);
boolean result = AppManager.CheckConnectionStatus(getApplicationContext());
if(result == true) {
startActivity(i);
}
else{
//Show a Message informing there is not internet connection
}
finish();
}
}, myTimer);
setContentView(R.layout.activity_splash);
}
As you can see I'm waiting 4000 ms but this is not the idea...
If any have any idea of how can I face this I will be grateful.
As i understand, you want to check network availability and then if available go start MainActivity. You can check network availability with this function:
public boolean isInternetAvailable(Context context)
{
NetworkInfo info = (NetworkInfo) ((ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
if (info == null){
return false;
}
else{
return true;
}
}
Then add this codes on your SplashScreen activity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
Intent i = new Intent(Splash.this, DashBoard.class);
if(isInternetAvailable(Splash.this)){
startActivity(i);
finish();
}
else{
Toast toast = Toast.makeText(Splash.this,
"Please check your internet options...", Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
finish();
}
}
Do not forget to add this permissions to your manifest file:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
I wish i could understand you right. Good luck.
You can use an AsyncTask in this case. Here's some simple code to get you started:
public class CheckConnectionAsyncTask extends AsyncTask<Void, Void, Boolean> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Display some waiting progress bar or a splash image here
}
#Override
protected Boolean doInBackground(Void... params) {
return AppManager.CheckConnectionStatus(getApplicationContext());
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(aBoolean);
if (result) {
// start next activity
} else {
// error message that you're not connected.
}
}
}
Hope it helps!