I'm new in Android world (as user but also as developer) and my Android App crash when execute myWebView.loadUrl("https://www.google.com"), but I don't understand why...
The goal is monitoring internet connection while the app is running:
If the connection is lost -> loads the error html in the web view
If the connection returns active -> reload the web view
Here's my app code:
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dedalos.amb">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".SplashScreen" android:theme="#style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
MainActivity
public class MainActivity extends AppCompatActivity {
// WEB VIEW
WebView myWebView = null;
// NETWORK MONITORING
Boolean isInternetConnected = false;
ConnectivityManager.NetworkCallback networkCallback = null;
ConnectivityManager connectivityManager = null;
//////////////////// OVERRIDE ////////////////////
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
hideSystemUI();
SharedPreferences prefs = getPreferences(MODE_PRIVATE);
if (getToken().equals("")) {
String uniqueID = UUID.randomUUID().toString();
SharedPreferences.Editor editor = prefs.edit();
editor.putString("token", uniqueID);
editor.commit();
}
creaWebView();
configuraWebView();
initNetworkCallback();
}
#Override
public void onResume() {
super.onResume();
if (myWebView == null) {
creaWebView();
configuraWebView();
}
if (networkCallback == null || connectivityManager == null)
initNetworkCallback();
isInternetConnected = (new ConnectionDetector(this).isConnectingToInternet());
startNetworkMonitoring();
if (isInternetConnected) {
caricaWebView();
}
else {
MyWebViewClient.loadError(myWebView);
}
}
#Override
public void onPause() {
super.onPause();
stopNetworkMonitoring();
}
private void creaWebView() {
if (myWebView == null) {
myWebView = (WebView) findViewById(R.id.ambWebViewLayout);
}
}
private void configuraWebView() {
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
myWebView.setWebViewClient(new MyWebViewClient());
}
private void caricaWebView() {
if (myWebView == null) {
creaWebView();
configuraWebView();
}
myWebView.loadUrl("https://www.google.com");
}
private void initNetworkCallback() {
networkCallback = new ConnectivityManager.NetworkCallback() {
#Override
public void onAvailable(Network network) {
if (!isInternetConnected) {
isInternetConnected = true;
caricaWebView();
}
}
#Override
public void onLost(Network network) {
if (isInternetConnected) {
isInternetConnected = false;
MyWebViewClient.loadError(myWebView);
}
}
};
connectivityManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
}
private void startNetworkMonitoring() {
if (networkCallback == null)
initNetworkCallback();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
connectivityManager.registerDefaultNetworkCallback(networkCallback);
}
else {
NetworkRequest request = new NetworkRequest.Builder().addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET).build();
connectivityManager.registerNetworkCallback(request, networkCallback);
}
}
private void stopNetworkMonitoring() {
connectivityManager.unregisterNetworkCallback(networkCallback);
}
private String getToken() {
return getPreferences(MODE_PRIVATE).getString("token", "");
}
private void hideSystemUI() {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE
// Set the content to appear under the system bars so that the
// content doesn't resize when the system bars hide and show.
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
// Hide the nav bar and status bar
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
}
}
MyWebViewClient
public class MyWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith("https://www.google.com")) {
view.getContext().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
return true;
}
else {
return false;
}
}
#Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
if (error.getErrorCode() == -2) {
loadError(view);
}
else {
// TODO
}
}
public static void loadError(WebView view) {
String html = "<!DOCTYPE HTML>\n" +
"<html>\n" +
"<head>\n" +
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n" +
"<title>APP</title>\n" +
"</head>\n" +
"<body style=\"background:#e11020;font-family:Arial,Helvetica;\">\n" +
"<h1 style=\"color:rgba(255,255,255,0.9);text-align:center;padding:120px 20px 20px 20px;font-size:30px;\">No Internet connection</h1>\n" +
"</body>\n" +
"</html>";
view.loadDataWithBaseURL(null, html, "text/html", "UTF-8", null);
}
}
ConnectionDetector
public class ConnectionDetector {
private Context mContext;
public ConnectionDetector(Context context) {
this.mContext = context;
}
/**
* Checking for all possible internet providers
* **/
public boolean isConnectingToInternet() {
ConnectivityManager connectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Network[] networks = connectivityManager.getAllNetworks();
NetworkInfo networkInfo;
for (Network mNetwork : networks) {
networkInfo = connectivityManager.getNetworkInfo(mNetwork);
if (networkInfo.getState().equals(NetworkInfo.State.CONNECTED)) {
return true;
}
}
}
else {
if (connectivityManager != null) {
//noinspection deprecation
NetworkInfo[] info = connectivityManager.getAllNetworkInfo();
if (info != null) {
for (NetworkInfo anInfo : info) {
if (anInfo.getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
}
}
}
return false;
}
}
Thanks in advance
According to this you need to call all view related methods on UI thread. Just load the url on UI thread like this:
myWebView.post(new Runnable() {
#Override
public void run() {
myWebView.loadUrl("https://www.google.com");
}
});
You also need to load your error html in the same way, like:
view.post(new Runnable() {
#Override
public void run() {
String html = "<!DOCTYPE HTML>\n" +
"<html>\n" +
"<head>\n" +
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n" +
"<title>APP</title>\n" +
"</head>\n" +
"<body style=\"background:#e11020;font-family:Arial,Helvetica;\">\n" +
"<h1 style=\"color:rgba(255,255,255,0.9);text-align:center;padding:120px 20px 20px 20px;font-size:30px;\">No Internet connection</h1>\n" +
"</body>\n" +
"</html>";
view.loadDataWithBaseURL(null, html, "text/html", "UTF-8", null);
}
});
If you get Only the original thread that created a view hierarchy can touch its views error in your Logcat, use this.
Related
Hi I m getting this error again and again.
Process: pandaboo.run.carromking, PID: 30965
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{pandaboo.run.carromking/pandaboo.run.carromking.MainActivity}: java.lang.InstantiationException: java.lang.Class<pandaboo.run.carromking.MainActivity> has no zero argument constructor
the android manifest is as follow:
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:fullBackupContent="#xml/backup_descriptor"
tools:ignore="AllowBackup">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
there is no error in build but there is a red underline in the manifest under the .MainActivity with error:
This class should provide a default constructor (a public constructor with no arguments) (`pandaboo.run.carromking.MainActivity`)
pls help.
sure the MainActivity is as follow:
public class MainActivity extends Activity {
#SuppressLint("StaticFieldLeak")
static Context context;
public final ThreadLocal<Discovery> disc;
{
disc = new ThreadLocal<Discovery>() {
#Override
protected Discovery initialValue() {
return new Discovery(Discovery.DiscoveryType.MDNS);
}
};
}
public static Publisher gamePublisher;
Subscriber gameSubscriber;
Thread testPublishing;
RenderThread renderThread;
private final Node node;
public MainActivity(Node node) {
this.node = node;
}
public class TestPublishing extends Application implements Runnable {
#Override
public void run() {
while (gamePublisher != null) {
Log.v("CarromGame: umundo", "run");
//gamePublisher.send(message.getBytes());
try {
Thread.sleep(1000);
Log.v("CarromGame:", "sleep");
} catch (InterruptedException e) {
Log.v("CarromGame: exception", "in run");
e.printStackTrace();
}
pandaboo.run.carromking.MainActivity.this.runOnUiThread(() -> {
//tv.setText(tv.getText() + "o");
Log.v("CarromGame: umundo", "context view o");
//contentView = true;
renderThread = new RenderThread(new pandaboo.run.carromking.MainActivity.displayComponents().getHolder(), new MainGamePanel(pandaboo.run.carromking.MainActivity.this));
renderThread.start();
});
}
}
}
public class TestReceiver extends Receiver {
byte[] msgb;
String type = null;
public void receive(Message msg) {
msgb = msg.getData();
type = msg.getMeta("CLASS");
Log.v("CarromGame:umundo value", "TYPE = " + type);
for (String key : msg.getMeta().keySet()) {
Log.v("CarromGame: umundo", key + ": " + msg.getMeta(key) + " value for class" + msg.getMeta("CLASS"));
}
pandaboo.run.carromking.MainActivity.this.runOnUiThread(() -> {
//tv.setText(tv.getText() + "i");
Log.v("CarromGame: umundo", "context view i before");
ObjectInputStream is = null;
if ((type != null) && (!type.equals(""))) {
try {
type = null;
ByteArrayInputStream in = new ByteArrayInputStream(msgb);
is = new ObjectInputStream(in);
is.readObject();
Log.v("CarromGame: umundo", "inside try block " + is.toString());
} catch (Exception e) {
e.printStackTrace();
}
assert is != null;
Log.v("CarromGame: umundo", "context view i after" + is.toString());
renderThread = new RenderThread(new pandaboo.run.carromking.MainActivity.displayComponents().getHolder(), new MainGamePanel(pandaboo.run.carromking.MainActivity.this));
renderThread.start();
}
});
}
}
public class displayComponents extends SurfaceView implements SurfaceHolder.Callback {
public displayComponents() {
super(getApplicationContext());
this.getHolder().addCallback(this);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
renderThread.running = true;
renderThread.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
while (true) {
try {
renderThread.join();
break;
} catch (InterruptedException ignored) {
}
}
}
}
//Called when activity is created for the first time
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
WifiManager wifi = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
// To check if there is any active Wifi connection
if (!wifi.isWifiEnabled()) {
startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
}
//Allow the application to receive Wifi Multicast packets.
WifiManager.MulticastLock mcLock = wifi.createMulticastLock("gameLock");
mcLock.acquire();
System.loadLibrary("umundoNativeJava");
Objects.requireNonNull(disc.get()).add(node);
Log.v("CarromGame:", "on create");
gamePublisher = new Publisher("Carrom"); //Carrom: channel Name
node.addPublisher(gamePublisher);
//gamePublisher.send();
gameSubscriber = new Subscriber("Carrom", new pandaboo.run.carromking.MainActivity.TestReceiver());
node.addSubscriber(gameSubscriber);
testPublishing = new Thread(new pandaboo.run.carromking.MainActivity.TestPublishing());
//contentView();
testPublishing.start();
Log.v("CarromGame: umundo", "inside context view");
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
//setTitle(title);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
MainGamePanel.PANEL_HEIGHT = this.getWindowManager().getDefaultDisplay().getHeight();
MainGamePanel.PANEL_WIDTH = this.getWindowManager().getDefaultDisplay().getWidth();
setContentView(new MainGamePanel(this));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_carrom_game_umundo, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
return super.onOptionsItemSelected(item);
}
}
You cannot do this:
public MainActivity(Node node) {
this.node = node;
}
Do not declare any constructors for an Activity. Only the Android framework can instantiate an Activity and you cannot define any additional constructors.
i want to set video as Wallpaper just like ZEDGE Wallpaper and others wallpaper application do in play store. following is screen shot of ZEDGE Wallpaper app that set video As a Wallpaper in android.
i use below code for image as wallpaper:
val intentt = Intent(Intent.ACTION_ATTACH_DATA)
.setDataAndType(uri, "image/*")
.putExtra("mimeType", "image/*")
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
startActivityForResult(Intent.createChooser(intentt, getString(R.string.setas)), 1)
what can i do for Video to Set As Wallpaper?
Hello i found solution for my problem:
in Kotlin Android:
class VideoLiveWallpaperService : WallpaperService() {
override fun onCreateEngine(): WallpaperService.Engine {
return VideoEngine()
}
internal inner class VideoEngine : WallpaperService.Engine() {
private val TAG = javaClass.simpleName
private val mediaPlayer: MediaPlayer
init {
Log.i(TAG, "( VideoEngine )")
mediaPlayer = MediaPlayer.create(baseContext, R.raw.video1)
mediaPlayer.isLooping = true
}
override fun onSurfaceCreated(holder: SurfaceHolder) {
Log.i(TAG, "onSurfaceCreated")
mediaPlayer.setSurface(holder.surface)
mediaPlayer.start()
}
override fun onSurfaceDestroyed(holder: SurfaceHolder) {
Log.i(TAG, "( INativeWallpaperEngine ): onSurfaceDestroyed")
playheadTime = mediaPlayer.currentPosition
mediaPlayer.reset()
mediaPlayer.release()
}
}
companion object {
protected var playheadTime = 0
}
}
in Java:
public class VideoWallpaperService extends WallpaperService
{
protected static int playheadTime = 0;
#Override
public Engine onCreateEngine()
{
return new VideoEngine();
}
class VideoEngine extends Engine
{
private final String TAG = getClass().getSimpleName();
private final MediaPlayer mediaPlayer;
public VideoEngine()
{
super();
Log.i( TAG, "( VideoEngine )");
mediaPlayer = MediaPlayer.create(getBaseContext(), R.raw.wallpapervideo);
mediaPlayer.setLooping(true);
}
#Override
public void onSurfaceCreated( SurfaceHolder holder )
{
Log.i( TAG, "onSurfaceCreated" );
mediaPlayer.setSurface(holder.getSurface());
mediaPlayer.start();
}
#Override
public void onSurfaceDestroyed( SurfaceHolder holder )
{
Log.i( TAG, "( INativeWallpaperEngine ): onSurfaceDestroyed" );
playheadTime = mediaPlayer.getCurrentPosition();
mediaPlayer.reset();
mediaPlayer.release();
}
}
}
in Manifest:
<service android:name=".VideoLiveWallpaperService"
android:label="Video live wallpaper" android:permission="android.permission.BIND_WALLPAPER">
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
</intent-filter>
<meta-data android:name="android.service.wallpaper"
android:resource="#xml/wallpaper" />
</service>
in res/xml/wallpaper.xml:
<?xml version="1.0" encoding="utf-8"?>
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android" />
So I'm writing an app that reads reads in data from the serial port. This data is coming in from an arduino which is connected to a force transducer - essentially, the app is meant to measure the weight of something. I found serial port code here: https://www.allaboutcircuits.com/projects/communicate-with-your-arduino-through-android/, and I'm using it in multiple different activities (since I need an activity for calibration, an activity for the actual measuring, etc.). My problem is that the same exact serial port code is working in one activity and is not working in another. It works in this activity, for example:
public class EnterDataActivity extends AppCompatActivity {
private static final long TIMER_DELAY = 5000;
private static final long TIMER_LENGTH = 15000;
EditText enterMax, enterMin;
Button submitMax, submitMin, continueButton;
Chronometer emptyBagTimer;
boolean firstMeasure, getEmptyBagData, canEnterMax, canEnterMin;
ArrayList<String> emptyBagData;
float maxLoad, minLoad;
// serial port variables:
public final String ACTION_USB_PERMISSION = "com.example.jake.USB_PERMISSION";
UsbManager usbManager;
UsbDevice device;
UsbSerialDevice serialPort;
UsbDeviceConnection connection;
UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() { //Defining a Callback which triggers whenever data is read.
#Override
public void onReceivedData(byte[] arg0) {
String data;
try {
data = new String(arg0, "UTF-8");
if(getEmptyBagData)
emptyBagData.add(data);
} catch (UnsupportedEncodingException e) {}
}
};
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { //Broadcast Receiver to automatically start and stop the Serial connection.
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_USB_PERMISSION)) {
boolean granted = intent.getExtras().getBoolean(UsbManager.EXTRA_PERMISSION_GRANTED);
if (granted) {
connection = usbManager.openDevice(device);
serialPort = UsbSerialDevice.createUsbSerialDevice(device, connection);
if (serialPort != null) {
if (serialPort.open()) { //Set Serial Connection Parameters.
serialPort.setBaudRate(9600);
serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8);
serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1);
serialPort.setParity(UsbSerialInterface.PARITY_NONE);
serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
serialPort.read(mCallback);
} else {
Log.d("SERIAL", "PORT NOT OPEN");
}
} else {
Log.d("SERIAL", "PORT IS NULL");
}
} else {
Log.d("SERIAL", "PERM NOT GRANTED");
}
} else if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
start();
} else if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {
stop();
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_enter_data);
usbManager = (UsbManager) getSystemService(USB_SERVICE);
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
registerReceiver(broadcastReceiver, filter);
enterMax = (EditText) findViewById(R.id.enterMax);
enterMin = (EditText) findViewById(R.id.enterMin);
submitMax = (Button) findViewById(R.id.submitMax);
submitMin = (Button) findViewById(R.id.submitMin);
continueButton = (Button) findViewById(R.id.continueButton);
emptyBagTimer = (Chronometer) findViewById(R.id.emptyBagTimer);
firstMeasure = true;
getEmptyBagData = false;
canEnterMax = true;
canEnterMin = true;
emptyBagData = new ArrayList<>();
start();
}
// method: measureEmptyBag
// description: this method is called when the button to measure the mass of the empty bag is
// pressed. It starts the chronometer and serial port, first waiting TIMER_DELAY milliseconds
// from the button press, then sets a boolean to true that causes the serial data to be added to
// an arraylist over the next TIMER_LENGTH milliseconds. It then sets the next views in the
// enter data process to visible. The firstMeasure boolean is to prevent spamming.
public void measureEmptyBag(View view){
if(firstMeasure) {
firstMeasure = false;
start();
emptyBagTimer.setBase(SystemClock.elapsedRealtime());
emptyBagTimer.start();
emptyBagTimer.setFormat("Waiting - %s");
emptyBagTimer.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
#Override
public void onChronometerTick(Chronometer chronometer) {
if (SystemClock.elapsedRealtime() - emptyBagTimer.getBase() <= TIMER_DELAY)
emptyBagTimer.setFormat("Waiting - %s");
else if (SystemClock.elapsedRealtime() - emptyBagTimer.getBase() <= TIMER_DELAY + TIMER_LENGTH) {
emptyBagTimer.setFormat("Calculating - %s");
getEmptyBagData = true;
}
else if (SystemClock.elapsedRealtime() - emptyBagTimer.getBase() > TIMER_DELAY + TIMER_LENGTH) {
getEmptyBagData = false;
emptyBagTimer.stop();
enterMax.setVisibility(View.VISIBLE);
submitMax.setVisibility(View.VISIBLE);
}
else
emptyBagTimer.setFormat("Waiting - %s");
}
});
}
}
// method: setMaxLoad
// description: called when the submit button is pressed for the max load, this method trys to
// pull the max load value from it edit text and store it. If that is successful (the user has
// entered in a number) then it sets the next views in the enter data process to visible.
public void setMaxLoad(View view){
if(canEnterMax){
try {
canEnterMax = false;
maxLoad = Float.parseFloat(enterMax.getText().toString());
enterMin.setVisibility(View.VISIBLE);
submitMin.setVisibility(View.VISIBLE);
} catch (Exception e) {} // in case the user enters a non number
}
}
// method: setMinLoad
// description: called when the submit button is pressed for the min load, this method trys to
// pull the min load value from its edit text and store it. If that is successful (the user has
// entered in a number) then it sets the next view in the enter data process to visible.
public void setMinLoad(View view){
if(canEnterMin){
try {
canEnterMin = false;
minLoad = Float.parseFloat(enterMin.getText().toString());
continueButton.setVisibility(View.VISIBLE);
} catch (Exception e) {} // in case the user enters a non number
}
}
// method: continuePressed
// description: this method is called when the continue button is pressed. It averages all of the
// data read in over the measure empty mass period to find the mass when empty, then writes that
// value along with maxLoad and minLoad to a file for later use. Finally it starts the pump
// activity
public void continuePressed(View view){
int emptyMassSum = 0;
int emptyMass;
// cleaning up emptyBagData to only include 3,2, or 1 digit numbers (the serial output gets
// wonky sometimes and spits out weird numbers that would throw off the calculations below,
// so those numbers need to be removed)
for (int i = emptyBagData.size() - 1; i >= 0; i--)
if (emptyBagData.get(i).length() != 3)
emptyBagData.remove(i);
// add up all the values in emptyBagData (try catch in case a non-number was read in)
for (int i = emptyBagData.size() - 1; i >= 0; i--) {
try {
emptyMassSum += Integer.parseInt(emptyBagData.get(i));
} catch (Exception e) {
emptyBagData.remove(i);
}
}
emptyMass = emptyMassSum / emptyBagData.size();
FileOutputStream outputStream;
String dataOut = "E" + emptyMass + "Mx" + maxLoad + "Mn" + minLoad + ";";
try {
outputStream = openFileOutput("BagData.txt", Context.MODE_PRIVATE);
outputStream.write(dataOut.getBytes());
outputStream.close();
} catch (Exception e) {
continueButton.setText(R.string.file_write_error_message);
}
Intent intent = new Intent(this, PumpActivity.class);
startActivity(intent);
}
// serial port methods:
public void start() {
HashMap<String, UsbDevice> usbDevices = usbManager.getDeviceList();
if (!usbDevices.isEmpty()) {
boolean keep = true;
for (Map.Entry<String, UsbDevice> entry : usbDevices.entrySet()) {
device = entry.getValue();
int deviceVID = device.getVendorId();
if (deviceVID == 10755 || deviceVID == 9025)//Arduino Vendor ID
{
PendingIntent pi = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
usbManager.requestPermission(device, pi);
keep = false;
} else {
connection = null;
device = null;
}
if (!keep)
break;
}
}
}
public void stop() {
if(serialPort!=null)
serialPort.close();
}
}
By "it works", I mean that I can get the data coming in from the serial port and use it. However, the same code does not work here:
public class PumpActivity extends AppCompatActivity {
File calibrationData, bagData;
int mass1, mass2, read1, read2, emptyMassNum;
float maxLoad, minLoad;
double slope, currentMassVal, emptyMass;
boolean status, runTimer;
TextView statusTextView, currentMassTextView;
Button stop;
Thread updateMass;
ArrayList<String> inData;
// this does two things when the handleMessage method is called:
// 1) it takes the most recent data read in and calculates the current mass from it, then updates
// the current mass text view to reflect that
// 2) it takes that newly calculated mass and sees if status should change, depending on how much
// mass there currently is. It also writes a value to the serial port (back to the arduino)
// depending on that status. It then updates the status text view to reflect this
Handler updateMassHandler = new Handler(){
public void handleMessage(Message msg){
// mass calculation
try{currentMassVal = calculateMass(Integer.parseInt(inData.get(inData.size()-1)));} catch (Exception e){} // try-catch in case data isn't an int
inData.clear();
currentMassTextView.setText(String.format(getResources().getString(R.string.current_mass_string), currentMassVal));
// status check with new mass
if (currentMassVal >= maxLoad)
status = true;
else if (currentMassVal <= minLoad)
status = false;
statusTextView.setText(String.format(getResources().getString(R.string.pump_status), getStatus()));
// writing back to arduino
if (serialPort != null) {
if (status)
serialPort.write("1".getBytes());
else
serialPort.write("0".getBytes());
}
}
};
// serial port variables:
public final String ACTION_USB_PERMISSION = "com.example.jake.USB_PERMISSION";
UsbManager usbManager;
UsbDevice device;
UsbSerialDevice serialPort;
UsbDeviceConnection connection;
UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() { //Defining a Callback which triggers whenever data is read.
#Override
public void onReceivedData(byte[] arg0) {
String data;
try {
data = new String(arg0, "UTF-8");
inData.add(data);
} catch (UnsupportedEncodingException e) {}
}
};
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { //Broadcast Receiver to automatically start and stop the Serial connection.
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_USB_PERMISSION)) {
boolean granted = intent.getExtras().getBoolean(UsbManager.EXTRA_PERMISSION_GRANTED);
if (granted) {
connection = usbManager.openDevice(device);
serialPort = UsbSerialDevice.createUsbSerialDevice(device, connection);
if (serialPort != null) {
if (serialPort.open()) { //Set Serial Connection Parameters.
serialPort.setBaudRate(9600);
serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8);
serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1);
serialPort.setParity(UsbSerialInterface.PARITY_NONE);
serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
serialPort.read(mCallback);
} else {
Log.d("SERIAL", "PORT NOT OPEN");
}
} else {
Log.d("SERIAL", "PORT IS NULL");
}
} else {
Log.d("SERIAL", "PERM NOT GRANTED");
}
} else if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
start();
} else if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {
stop();
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pump);
usbManager = (UsbManager) getSystemService(USB_SERVICE);
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
registerReceiver(broadcastReceiver, filter);
status = false;
statusTextView = (TextView) findViewById(R.id.statusTextView);
statusTextView.setText(String.format(getResources().getString(R.string.pump_status), getStatus()));
currentMassTextView = (TextView) findViewById(R.id.currentMassTextView);
currentMassTextView.setText(R.string.calculating_text);
stop = (Button) findViewById(R.id.stopButton);
runTimer = true;
currentMassVal = 0;
inData = new ArrayList<>();
// thread that "calls" the handleMessage method in the upDateMassHandler every 100 milliseconds
updateMass = new Thread(new Runnable() {
#Override
public void run() {
while(runTimer){
updateMassHandler.sendEmptyMessage(0);
try{Thread.sleep(100);} catch (InterruptedException e){}
}
}
});
// thanks to stackOverflow for the file reading code
// reading and parsing from calibration data
calibrationData = new File(getFilesDir(), "CalibrationData.txt");
StringBuilder text = new StringBuilder();
// reading in the calibration data from the file (of the same name)
try {
BufferedReader br = new BufferedReader(new FileReader(calibrationData));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
text.append('\n');
}
br.close();
} catch (IOException e) {}
// parsing values from calibration data
String calibData = text.toString();
calibData = calibData.substring(3);
mass1 = Integer.parseInt(calibData.substring(0, calibData.indexOf('R')));
calibData = calibData.substring(calibData.indexOf(':') + 1);
read1 = Integer.parseInt(calibData.substring(0, calibData.indexOf('M')));
calibData = calibData.substring(calibData.indexOf(':') + 1);
mass2 = Integer.parseInt(calibData.substring(0, calibData.indexOf('R')));
calibData = calibData.substring(calibData.indexOf(':') + 1);
read2 = Integer.parseInt(calibData.substring(0, calibData.indexOf('.')));
slope = ((double) (mass2 - mass1) / (read2 - read1)); // calculating slope of masses and reads to allow
// calculation of mass of an unknown read
// reading and parsing from bag data
bagData = new File(getFilesDir(), "BagData.txt");
StringBuilder text2 = new StringBuilder();
// reading in the bag data from the file (of the same name)
try {
BufferedReader br = new BufferedReader(new FileReader(bagData));
String line;
while ((line = br.readLine()) != null) {
text2.append(line);
text2.append('\n');
}
br.close();
} catch (IOException e) {}
// parsing values frm bag data
String bagData = text2.toString();
bagData = bagData.substring(1);
emptyMassNum = Integer.parseInt(bagData.substring(0, bagData.indexOf('M')));
bagData = bagData.substring(bagData.indexOf('x') + 1);
maxLoad = Float.parseFloat(bagData.substring(0, bagData.indexOf('M')));
bagData = bagData.substring(bagData.indexOf('n') + 1);
minLoad = Float.parseFloat(bagData.substring(0, bagData.indexOf(';')));
emptyMass = calculateMass(emptyMassNum); // emptyMassNum is the values read in from the arduino
// this converts it to a mass
updateMass.start();
start();
}
// method: calculateMass
// description: calculates the mass of the object on the transducer based off of the value read
// in and the data gotten from calibration
// input: int readVal - the value read in
// output: double - the calculated mass
public double calculateMass(int readVal){
return (slope * (readVal-read1)) + mass1;
}
// method: getStatus
// description: returns a string representation of the status
public String getStatus(){
if(status)
return "running";
else
return "stopped";
}
// method: stop
// description: stops everything when the stop button is pressed
public void stop(View view){
status = false;
runTimer = false;
stop();
stop.setText(R.string.button_stopped);
}
// serial port methods:
public void start() {
HashMap<String, UsbDevice> usbDevices = usbManager.getDeviceList();
if (!usbDevices.isEmpty()) {
boolean keep = true;
for (Map.Entry<String, UsbDevice> entry : usbDevices.entrySet()) {
device = entry.getValue();
int deviceVID = device.getVendorId();
if (deviceVID == 10755 || deviceVID == 9025)//Arduino Vendor ID
{
PendingIntent pi = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
usbManager.requestPermission(device, pi);
keep = false;
} else {
connection = null;
device = null;
}
if (!keep)
break;
}
}
}
public void stop() {
if(serialPort!=null)
serialPort.close();
}
}
For some reason, the onReceivedData method in the mCallback variable does not seem to be called in the second activity (the one not working). I'm pretty sure this is the problem, I'm just not sure why it is being called in one activity and not in another with the same code. If that method is not called, then I can't access the data coming in, which is my problem.
Also, here's my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.stylosa.hangingtransducer">
<uses-feature android:name="android.hardware.usb.host" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
</intent-filter>
</activity>
<activity
android:name=".CalibrateActivity">
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
</intent-filter>
</activity>
<activity
android:name=".InputActivity"
android:parentActivityName=".MainActivity">
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
</intent-filter>
</activity>
<activity
android:name=".EnterDataActivity">
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
</intent-filter>
</activity>
<activity
android:name=".PumpActivity">
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
</intent-filter>
</activity>
</application>
Any and all help would be greatly appreciated!
I run through the following life-cycle when starting my app through the launcher:
onCreate..., onPostCreate..., onResume..., onNewIntent..., act:android.intent.action.MAIN, mNfcAdapter.disableForegroundDispatch OK.
When I then tap a tag, a new instance of application seems to be launched as I run through the following life-cycle then:
onPause..., onCreate..., onPostCreate..., onResume..., onNewIntent..., act:android.nfc.action.TAG_DISCOVERED, myTag.mId:048a1382bd2384)
Since I try to use the foreground dispatch system to disable recieving NFC events, I expected my app to ignore the NFC tag. So why is my activity recreated instead? Is it because AndroidManifest.xml allows it?
package com.example.pdf.nfcaccess;
import android.annotation.SuppressLint;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
// PDf import
import android.telephony.TelephonyManager;
import android.content.Intent;
import android.content.Context;
import android.content.IntentFilter;
import android.app.PendingIntent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.NfcAdapter.CreateNdefMessageCallback;
import android.nfc.NfcEvent;
import android.widget.TextView;
import android.widget.Toast;
import android.util.Log;
import android.nfc.tech.NfcF;
import android.nfc.Tag;
/**
* An example full-screen activity that shows and hides the system UI (i.e.
* status bar and navigation/system bar) with user interaction.
*/
public class FullscreenActivity extends AppCompatActivity {
/**
* Whether or not the system UI should be auto-hidden after
* {#link #AUTO_HIDE_DELAY_MILLIS} milliseconds.
*/
private static final boolean AUTO_HIDE = true;
/**
* If {#link #AUTO_HIDE} is set, the number of milliseconds to wait after
* user interaction before hiding the system UI.
*/
private static final int AUTO_HIDE_DELAY_MILLIS = 3000;
/**
* Some older devices needs a small delay between UI widget updates
* and a change of the status and navigation bar.
*/
private static final int UI_ANIMATION_DELAY = 300;
private final Handler mHideHandler = new Handler();
private View mContentView;
private final Runnable mHidePart2Runnable = new Runnable() {
#SuppressLint("InlinedApi")
#Override
public void run() {
// Delayed removal of status and navigation bar
// Note that some of these constants are new as of API 16 (Jelly Bean)
// and API 19 (KitKat). It is safe to use them, as they are inlined
// at compile-time and do nothing on earlier devices.
mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
}
};
private View mControlsView;
// application
static FullscreenActivity mInstance;
NfcAdapter mNfcAdapter;
Intent mNfcIntent;
PendingIntent mNfcPendingIntent;
IntentFilter mTagIntentFilter;
IntentFilter[] mIntentFiltersArray;
String[][] mTechLists;
TextView mTagContentText;
// log
//java.util.ArrayList<String> mLogItems = new java.util.ArrayList<String>();
java.util.ArrayList<String> mLogItems = new java.util.ArrayList<String>();
android.widget.ArrayAdapter<String> mLogAdapter;
android.widget.ListView mLogList;
/**/
private final Runnable mShowPart2Runnable = new Runnable() {
#Override
public void run() {
// Delayed display of UI elements
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.show();
}
mControlsView.setVisibility(View.VISIBLE);
}
};
private boolean mVisible;
private final Runnable mHideRunnable = new Runnable() {
#Override
public void run() {
hide();
}
};
/**
* Touch listener to use for in-layout UI controls to delay hiding the
* system UI. This is to prevent the jarring behavior of controls going away
* while interacting with activity UI.
*/
/* Enable NFC
*/
private final View.OnTouchListener mFuncNfcEnable = new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
traceTry("mFuncNfcEnable");
if (mNfcAdapter != null) {
try {
traceTry("mNfcAdapter.enableForegroundDispatch");
mNfcAdapter.enableForegroundDispatch(FullscreenActivity.mInstance, mNfcPendingIntent, mIntentFiltersArray, mTechLists);
traceOk();
}
catch (Throwable t) {
traceFails(t);
}
}
}
return false;
}
};
/* read Intent
*/
private final View.OnTouchListener mFuncNfcRead = new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (mNfcAdapter != null) {
try {
traceTry("onNewIntent");
onNewIntent(getIntent());
traceOk();
}
catch (Throwable t) {
traceFails(t);
}
}
return false;
}
};
/* Disable NFC
*/
private final View.OnTouchListener mFuncNfcDisable = new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN){
traceTry("mFuncNfcDisable");
if (mNfcAdapter != null) {
try {
traceTry("mNfcAdapter.disableForegroundDispatch");
mNfcAdapter.disableForegroundDispatch(FullscreenActivity.mInstance);
traceOk();
}
catch (Throwable t) {
traceFails(t);
}
}
}
return false;
}
};
/* Quit
*/
private final View.OnTouchListener mFuncBtnQuit = new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
finish();
return false;
}
};
/**/
private void trace(String m) {
Log.d("NFCTags",m);
/*TextView tv = (TextView)findViewById(R.id.logContent_value);
String previous = tv.getText().toString();
tv.setText(previous + "\n" + m);*/
if (mLogAdapter != null) {
mLogItems.add(m);
mLogAdapter.notifyDataSetChanged();
mLogList.setSelection(mLogList.getCount()-1);
}
}
String mMessage = "";
private void traceTry(String m) {
trace(m + "...");
mMessage = m;
}
private void traceOk() {
trace(mMessage + " OK");
mMessage = "";
}
private void traceFails(Throwable t) {
String msg = mMessage + " fails";
if (t != null) {
msg += " exception:" + t.getMessage();
}
trace(msg);
//Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
mMessage = "";
}
/*
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
trace("onCreate...");
// set global unique instance
FullscreenActivity.mInstance = this;
setContentView(R.layout.activity_fullscreen);
// log
mLogItems.add("starts");
mLogAdapter = new android.widget.ArrayAdapter<String>(this, R.layout.support_simple_spinner_dropdown_item, mLogItems);
mLogList = (android.widget.ListView) findViewById(R.id.logList_value);
mLogList.setAdapter(mLogAdapter);
mVisible = true;
mControlsView = findViewById(R.id.fullscreen_content_controls);
mContentView = findViewById(R.id.fullscreen_content);
mTagContentText = (TextView) findViewById(R.id.tagContent_value);
// Set up the user interaction to manually show or hide the system UI.
mContentView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
toggle();
}
});
// Upon interacting with UI controls, delay any scheduled hide()
// operations to prevent the jarring behavior of controls going away
// while interacting with the UI.
findViewById(R.id.nfcRead_btn).setOnTouchListener(mFuncNfcRead);
//findViewById(R.id.nfcDisable_btn).setOnTouchListener(mFuncNfcDisable);
findViewById(R.id.quit_btn).setOnTouchListener(mFuncBtnQuit);
trace("onCreate > before initializing nfc");
TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
trace("ID:" + tm.getDeviceId());
trace("Network Operator Name:" + tm.getNetworkOperatorName());
trace("Sim Operator Name:" + tm.getSimOperatorName());
trace("Sim Serial Number:" + tm.getSimSerialNumber());
trace("Phone Type:" + tm.getPhoneType());
trace("Initial Phone Number:" + tm.getLine1Number());
boolean tryNfc = true;
if (tryNfc) {
try {
mMessage = "NfcAdapter.getDefaultAdapter";
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (mNfcAdapter == null) {
mMessage = "NFC is not available";
traceFails(null);
return;
} else {
traceOk();
}
} catch (Throwable t) {
traceFails(t);
return;
}
// Check if NFC is enabled
try {
mMessage = "test NfcAdapter.isEnabled";
if (!mNfcAdapter.isEnabled()) {
mMessage = "NFC is not enabled. do it manually";
traceFails(null);
return;
} else {
trace("NFC is enabled.");
}
} catch (Throwable t) {
traceFails(t);
return;
}
try {
mMessage = "create new Intent";
mNfcIntent = new Intent(this, getClass());
traceOk();
} catch (Throwable t) {
traceFails(t);
return;
}
try {
mMessage = "mNfcIntent.addFlags, PendingIntent.getActivity";
mNfcIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
mNfcPendingIntent = PendingIntent.getActivity(this, 0, mNfcIntent, 0);
traceOk();
} catch (Throwable t) {
traceFails(t);
return;
}
try {
mMessage = "new IntentFilter";
mTagIntentFilter = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
mTagIntentFilter.addCategory(Intent.CATEGORY_DEFAULT);
traceOk();
} catch (Throwable t) {
traceFails(t);
return;
}
try {
mMessage = "addDataType, new IntentFilter[]";
mTagIntentFilter.addDataType("*/*");
//mTagIntentFilter.addDataType("text/plain");
mIntentFiltersArray = new IntentFilter[]{mTagIntentFilter};
traceOk();
} catch (Throwable t) {
traceFails(t);
return;
}
// Setup a tech list for all NfcF tags
try {
mMessage = "new tech list";
//mTechLists = new String[][]{new String[]{NfcF.class.getName()}};
mTechLists = new String[][]{};
traceOk();
} catch (Throwable t) {
traceFails(t);
return;
}
/*
if (mNfcAdapter != null) {
try {
mMessage = "mNfcAdapter.enableForegroundDispatch";
mNfcAdapter.enableForegroundDispatch(FullscreenActivity.mInstance, mNfcPendingIntent, mIntentFiltersArray, mTechLists);
traceOk();
}
catch (Throwable t) {
traceFails(t);
}
}
*/
}
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
trace("onPostCreate...");
// Trigger the initial hide() shortly after the activity has been
// created, to briefly hint to the user that UI controls
// are available.
//delayedHide(100);
}
private void toggle() {
trace("toggle...");
if (mVisible) {
hide();
} else {
show();
}
}
private void hide() {
trace("hide...");
// Hide UI first
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.hide();
}
mControlsView.setVisibility(View.GONE);
mVisible = false;
// Schedule a runnable to remove the status and navigation bar after a delay
mHideHandler.removeCallbacks(mShowPart2Runnable);
mHideHandler.postDelayed(mHidePart2Runnable, UI_ANIMATION_DELAY);
}
#SuppressLint("InlinedApi")
private void show() {
// Show the system bar
mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
mVisible = true;
// Schedule a runnable to display UI elements after a delay
mHideHandler.removeCallbacks(mHidePart2Runnable);
mHideHandler.postDelayed(mShowPart2Runnable, UI_ANIMATION_DELAY);
}
/**
* Schedules a call to hide() in [delay] milliseconds, canceling any
* previously scheduled calls.
*/
private void delayedHide(int delayMillis) {
mHideHandler.removeCallbacks(mHideRunnable);
mHideHandler.postDelayed(mHideRunnable, delayMillis);
}
/**/
public String intentToText(Intent intent){
String report = "?";
try {
Bundle bundle = intent.getExtras();
if (bundle != null) {
java.util.Set<String> keys = bundle.keySet();
java.util.Iterator<String> it = keys.iterator();
report = "Intent:{";
while (it.hasNext()) {
String key = it.next();
report += "\n[" + key + ":" + bundle.get(key) + "],";
}
report += "}\n";
}
}
catch(Throwable t){
trace("intentToText > " + t.getMessage());
}
return report;
}
/**/
public static String byteArrayToHex(byte[] a) {
StringBuilder sb = new StringBuilder(a.length * 2);
for(byte b: a)
sb.append(String.format("%02x", b & 0xff));
return sb.toString();
}
/**/
#Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
trace("onNewIntent...");
handleIntent(intent);
}
/**/
void handleIntent(Intent intent) {
if (intent == null) return;
String sAction = intent.getAction();
trace("act:" + sAction);
if( (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()))
|| (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction()))
|| (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction()))) {
String payload = intent.getDataString();
mTagContentText.setText("act:" + sAction + "\n" + "pload:" + payload + "\n" + intentToText(intent));
Tag myTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
if (myTag != null) {
trace("myTag.mId:" + byteArrayToHex(myTag.getId()));
mTagContentText.setText(mTagContentText.getText() + "\n" + "myTag.mId:" + byteArrayToHex(myTag.getId()));
android.os.Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (rawMsgs != null) {
for (android.os.Parcelable p : rawMsgs) {
NdefMessage msg = (NdefMessage) p;
NdefRecord[] records = msg.getRecords();
for (NdefRecord record : records) {
short tnf = record.getTnf();
byte[] id = record.getId();
byte[] payLoad = record.getPayload();
}
}
}
}
}
}
/**/
#Override
protected void onResume() {
super.onResume();
trace("onResume...");
if (mNfcAdapter != null) {
try {
// See if the Activity is being started/resumed due to an NFC event and handle it
onNewIntent( getIntent());
}
catch (Throwable t) {
traceFails(t);
}
try {
mMessage = "mNfcAdapter.disableForegroundDispatch";
mNfcAdapter.disableForegroundDispatch(FullscreenActivity.mInstance);
traceOk();
}
catch (Throwable t) {
traceFails(t);
}
}
}
/**/
#Override
protected void onPause() {
super.onPause();
trace("onPause...");
}
}
AndroidManifest.xml is :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.pdf.nfcaccess">
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_pdflauncher"
android:label="#string/app_name"
android:supportsRtl="true"
android:debuggable="true"
android:theme="#style/AppTheme">
<activity
android:name=".FullscreenActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/app_name"
android:theme="#style/FullscreenTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
<!--intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain"/>
</intent-filter-->
</manifest>
You receive the NFC intent (action TAG_DISCOVERED) because you registered for it in the manifest:
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
This is also the reason why your activity is recreated upon receiving the intent.
The intent filter that you register for the foreground dispatch (action NDEF_DISCOVERED with any MIME type) does not seem to match your tag (or you did not yet invoke the piece of code that would enable the foreground dispatch).
Note that calling disableForegroundDispatch() will ony disable a foreground dispatch previously registered through enableForegroundDispatch(). It will not influence the intent filters in your manifest. See Android: Can I enable/disable an activity's intent filter programmatically? on how you could selectively disable intent filters registered in the manifest. However, with regard to NFC intents, you would probably want to register to receive events for all tags through the foreground dispatch system and then, upon receiving the event in onNewIntent() selectively ignore tags that you don't want.
A few more things about your code (actually only about the NFC parts)
For the NDEF_DISCOVERED intent filter in your manifest you would typically also want to specify a <data ... /> element that matches the data type of your tags.
Do not use a TAG_DISCOVERED intent filter in your manifest (unless you really understand and want the impact of this). The TAG_DISCOVERED intent filter (when used in the manifest) is merely a compatibility mode for API level 9 (before Android 2.3.3) where NFC support was very, very limited and a fall-back mode that can be used to create apps that handle NFC tags that are not supported by any other app.
The TECH_DISCOVERED intent filter requires a tech-list XML file in order to match any tag. Thus, your current version of this filter in your manifest will never match anything.
Calling disableForegroundDispatch() in onResume() does not make any sense. By design, the foreground dispatch could never be enabled at this point of the activity life-cycle. The reason for this is that you must not call enableForegroundDispatch() before onResume() and you are required to call disableForegroundDispatch() at latest in onPause().
In fact it does not make sense to use enableForegroundDispatch() / disableForegroundDispatch() anywhere other than in onResume() / onPause(). If you want to stop listening for tags upon other events (e.g. a pressing a button), you would simply remember your current state (process/don't process NFC events) in some flag and, when you receive a new NFC intent in onNewIntent(), you would either process or silently ignore the tag based n that flag.
Your code should not manually call activity life-cycle methods (as you currently do with onNewIntent(getIntent());).
I have an application that runs on boot up and that works great, my new problem is that my app requires an internet connection and my app gets booted up before there is an internet connect, thus I get a 404 error inside my app,
is there away to put this code below in a loop to if internet connection fails, them try the code again, like a try catch sorta thing. I am very new to java and would have no idea how to do this. Here is my code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Loop Here to test if internet connection, if not try again
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new WebViewClient());
myWebView.getSettings().setJavaScriptEnabled(true);
myWebView.loadUrl("http://example.com");
}
I have also tried the following with a try and catch by now my application will not run altogether:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Socket socket = new Socket();
InetSocketAddress address = new InetSocketAddress("www.google.com",80);
try{
socket.connect(address, 3000);
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new WebViewClient());
myWebView.getSettings().setJavaScriptEnabled(true);
myWebView.loadUrl("http://example.com");
} catch (Exception e){
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new WebViewClient());
myWebView.getSettings().setJavaScriptEnabled(true);
myWebView.loadUrl("http://example.com");
} finally {
try {socket.close();}
catch (Exception e){}
}
}
PLEASE HELP :(
And I have also been playing with this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread t = new Thread();
try{
while(!isConnected(WifiExplorerActivity.this)){
Thread.sleep(1000);
}
} catch (Exception e){
}
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new WebViewClient());
myWebView.getSettings().setJavaScriptEnabled(true);
myWebView.loadUrl("http://example.com");
}
and adding this to my Manifest:
<activity android:name=".WifiExplorerActivity" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</activity>
You better try a BroadcastReceiver :
use : either use the whole class or just call the static methods
public class NetworkManager extends BroadcastReceiver {
protected static final String TAG = NetworkManager.class.getSimpleName(); // log
protected Context mContext;
protected boolean mNoConnectivity;
protected String mReason;
protected boolean mIsFailover;
protected static boolean mIsConnected = false;
protected static boolean mIsConnectivityGood = true;
public NetworkManager(Context context) {
this.mContext = context;
}
public void registerReceivers() {
mContext.registerReceiver(this, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
public boolean isConnectingToInternet() {
ConnectivityManager connectivity = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity != null) {
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null)
for (int i = 0; i < info.length; i++)
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
return false;
}
/**
* #param context
* #return
*/
public static NetworkInfo getNetworkInfo(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo();
}
/**
* #param context
* #return
*/
public static boolean isConnected(Context context) {
NetworkInfo info = getNetworkInfo(context);
return (info != null && info.isConnected());
}
/**
* #param context
* #return
*/
public static boolean isConnectedWifi(Context context) {
NetworkInfo info = getNetworkInfo(context);
return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_WIFI);
}
/**
* #param context
* #return
*/
public static boolean isConnectedMobile(Context context) {
NetworkInfo info = getNetworkInfo(context);
return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_MOBILE);
}
/**
* #param context
* #return
*/
public static boolean isConnectedFast(Context context) {
NetworkInfo info = getNetworkInfo(context);
return (info != null && info.isConnected() && isConnectionFast(info.getType(), info.getSubtype()));
}
protected static boolean isConnectionFast(int type, int subType) {
if (type == ConnectivityManager.TYPE_WIFI) {
return true;
} else if (type == ConnectivityManager.TYPE_MOBILE) {
switch (subType) {
case TelephonyManager.NETWORK_TYPE_1xRTT:
return false; // ~ 50-100 kbps
case TelephonyManager.NETWORK_TYPE_CDMA:
return false; // ~ 14-64 kbps
case TelephonyManager.NETWORK_TYPE_EDGE:
return false; // ~ 50-100 kbps
case TelephonyManager.NETWORK_TYPE_EVDO_0:
return true; // ~ 400-1000 kbps
case TelephonyManager.NETWORK_TYPE_EVDO_A:
return true; // ~ 600-1400 kbps
case TelephonyManager.NETWORK_TYPE_GPRS:
return false; // ~ 100 kbps
case TelephonyManager.NETWORK_TYPE_HSDPA:
return true; // ~ 2-14 Mbps
case TelephonyManager.NETWORK_TYPE_HSPA:
return true; // ~ 700-1700 kbps
case TelephonyManager.NETWORK_TYPE_HSUPA:
return true; // ~ 1-23 Mbps
case TelephonyManager.NETWORK_TYPE_UMTS:
return true; // ~ 400-7000 kbps
case TelephonyManager.NETWORK_TYPE_UNKNOWN:
default:
return false;
}
} else {
return false;
}
}
#Override
public void onReceive(Context context, Intent intent) {
mNoConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
mReason = intent.getStringExtra(ConnectivityManager.EXTRA_REASON);
mIsFailover = intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false);
//
if (mNoConnectivity) {
mIsConnected = false;
} else {
if (isConnectedFast(mContext)) {
mIsConnectivityGood = true;
} else {
mIsConnectivityGood = false;
}
mIsConnected = true;
}
}
}
Its Should work:
public class SMSReceiver extends BroadcastReceiver
{
public void onReceive(Context context, Intent intent)
{
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
wifiManager.setWifiEnabled(true);//make it enabled
if(wifiManager.isWifiEnabled()){//if its enabled
//your code...
}
}
}
your should have on your manifest:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>//if you want to change it
This method works for me:
public static boolean isConnectivityOn(Context ctx) {
boolean resCode = false;
try {
ConnectivityManager cm =
(ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
resCode = cm.getActiveNetworkInfo().isConnectedOrConnecting();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return resCode;
}
Taking care having
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
in the Manifest