Best way to check internet connection in whole app - java

I want to check internet connection in whole app. I've googled for it, but the result was everyone creates an instance method in each class and tries to check the internet connection. My plan is to create a class with static method and check it without instantiating my class. Is it good idea to do that? Or should I try another way? My plan is to do something like this:
public class CheckInternetConnecting {
public static boolean isOnline(Context context) {
ConnectivityManager cm =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo() != null &&
cm.getActiveNetworkInfo().isConnectedOrConnecting();
}
}

You can also check the internet connectivity in the following way..
public boolean testConnection() {
try {
boolean connectionStatus=false;
InetAddress addr=InetAddress.getByName("8.8.8.8");//google dns 8.8.8.8
connectionStatus=addr.isReachable(1000); // 1second time for response
}
catch (Exception e) {
e.printStackTrace();
System.out.println(e.toString());
}
return connectionStatus;
}

Your approach is totally fine. I would recommend to add a package Utils to your project and put Helper-Classes in there. So instead of a class CheckInternetConnecting, create a class NetworkHelper and put your static method in there.
Adding a package:
On the left side of eclipse, in your package explorer right click your src folder and add a new package. It's important to include your package name, e.g when your package name is com.my.project than add a package called com.my.project.utils... Then you can add your NetworkHelper class to the new package by e.g right clicking and adding a new file. Copy your static code into the NetworkHelper and then you're all set...

Perhaps you can consider registering a broadcast receiver and listening out for connectivity changes as explained here.

Related

How to disable image loading in CEF/JCEF?

Is there a switch/flag that allows to do this? I spent hours finding those but couldn't find anything that works. The other thing I'm planning to do is intercept the cefRequest by adding my own CefRequestHandler, examine the resource type and if it matches RT_IMAGE, cancel the request. Everything seems easy except the part when I have to cancel a request. How do I stop/block/cancel a cefRequest? I probably should not be doing it this way but it doesn't work anyway:
public class CefClientRequestHandler extends CefRequestHandlerAdapter {
#Override
public boolean onBeforeResourceLoad(CefBrowser cefBrowser, CefFrame cefFrame, CefRequest cefRequest) {
if (cefRequest.getResourceType().equals(CefRequest.ResourceType.RT_IMAGE)) {
cefRequest.setURL("");
}
return false;
}
// more overides
}
Any ideas?
So here's a hack that works. The trick is to change the Request Method to HEAD, and because HEAD requests aren't returned the body, images won't be part of the response.
public class CefClientRequestHandler extends CefRequestHandlerAdapter {
#Override
public boolean onBeforeResourceLoad(CefBrowser cefBrowser, CefFrame cefFrame, CefRequest cefRequest) {
if (cefRequest.getResourceType().equals(RT_IMAGE)) {
cefRequest.setMethod("HEAD");
}
return false;
}
// other overridden methods here...
}
I believe that this approach should be avoided mainly because of the following two reasons:
Changing the method from GET to HEAD does not prevent CEF from making the request to the server. The overhead of opening a connection and handling a request is still there which makes it slower than simply blocking the request.
I'm not sure if images won't be displayed if they are available from browser cache. Currently, I don't know of any methods to test this. Suggestions are welcome.
Edit 1:
Changing URL didn't work in the example I posted in the question because I was passing an empty String as the new URL. If we set the URL to some address that is not an "active" domain name (e.g. https://absolutegarbage-sdjdjfbskdfb.com), the request for that resource fails immediately:
#Override
public boolean onBeforeResourceLoad(CefBrowser cefBrowser, CefFrame cefFrame, CefRequest cefRequest) {
if (cefRequest.getResourceType().equals(CefRequest.ResourceType.RT_IMAGE)) {
cefRequest.setURL("https://yghjbnbk.com");
System.out.println("LOL!");
}
return false;
}
As you can probably guess, this still is not the best solution. Please post an answer or comment if someone has found a better solution.
Edit 2: Finally I have a clean working solution, thanks to user amaitland. We just have to pass a command line switch while setting the CefAppHandler. We can do that by overriding the method onBeforeCommandLineProcessing like this:
CefApp.addAppHandler(new CefAppHandlerAdapter(null) {
#Override
public void onBeforeCommandLineProcessing(String s, CefCommandLine cefCommandLine) {
cefCommandLine.appendSwitch("disable-image-loading");
}
#Override
public void stateHasChanged(CefApp.CefAppState state) {
if (state == CefApp.CefAppState.TERMINATED) System.exit(0);
}
});

