Below is my code, i tried to implement interface to intercept respond from Connectivity Manager Network Callback, but Android Studio is throwing error at this interface internetListener.onInternetStatusUpdate(true) in onAvailable method.
I also implemented this interface at my main activity. I follow a few example too but failed. Is it that onAvailable method, my interface is not reachable?
public class CheckInternetAsyncTask extends ConnectivityManager.NetworkCallback
{
private static final String TAG = "CheckInternetAsyncTask";
private Context context;
public InternetListener internetListener;
private ConnectivityManager connectivityManager;
private Network network;
private NetworkCapabilities networkCapabilities;
public interface InternetListener{
void onInternetStatusUpdate(boolean hasInternet);
}
public CheckInternetAsyncTask(Context _context) {
this.context = _context;
this.connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
connectivityManager.registerDefaultNetworkCallback(this);
}
try {
new SendInternetRequest().execute().get(5, TimeUnit.SECONDS);
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
public void TestInternetRequest(){
try {
new SendInternetRequest().execute().get(5, TimeUnit.SECONDS);
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
#Override
public void onAvailable(Network network) {
super.onAvailable(network);
this.network = network;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
connectivityManager.bindProcessToNetwork(network);
this.network = connectivityManager.getActiveNetwork();
}else{
ConnectivityManager.setProcessDefaultNetwork(network);
}
this.networkCapabilities = connectivityManager.getNetworkCapabilities(network);
if(networkCapabilities != null && networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) && networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)){
internetListener.onInternetStatusUpdate(true);
}else{
try {
new SendInternetRequest().execute().get(5, TimeUnit.SECONDS);
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
}
class SendInternetRequest extends AsyncTask<Void,Void, Void>{
private static final String TAG = "SendInternetRequest";
CheckInternetAsyncTask.InternetListener internetListener;
#Override
protected Void doInBackground(Void... voids) {
try {
Socket sock = new Socket();
sock.connect(new InetSocketAddress("8.8.8.8", 53), 1500);
sock.close();
internetListener.onInternetStatusUpdate(true);
} catch (IOException e) {
internetListener.onInternetStatusUpdate(false);
}
return null;
}
}
Stacktrace
2019-09-25 10:08:02.566 29555-29578/com.kioskactionandnotification E/AndroidRuntime: FATAL EXCEPTION: ConnectivityThread
Process: com.kioskactionandnotification, PID: 29555
java.lang.NullPointerException: Attempt to invoke interface method 'void com.kioskactionandnotification.Model.Helper.CheckInternetAsyncTask$InternetListener.onInternetStatusUpdate(boolean)' on a null object reference
at com.kioskactionandnotification.Model.Helper.CheckInternetAsyncTask.onAvailable(CheckInternetAsyncTask.java:85)
at android.net.ConnectivityManager$NetworkCallback.onAvailable(ConnectivityManager.java:2770)
at android.net.ConnectivityManager$CallbackHandler.handleMessage(ConnectivityManager.java:2969)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.os.HandlerThread.run(HandlerThread.java:65)
MainActivity.java
I implemented the interface
#Override
public void onInternetStatusUpdate(boolean hasInternet) {
this.hasInternet = hasInternet;
Log.d(TAG, "onInternetStatusUpdate: hasInternet : "+hasInternet);
}
That's all i have.
It seems like you're trying to access an uninitialized object of type internetListener.
You need to initialize it:
internetListener = new InternetListener();
Or check if it was already initialized:
if (internetListener != null) {
internetListener.onInternetStatusUpdate(true);
}
NOTE
Any abstract class you are using should be extended by a subclass that provides implementations for any of the abstract data/methods used from the abstract class.
Abstract class in Java
In my constructor below, i added a listener. Its basically my interface.
public CheckInternetAsyncTask(Context _context, InternetListener internetListener) {
this.context = _context;
this.internetListener = internetListener;
}
Then in my main activity where i am implementing this interfaces, I had to push "this" keyword, to my listener.
I am still studying the difference between context and "this" keyword and how they work on interfaces
new CheckInternetAsyncTask(context, this);
Reference: How to create our own Listener interface in android?
Related
I want to reflect an interface in one of my SDK and call it, but I received an exception. The following is my code. Please help me solve this problem
public class ReflectMain {
Class<?> obs = null;
InterProxy.ProxyCallback callback = new InterProxy.ProxyCallback() {
#Override
public void onInvoke() {
Log.d("totolog", "invokeSuccess");
}
};
public void reflectinterMain() {
try {
Class<?> reflectClass = Class.forName(ReflectClass.class.getName());
obs = Class.forName(ReflectClass.ReflectInter.class.getName());
Method method = reflectClass.getDeclaredMethod("addInter", obs);
Object listener = Proxy.newProxyInstance(obs.getClassLoader(), new Class[]{obs}, new InterProxy(callback));
method.setAccessible(true);
method.invoke("addInter", new Object[]{listener});
obs.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (Exception e){
e.printStackTrace();
}
}
class InterProxy implements InvocationHandler {
public ProxyCallback callback = null;
interface ProxyCallback {
void onInvoke();
}
InterProxy(ProxyCallback callback) {
if (this.callback != null) {
this.callback = callback;
}
}
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Log.d("totolog", method.getName());
if ("onRefletc".equals(method.getName())) {
callback.onInvoke();
}
return proxy;
}
And Reflect Class
class ReflectClass {
public ReflectInter inter = null;
void addInter(ReflectInter reflectInter) {
inter = reflectInter;
invoInter();
}
interface ReflectInter {
public void onRefletc();
}
private void invoInter() {
inter.onRefletc();
}
Then I received such an exception. Please help me analyze the cause of this exception and how to solve it.
Caused by: java.lang.IllegalArgumentException: Expected receiver of type lab.mon.actlab.java.reflectInter.ReflectClass, but got java.lang.String
at java.lang.reflect.Method.invoke(Native Method)
at lab.mon.actlab.java.reflectInter.ReflectMain.reflectinterMain(ReflectMain.java:29)
at lab.mon.actlab.java.reflect.ReflectActivity.onResume(ReflectActivity.java:87)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1354)
at android.app.Activity.performResume(Activity.java:7079)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3620)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3685)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2898)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
How can I fix it, I want to know why?
The call to method.invoke is not correct since it expects as the first parameter an instance of the object on which you want to invoke the method. You're passing the name of the method.
So I am in the process of developing an app that would silence texting notifications (sending the message straight to the inbox maybe)
I am using Lollipop.
Is there code out there that would make this possible?
Here is what i have got thus far.
FIRST JAVA CLASS
public class NoNotification extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
abortBroadcast();
}
}
SECOND JAVA FILE
private static final String CHECK_OP_NO_THROW = "checkOpNoThrow";
private static final String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION";
public static boolean isNotificationEnabled(Context context) {
AppOpsManager mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
ApplicationInfo appInfo = context.getApplicationInfo();
String pkg = context.getApplicationContext().getPackageName();
int uid = appInfo.uid;
Class appOpsClass = null; /* Context.APP_OPS_MANAGER */
try {
appOpsClass = Class.forName(AppOpsManager.class.getName());
Method checkOpNoThrowMethod = appOpsClass.getMethod(CHECK_OP_NO_THROW, Integer.TYPE, Integer.TYPE, String.class);
Field opPostNotificationValue = appOpsClass.getDeclaredField(OP_POST_NOTIFICATION);
int value = (int)opPostNotificationValue.get(Integer.class);
return ((int)checkOpNoThrowMethod.invoke(mAppOps,value, uid, pkg) == AppOpsManager.MODE_ALLOWED);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return false;
}
}
Could I possibly be missing some permissions?
Thanks.
I am using an actionListener to trigger an sequence of events and ultimatley this code is called:
public class ScriptManager {
public static Class currentScript;
private Object ScriptInstance;
public int State = 0;
// 0 = Not Running
// 1 = Running
// 2 = Paused
private Thread thread = new Thread() {
public void run() {
try {
currentScript.getMethod("run").invoke(ScriptInstance);
} catch(Exception e) {
e.printStackTrace();
}
}
};
public void runScript() {
try {
ScriptInstance = currentScript.newInstance();
new Thread(thread).start();
State = 1;
MainFrame.onPause();
} catch (Exception e) {
e.printStackTrace();
}
}
public void pauseScript() {
try {
thread.wait();
System.out.println("paused");
State = 2;
MainFrame.onPause();
} catch (Exception e) {
e.printStackTrace();
}
}
public void resumeScript() {
try {
thread.notify();
System.out.println("resumed");
State = 1;
MainFrame.onResume();
} catch (Exception e) {
e.printStackTrace();
}
}
public void stopScript() {
try {
thread.interrupt();
thread.join();
System.out.println("stopped");
State = 0;
MainFrame.onStop();
} catch (Exception e) {
e.printStackTrace();
}
}
}
The runnable is created and ran, however, the problem occurs when I try to use the any of the other methods, they lock my UI. (I'm assuming this is because im running this on the EDT) Does anyone know how to fix this?
That's not how you use wait and notify. They need to be executed on the thread that you are trying to pause and resume. Which means you need to send a message to the other thread somehow. There are various ways to do this, but the other thread needs to be listening for this message, or at least check for it occassionally.
I have desktop and android applications, which connected by bluetooth(in desktop side I use Bluecove 2.1.1 library). Desktop application create bluetooth service then android application connects to it. I want to add logout functionality from both desktop and android sides. For example in desktop app user click disconnect, both desktop and android apps reset their connections and should be able to connect again. Here is bluetoothService code for desktop side:
public class BluetoothService
{
private static final String serviceName = "btspp://localhost:"
// + new UUID("0000110100001000800000805F9B34F7", false).toString()
// + new UUID("0000110100001000800000805F9B34F8", false).toString()
+ new UUID("0000110100001000800000805F9B34F9", false).toString()
+ ";name=serviceName";
private StreamConnectionNotifier m_service = null;
private ListenerThread m_listenerThread;
private DataOutputStream m_outStream;
public BluetoothService()
{
Open();
}
public void Open()
{
try
{
assert (m_service == null);
m_service = (StreamConnectionNotifier) Connector.open(serviceName);
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void Start()
{
try
{
StreamConnection connection = (StreamConnection) m_service
.acceptAndOpen();
System.out.println("Connected");
m_listenerThread = new ListenerThread(connection);
Thread listener = new Thread(m_listenerThread);
listener.start();
m_outStream = new DataOutputStream(connection.openOutputStream());
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void Send(String message)
{
assert (m_listenerThread != null);
try
{
m_outStream.writeUTF(message);
m_outStream.flush();
System.out.println("Sent: " + message);
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void Close()
{
try
{
m_service.close();
m_listenerThread.Stop();
m_listenerThread = null;
m_outStream.close();
m_outStream = null;
m_service = null;
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
class ListenerThread implements Runnable
{
private DataInputStream m_inStream;
private boolean m_isRunning;
public ListenerThread(StreamConnection connection)
{
try
{
this.m_inStream = new DataInputStream(connection.openInputStream());
m_isRunning = true;
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
;
}
public void run()
{
while (m_isRunning)
{
try
{
assert (m_inStream != null);
if (m_inStream.available() > 0)
{
String message = m_inStream.readUTF();
System.out.println("Received command: " + message);
CommandManager.getInstance().Parse(message);
}
}
catch (IOException e)
{
System.err.println(e.toString());
}
}
}
public void Stop()
{
m_isRunning = false;
try
{
m_inStream.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
for restarting service I do:
BluetoothService::Close();
BluetoothService::Open();
BluetoothService::Start();
but seems I cannot reconnect. Maybe I should create service with different name?
My Android App needs some basic data to run. This data is downloaded from a server using JSON. In Xcode I simply used the sendsynchronous request but I noticed that Eclipse gives me a error when i do networking on the main ui.
Found a lot of stuff on asynctask but i want my app to wait till the required data is downloaded (synchronous?).
I tried using asynctask .execute().get() and setting the variables in onPostExecute but when I return the variable I get a NullPointerException. Does someone know how to make this work? I really need this data before the app can run so I want my app to wait till the data is downloaded.
MainActivity calls this:
SingletonClass appIDSingleton = SingletonClass.getInstance();
this.ID = appIDSingleton.getAppID();
Singleton Class:
public String getAppID() {
try {
new DownloadAppID().execute(APP_ID_URL).get(5000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return AppID; //AppID is still NULL (because the download isnt finished yet?)
}
private class DownloadAppID extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String response = "";
for (String url : urls) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse execute = client.execute(httpGet);
InputStream content = execute.getEntity().getContent();
BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
response += s;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return response;
}
#Override
protected void onPostExecute(String result) {
System.out.println(result);
AppID = result;
}
}
You need to understand that your getAppID method can't return a result that is going to be computed asynchronously.
You could for instance provide a listener to your async task in order to notify when app ID is available:
SingletonClass appIDSingleton = SingletonClass.getInstance();
appIDSingleton.getAppID(new AppIdDownloadListener() {
#Override
public void appIDAvailable(String appId) {
this.ID = appId;
}
});
public void getAppID(AppIdDownloadListener listener) {
try {
new DownloadAppID(listener).execute(APP_ID_URL).get(5000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public interface AppIdDownloadListener {
public void appIDAvailable(String appId);
}
private class DownloadAppID extends AsyncTask<String, Void, String> {
private AppIdDownloadListener listener;
public DownloadAppID(AppIdDownloadListener listener) {
this.listener = listener;
}
#Override
protected String doInBackground(String... params) {
/* Your stuff here */
}
#Override
protected void onPostExecute(String result) {
System.out.println(result);
listener.appIDAvailable(result);
}
}