I have a little problem... I have made an Android application which extends the webview. The webview Html page with a map on like this: Map example, it was also here I got my inspiration. My onCreate method looks like this:
super.onCreate(savedInstanceState);
//Removes the title bar in the application
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
//Creation of the Webview found in the XML Layout file
browserView = (WebView)findViewById(R.id.webkit);
//Removes both vertical and horizontal scroll bars
browserView.setVerticalScrollBarEnabled(false);
browserView.setHorizontalScrollBarEnabled(false);
myLocationManager=(LocationManager)getSystemService(Context.LOCATION_SERVICE);
//Enable Javascripts
url = "http://www.my-homepage.dk/map_example.html";
browserView.getSettings().setJavaScriptEnabled(true);
//The website which is wrapped to the webview
browserView.loadUrl(url);
So when My application gets a GPS location, it invokes this method:
LocationListener onLocationChange=new LocationListener() {
public void onLocationChanged(Location location) {
StringBuilder buf=new StringBuilder(url);
buf.append("?");
buf.append("lon=");
buf.append(String.valueOf(location.getLongitude()));
buf.append("&");
buf.append("lat=");
buf.append(String.valueOf(location.getLatitude()));
browserView.loadUrl(buf.toString());
}
So it basically just loads another URL.... But, my problem is, 1. it keeps the orignal website "map image", i imagined it would "unload" the page, and 2. When the second url is loaded, it takes quite a long time before it is finished, and when i am testing on my HTC Desire, it sometimes doesnt show the second loaded page (the map with location) before it turns the screen off and lock, or if i go out and in the application, that sometimes helps too...
Hope you can help :)
A suggestion - in onLocationChanged, make locationFound(); the first statement instead of the last.
It would be good to stop the listener immediately, as the loadUrl statement could take some time to complete, while the provider could be sending more updates.
Here is the solution... The GPS listener apparently broadcast more than once ;) so, when the GPS finds a location it loads the url and then stops broadcasting.
So the problem before was, that it sent loads of URL's to the html page, and therefore never just loaded 1 single url. And i just simplified the onLocationChanged a bit.
public void locationFound(){
myLocationManager.removeUpdates(this);
}
#Override
public void onLocationChanged(Location location) {
String lon = "lon="+String.valueOf(location.getLongitude());
String lat = "lat="+String.valueOf(location.getLatitude());
browserView.loadUrl(url+"?"+lon+"&"+lat);
locationFound();
}
Here is the SourceCode for the application:
package com.webview;
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Window;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class WebViewTest extends Activity implements LocationListener{
private WebView browserView;
private static String PROVIDER="gps";
private LocationManager myLocationManager=null;
private String url;
private boolean LocFound = false;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Removes the title bar in the application
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
//Creation of the Webview found in the XML Layout file
browserView = (WebView)findViewById(R.id.webkit);
//Removes both vertical and horizontal scroll bars
browserView.setVerticalScrollBarEnabled(false);
browserView.setHorizontalScrollBarEnabled(false);
myLocationManager=(LocationManager)getSystemService(Context.LOCATION_SERVICE);
//Enable Javascripts
url = "http://www.test.dk/test.html";
browserView.getSettings().setJavaScriptEnabled(true);
//The website which is wrapped to the webview
browserView.loadUrl(url);
}
#Override
public void onResume() {
super.onResume();
myLocationManager.requestLocationUpdates(PROVIDER, 0,
0,
this);
}
#Override
public void onPause() {
super.onPause();
myLocationManager.removeUpdates(this);
}
public void locationFound(){
myLocationManager.removeUpdates(this);
}
#Override
public void onLocationChanged(Location location) {
String lon = "lon="+String.valueOf(location.getLongitude());
String lat = "lat="+String.valueOf(location.getLatitude());
browserView.loadUrl(url+"?"+lon+"&"+lat);
locationFound();
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
}
Related
I am trying to use a code from this link https://developer.android.com/training/connect-devices-wirelessly/nsd.html
"from Discover Services on the Network."
I copy and paste code as the following:
import android.net.nsd.NsdManager;
import android.net.nsd.NsdServiceInfo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button aButton = (Button) findViewById(R.id.MyButton);
aButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// there is an error in the next line, ";" expected.
// but I do not know where to put ; exactly
public void initializeRegistrationListener() {
mRegistrationListener = new NsdManager.RegistrationListener() {
#Override
public void onServiceRegistered(NsdServiceInfo NsdServiceInfo) {
// Save the service name. Android may have changed it in order to
// resolve a conflict, so update the name you initially requested
// with the name Android actually used.
mServiceName = NsdServiceInfo.getServiceName();
}
#Override
public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
// Registration failed! Put debugging code here to determine why.
}
#Override
public void onServiceUnregistered(NsdServiceInfo arg0) {
// Service has been unregistered. This only happens when you call
// NsdManager.unregisterService() and pass in this listener.
}
#Override
public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
// Unregistration failed. Put debugging code here to determine why.
}
};
} }
});
}
}
But there is an error in the this Line "public void initializeRegistrationListener()", ";" expected. but I do not know where to put ";" exactly or there is something else wrong that I cannot see it, can someone guide me, please?
PS: I am trying to make my phone discovers Mdns service that I created on my laptop using javascript, I have no experience in Java but I need to run the previous code to test the service that I have created already.
First of all you need an xml that contains an Button(this button will have android:id="#+id/mybutton", and that's the id you have to use on findViewById(R.id.mybutton).
In onCreate method of your activity you will write that code that you showed us, and you are good to go.
Another small step, if you wrote your own xml, make sure to have this line in onCreate
setContentView(R.layout.yourxml)
In an android application that I am developing Im using a thread, and to make sure I dont get the "java.lang.IllegalStateException: System services not available to Activities before onCreate()" I use a boolean called donecreate. Problem is that Android studio says I have a "java.lang.NullPointerException at picLoop.run(picLoop.java:24)"
Code main class:
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.media.AudioManager;
import android.os.Bundle;
import android.view.Display;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;
public class main extends Activity {
public Boolean donecreate;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(new eyeCanvas(this));
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
docreate();
}
public void docreate(){
donecreate = true;
}
public void checkHead(){
AudioManager am = (AudioManager)getSystemService(AUDIO_SERVICE);
if(am.isWiredHeadsetOn()){
Toast.makeText(getApplicationContext(), "HEADPHONES", Toast.LENGTH_LONG).show();
}
}
}
Code: pic loop
import android.graphics.Canvas;
//**Threading
public class picLoop extends Thread {
private eyeCanvas eye;
private main main = new main();
public picLoop(eyeCanvas eye) {
this.eye = eye;
}
#Override
public void run(){
Canvas c = null;
while(true) {
if(main.donecreate){ //<-- where error is
main.checkHead();
}
try {
// head.onCreate(Bundle savedInstanceState);
c = eye.getHolder().lockCanvas();
synchronized (eye.getHolder()) {
eye.onDraw(c);
}
} finally {
if (c != null) {
eye.getHolder().unlockCanvasAndPost(c);
}
}
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Also if you guys could give me feedback on how I submitted, It would help :)
You can't create activities like you're trying to do. You can NEVER EVER do 'new Activity()', as the activity needs to be launched by the system to get set up properly and go through its lifecycle as intended.
So remove the line private main main = new main();.
To do what you're trying, make the boolean a static variable.
Change
public Boolean donecreate;
to
public static Boolean donecreate;
Then you can access it like you're trying to do, without creating an instance of main Activity.
There are a large number of things wrong with the assumptions you're making. Firstly, if your Thread requires your Activity to be created, don't start it until your Activity is created. Manage the lifecycle of this object within the Activity itself, i.e.:
#Override
public void onStart() {
super.onStart();
// Start your work here
}
#Override
public void onStop() {
super.onStop();
// Stop your work here
}
Secondly, please don't use the static access approach being recommended -- that makes the assumption that there is only one Activity instance (which is wrong immediately on a configuration change, and/or if you start another instance of that Activity in the task). And even if that assumption were true, you would need to set it back to false in onDestroy() (still, don't do that).
try setting donecreate to false initially
public class main extends Activity {
public Boolean donecreate = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
....
You can request system service on application context, look at this answer.
So create a static variable in application class, initialize it like instance = this; in onCreate of Application class and then you'll be able to get app context whenever you want.
I am trying to write a simple app that takes the users current location and notifies them when they come near this location later. In my code I have it set up so that when the app starts it starts requesting location updates. Then when the button is pressed it takes the last known location and creates a proximity alert around that. my problem however is that when i press the button on both the emulator and the real phone it quickly crashes and i cant seem to find a reason why. is there an infinite loop i am some how missing? if there is a way to see the error messages from my phone that would also be very helpful.
Here is my code:
MainActivity.java
package com.YdidApplications.shotgun;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.Toast;
public class MainActivity extends Activity implements LocationListener
{
private ImageButton flagButton;
LocationManager lm;
double lat=0,long1=0; //Defining Latitude & Longitude
float radius=5; //Defining Radius
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lm=(LocationManager) getSystemService(LOCATION_SERVICE);
lm.requestLocationUpdates(lm.GPS_PROVIDER,
10000, //Update every 10 sec
10, (LocationListener) this);
flagButton = (ImageButton) findViewById(R.id.FLAG);
onFlagPress();
}
public void onFlagPress()
{
flagButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
location();
}
});
}
public void location()
{
lm=(LocationManager) getSystemService(LOCATION_SERVICE);
lm.getLastKnownLocation(LOCATION_SERVICE);
Intent i= new Intent("com.adnan.proximityalert"); //Custom Action
PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), -1, i, 0);
lm.addProximityAlert(lat, long1, radius, -1, pi);
}
#Override
public void onLocationChanged(Location location) {
lat= location.getLatitude();
long1 = location.getLongitude();
Toast.makeText(null, lat+", "+long1, 0);
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
}
ProximityReciever.java
package ProximityReciever;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.LocationManager;
import android.widget.Toast;
/*This is the Reciever for the Brodcast sent, here our app will be notified if the User is
* in the region specified by our proximity alert.You will have to register the reciever
* with the same Intent you broadcasted in the previous Java file
*
* #Author: Adnan A M
*/
public class ProximityReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
// The reciever gets the Context & the Intent that fired the broadcast as arg0 & agr1
String k=LocationManager.KEY_PROXIMITY_ENTERING;
// Key for determining whether user is leaving or entering
boolean state=arg1.getBooleanExtra(k, false);
//Gives whether the user is entering or leaving in boolean form
if(state){
// Call the Notification Service or anything else that you would like to do here
Toast.makeText(arg0, "Welcome to my Area", 600).show();
}else{
//Other custom Notification
Toast.makeText(arg0, "Thank you for visiting my Area,come back again !!", 600).show();
}
}
}
Any advise would be greatly appreciated.
Thanks,
Logan
Google has an example on analytic data for mobile devices. The code is provided here. I added the jar file and everything compiles fine, but I get an error up running the app.
I took out the UA ID for security reasons (not sure if that matters or not)
LogCat provides me with this information:
E/AndroidRuntime(1175): java.lang.NoClassDefFoundError: com.google.android.apps.analytics.GoogleAnalyticsTracker
AND
E/AndroidRuntime(1130):at com.google.android.apps.analytics.sample.TestActivity.onCreate(TestActivity.java:19)
From what it says, it can't find the googleAnalyticTracker? But if it compiles fine why can't it find it?
package com.google.android.apps.analytics.sample;
import com.google.android.apps.analytics.GoogleAnalyticsTracker;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class TestActivity extends Activity {
GoogleAnalyticsTracker tracker;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tracker = GoogleAnalyticsTracker.getInstance();
// Start the tracker in manual dispatch mode...
// tracker.startNewSession("", this);
// ...alternatively, the tracker can be started with a dispatch interval
// (in seconds).
tracker.startNewSession("", 20, this);
setContentView(R.layout.main);
Button createEventButton = (Button) findViewById(R.id.NewEventButton);
createEventButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
tracker.trackEvent("Clicks", // Category
"Button", // Action
"clicked", // Label
77); // Value
}
});
Button createPageButton = (Button) findViewById(R.id.NewPageButton);
createPageButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// Add a Custom Variable to this pageview, with name of "Medium"
// and value "MobileApp"
tracker.setCustomVar(1, "Medium", "Mobile App");
// Track a page view. This is probably the best way to track
// which parts of your application
// are being used.
// E.g.
// tracker.trackPageView("/help"); to track someone looking at
// the help screen.
// tracker.trackPageView("/level2"); to track someone reaching
// level 2 in a game.
// tracker.trackPageView("/uploadScreen"); to track someone
// using an upload screen.
tracker.trackPageView("/testApplicationHomeScreen");
}
});
Button quitButton = (Button) findViewById(R.id.QuitButton);
quitButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
Button dispatchButton = (Button) findViewById(R.id.DispatchButton);
dispatchButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// Manually start a dispatch, not needed if the tracker was
// started with a dispatch
// interval.
tracker.dispatch();
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
// Stop the tracker when it is no longer needed.
tracker.stopSession();
}
}
I too had the same problem after I updated my android SDK. I resolved it by doing the following:
Right Click on your project -> Build Path -> Configure Build Path -> Select Order and Export Tab -> Check the GoogleAnalyticsJar.jar -> Press OK.
This helped me resolve the problem. Hope it helps you also.
Create alalytics.xml in your your layout folder and paste the following code.
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<!--Replace placeholder ID with your tracking ID-->
<string name="ga_trackingId">UA-XXXX-Y</string>
<!--Enable automatic activity tracking-->
<bool name="ga_autoActivityTracking">true</bool>
<!--Enable automatic exception tracking-->
<bool name="ga_reportUncaughtExceptions">true</bool>
</resources>
Create Helper.java class and paste the following code.
import android.content.Context;
import com.google.analytics.tracking.android.EasyTracker;
import com.google.analytics.tracking.android.Fields;
import com.google.analytics.tracking.android.MapBuilder;
import com.google.analytics.tracking.android.Tracker;
import com.google.tagmanager.DataLayer;
import com.google.tagmanager.TagManager;
public class Helper{
/**
* Push an "openScreen" event with the given screen name. Tags that match that event will fire.
*/
private static Tracker tracker;
public static void pushOpenScreenEvent(Context context, String screenName) {
// Instantiate the Tracker
tracker = EasyTracker.getInstance(context);
tracker.set(Fields.SCREEN_NAME, screenName);
// Send a screenview.
tracker.send(MapBuilder
.createAppView()
.build()
);
}
/**
* Push an "Button clicked" event with the given screen name. Tags that match that event will fire.
*/
public static void pushbtnClickedEvent(Context context, String clickE) {
tracker = EasyTracker.getInstance(context);
// Values set directly on a tracker apply to all subsequent hits.
tracker.set(Fields.SCREEN_NAME, "Home Screen");
// This screenview hit will include the screen name "Home Screen".
tracker.send(MapBuilder.createAppView().build());
// And so will this event hit.
tracker.send(MapBuilder
.createEvent("UI", "click", "my btn clicked", null)
.build()
);
}
/**
* Push a "closeScreen" event with the given screen name. Tags that match that event will fire.
*/
public static void pushCloseScreenEvent(Context context, String screenName) {
// Instantiate the Tracker
tracker = EasyTracker.getInstance(context);
tracker.set(Fields.SCREEN_NAME, screenName);
// Send a screenview.
tracker.send(MapBuilder
.createAppView()
.build()
);
}
}
MainActivity.java
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.google.analytics.tracking.android.EasyTracker;
public class MainActivity extends Activity {
Button btnClickEvent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnClickEvent=(Button)findViewById(R.id.button1);
btnClickEvent.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Helper.pushbtnClickedEvent(MainActivity.this, "Button Clicked");
}
});
}
#Override
protected void onStart() {
super.onStart();
EasyTracker.getInstance(this).activityStart(this);
Helper.pushOpenScreenEvent(this, "Main Activity");
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
EasyTracker.getInstance(this).activityStop(this); // Add this method
}
}
Now,your application is ready ,simply press the "Button" then,open your Google analytics dashboard.
Dont forget to add these permissions in manifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Refered from:http://velmuruganandroidcoding.blogspot.in/2014/08/google-analytics-in-android.html
I followed http://developer.android.com/guide/topics/location/obtaining-user-location.html and this worked fine when being in the activity in the onCreate-method.
Then I wanted to outsource this functionality in a separate class called LocationHelper.
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
public class LocationHelper {
public Context mContext;
public Location loc;
public LocationHelper (Context mContext){
this.mContext = mContext;
// Acquire a reference to the system Location Manager
LocationManager locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
setLocation(location);
}
public void onStatusChanged(String provider, int status, Bundle extras) {}
public void onProviderEnabled(String provider) {}
public void onProviderDisabled(String provider) {}
};
// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
}
public void setLocation(Location location) {
this.loc = location;
}
public Location getLocation() {
return this.loc;
}
}
In the activity I do this; basically I want to pull (for testing purposes!) the GPS coordinates from my helper class and display it. Problem being, the location always is null.
public class GraffitiWall extends Activity {
private TextView tv;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv = new TextView(this);
LocationHelper gpsie = new LocationHelper(this);
while (true){
makeUseOfNewLocation(gpsie.getLocation());
}
}
public void makeUseOfNewLocation(Location loc){
if (loc == null){return;}
tv.setText("" + loc.getLatitude());
setContentView(tv);
}
}
What am I missing and doing wrong?
Putting an infinite loop in your onCreate method is a bad idea. Your problem is most likely being caused because onCreate is never completing and passing control back to the OS. I wouldn't be surprised if this caused Force Close errors.
Maybe what you need to do is create a service which will do your location monitoring and update your activity from there.