Path requests must specify a user by using UserEnvironment

I am getting "Path requests must specify a user by using UserEnvironment" error by using
Environment.getExternalStorageDirectory().getPath()
I traced my code and I found that in java.io.Environment there is a function to produce this error :
private static void throwIfUserRequired() {
if (sUserRequired) {
Log.wtf(TAG, "Path requests must specify a user by using UserEnvironment",
new Throwable());
}
}
I searched in the web and found this solution from here
Environment.setUserRequired(false);
But this solution is not working for me because I cannot access to the "setUserRequired" method of Environment. I get compilation error. I searched this function in the Environment class and I found this :
/** {#hide} */
public static void setUserRequired(boolean userRequired) {
sUserRequired = userRequired;
}
Can anyone help me how can I access to my external storage of my phone? any solution ? it is emergency. Thanks a lot
You need to use UserEnvironment and get the path for this user.
int userId = UserHandle.myUserId();
sCurrentUser = new UserEnvironment(userId);
This code stolen from Environment.java and the code they use to initialize their internal user.
I could solve my problem by removing
Environment.getExternalStorageDirectory().getPath()
inside try-catch block and writing outside of the try-catch block,and it is working now.
Through the reflection to solve this problem
fun setUserRequired() {
var state = Environment.getExternalStorageDirectory()
if ("mounted".equals(state)) {
try {
var environmentcls = Class.forName("android.os.Environment");
var setUserRequiredM = environmentcls.getMethod("setUserRequired", Boolean::class.java);
setUserRequiredM.invoke(null, false);
} catch (e: Exception) {
e.printStackTrace()
}
}
}

global variables between different classes java

i am on the creation of an app in android. its a calculator app. the main activity is where the user could input the equation, and the second activity is where the user can add/edit/delete variables. so i made a new class in another file named Global.java. then i extended it to application, imported everything i need, made s private string, made some public functions, edited the manifest, and initialized it right on my main activity. everything works fine while im only using a string to be passed by the functions but when i started adding what i need, an ArrayList, and made some functions so i could access the list then run it, the app closes. i think its because the arraylist is not allowed to be passed to different classes? am i right or am i just missing something?
please dont downvote my post if i didn't post something needed. i am using aide so there is no log output. code:
Global.java
...
import android.app.*;
import java.util.*;
public class Global extends Application
{
private String s;
public static ArrayList<String> sList;
public String getS() {
return s;
}
public void setS(String ss) {
s=ss;
}
public void add() {
sList.add(s);
}
}
MainActivity.java
...
String s;
...
global=(Global)getApplicationContext();
...
global.setS("jian"); //this one works
global.sList.add("jian"); // this one dont
...
Are you sure you initialized sList, like this:
sList = new ArrayList<String>();
If you didn't, you might want to change its declaration to include this initialization.
public static ArrayList<String> sList = new ArrayList<String>();
Just do
global.add("jian");
since you have an add function to take care of the addition of item to arraylist.
Also, try with this:
public void add(String ss) {
sList.add(ss);
}
You are not instantiating your arraylist.
public static ArrayList<String> sList = new Arraylist<String>();
Also you should read beginner tutorials on Java and android, using a public extension of application like this is a bad idea and you can get log outputs from different apps if Aide doesn't provide that, search play store

JavaExe and Java application as windows system service interactive to desktop

Request:
This is a very common problem faced by Java devs in my locale. I am really stuck for many days on this. Searched and tried a lot, read the docs. read ALL the stackoverflow questions related to JavaExe. Please only reply if you have done similar thing before and have a comprehensive answer. I would be really grateful to the community!
Senario:
I am using JavaExe to run an application as system service in desktop interactive capability.
To be exact I have an application that captures screenshots of desktops. I want it to run (as admin) on any user login so no one can stop it.
I have a myapp.jar, settings.txt and a lib dir.
I have searched alot and found JavaExe works (by watching its examples)
If anyone has a better way. Please state so.
Problem:
According to my research,
you must create a .properties file that has named like the .exe, and write "RunType = 1" in this file.
you define a static method in your main class : serviceInit()
Do I need to place any class or reference/import? How?
Edit:
My code below works as stand alone .jar and in javaExe.exe too.
It now does makes a system service and runs by as SYSTEM user. but It is NOT interactive to desktop. i.e its not showing any GUI.
package temp;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
public class Temp {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
serviceInit();
}
public static boolean serviceInit(){
new Thread(){
public void run(){
Integer i = 0;
while(i < 999999999){
JOptionPane.showMessageDialog(null,i);
i++;
}
}
}.start();
return true;
}
}
And I dont think that bundling the .jar, lib directory and settings.txt into one .exe is possible?
you should have in your case :
public class MyApp_ServiceManagement
{
static boolean isMsgToDisplay = false;
/////////////////////////////
public static boolean serviceInit()
{
(new Thread()
{
public void run()
{
for(int i=0;i < 6;i++)
{
try { sleep(5*1000); }
catch(Exception ex) {}
isMsgToDisplay = true;
}
}
}).start();
return true;
}
/// is Data ready to be send to the UI ?
public static boolean serviceIsDataForUI()
{
return isMsgToDisplay;
}
/// Data to be send to the UI
public static Serializable serviceDataForUI()
{
isMsgToDisplay = false;
return "hello, I am an interactive Service";
}
}
and for the UI part :
public class MyApp_TaskbarManagement
{
/// To show (or not) the icon in tray
public static boolean taskIsShow()
{
return false;
}
/// Receive the message from Service
public static void taskDataFromService(Serializable data)
{
JOptionPane.showMessageDialog(null, data);
}
/// descr of UI
public static String[] taskGetInfo()
{
return new String[]
{
"UI part of Service"
};
}
}
the main() method is never called in service mode (except one particular case), but if you want keep your main() method you must put a call to main() in serviceInit().
Put serviceInit() in your main class or in another class named XXX_ServiceManagement where XXX is the name of your main class.
Then, serviceInit() must return before a 30 seconds delay.
Don't put a infinite loop, ... in it.
Put your code in a thread, and start it from serviceInit() (or main)
That answer to your problem?

Returning class instance via RMI call

I'm trying to return a normal class via a RMI call. My server holds a instance of a class called GameState that i want to perform actions on via it's methods, from a client application. So the RMI works fine if a just return a int or something, but when a try to return GameState, which is a class defined inside the GameServer java file, the following error occurs (game state is declared neither public, protected or private):
Exception in thread "main" java.lang.IllegalAccessError: tried to access class GameState from class $Proxy0
at $Proxy0.getGameState(Unknown Source)
at GameClient.login(GameClient.java:204)
at GameClient.main(GameClient.java:168)
So, i guess the client application knows how GameState looks, but dont have any access to it?
I have tried to make GameState a public class in it's own file, but then the different connecting client applications get each their own GameState, so it's seems like that dont get it from the server.
Here are some code that i think is relevant:
The remote interface:
import java.rmi.*;
public interface ServerInterface extends Remote
{
public GameState getGameState() throws RemoteException;
}
Some if the server code:
public class GameServer extends UnicastRemoteObject implements ServerInterface {
/**
*
*/
private static final long serialVersionUID = -6633456258968168102L;
private final static int DEFAULT_NAMING_PORT = 9955; // TODO: IMPORTANT - change this to a group-specific number,
// e.g., 2000 + group number. The number should be the same
// as in GameClient.java.
private final GameState m_state;
public static void main(String[] args) {
//the variables: port and host etc it configurated here, but has nothing to do with the RMI problem.
try {
GameServer instance = new GameServer(players);
System.out.print("Setting up registry on "+host+":"+port+" ... ");
//Set up an unrestricted security manager.
if (System.getSecurityManager() == null) {
// Set security manager to an instance of a dynamically created
// subclass of RMISecurityManager with the checkPermission() method overloaded
System.setSecurityManager(
new RMISecurityManager() {
#Override
public void checkPermission(Permission permission) {
}
}
);
}
// Create a registry for binding names (name server)
Registry naming = LocateRegistry.createRegistry(port);
System.out.println("done.");
String rmiObjectName = "GeschenktServer";
System.out.print("Binding name "+rmiObjectName+" ... ");
naming.rebind(rmiObjectName, instance);
System.out.println("done.");
} catch(RemoteException e) {
System.err.println("Could not start server: "+e);
System.exit(-1);
}
}
//the rest of the server code....
//the GameState declared in the same file
class GameState implements java.io.Serializable {
private static final long serialVersionUID = 545671487061859760L;
//the rest of the Game state code.
Here is some of the client code:
private void login() {
try {
System.out.println("Connecting to server on host "+m_host+".");
// Set up an unrestricted security manager. In the server we trust.
// See GameServer.java for code explanation.
if (System.getSecurityManager() == null) {
System.setSecurityManager(
new RMISecurityManager() {
#Override
public void checkPermission(Permission permission) {
}
}
);
}
System.out.print("Locating registry on "+m_host+":"+m_port+" ... ");
Registry naming = LocateRegistry.getRegistry(m_host, m_port);
System.out.println("done.");
String name = "GeschenktServer";
System.out.print("Looking up name "+name+" ... ");
m_server = (ServerInterface) naming.lookup(name);
System.out.println("done.");
// TODO: Connect the player, i.e., register the player with the server.
// Make sure that the player cannot register if there are already enough players.
m_Id = m_server.getGameState().loginPlayer(m_name); //this line is causing the error...
if(m_Id < 0)
System.exit(0);
System.out.println("Server connection successful.");
m_window = new GameWindow(m_server, m_name, m_Id);
m_window.run();
} catch (Exception e) {
System.out.println("Connection failed - "+e);
System.exit(1);
}
}
}
I am using eclipse to do all this, and based on what i have red about RMI in eclipse, rmic and that stuff is not needed anymore, i'm i right?
So anyone with any idea?
Thanks in advance!
I don't think this is a permission problem. I cannot tell for sure from the code above, but I would assume it is a codebase problem. Did you configure the codebase also on client-side?
To deserialize the GameState class, the client needs to be able to load the class definition. This definition is located in the Server implementation and not the interface. Normally, the Server implementation should not be compiled to the client's classpath, only the interface should. I am not entirely sure, as in your solution the interface seems to have a dependency on the implementation due to the GameState which is not a good idea btw. Anyways, try adding a codebase configuration to your VM-args. Assuming you execute everything on localhost, it should look like this:
-Djava.rmi.server.codebase=file:${workspace_loc}/PROJECT-NAME/bin/
Where ${workspace_loc} is the absolute path to your workspace and PROJECT-NAME is the name of the server project. Eclipse will resolve ${workspace_loc} automatically, so you only need to set your PROJECT-NAME
As a side note: If you implement it that way, the GameState object is transmitted to the client-side and is executed on the client, having no effect whatsoever on the execution of the server. Is this really what you want? If you want the GameState instance to execute on the server-side, GameState also needs to implement Remote, not Serializable, and you need to export it when transmitting its stub to the client.
Finally, as you correctly stated, you do not need to use rmic since Java 1.5
try to return GameState, which is a class defined inside the
GameServer java file, the following error occurs (game state is
declared neither public, protected or private)
This is the problem. Only the GameServer class and classes in the same package can create instances of GameState. Your RMI proxy object (stub) Make it a public class in its own file.
I have tried to make GameState a public class in it's own file, but
then the different connecting client applications get each their own
GameState, so it's seems like that dont get it from the server
That's correct. It is serialized to each client. If you want to share a single GameState and have it remain at the server, it has to be an exported remote object itself, with a remote interface called GameState.
The IllegalAccessError reason is simple: GameState is NOT public
However, there is a larger issue:
you do understand that loginPlayer will not do what you like it to... The GameState is a copy of the original state. You want GameState to be Remote not serializable, so you can execute the operation on the server, not each client to get a useless copy of.

Categories