For an engineering project I need to basically trick my phone to come out of NFC searching mode and into a mode where the phone is continuously putting out energy. Obviously I have activated NFC in the settings, but the only way I can trick it into leaving the searching mode and have it put out energy continuously is if I leave it on top of a blank tag.
I was thinking of implementing this NFC beam function: public boolean invokeBeam (Activity activity) and implanting it into the BeamLargeFiles sample code provided in Android studio, posted below.
I'm new to app development (though I have a fair bit of coding experience) so I'm just not sure if it's feasible, or if I'm looking in the right places. Any thoughts, ideas and help is appreciated!
package com.example.android.beamlargefiles;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.text.Html;
import android.widget.TextView;
import android.view.Menu;
import com.example.android.common.activities.SampleActivityBase;
import com.example.android.common.logger.Log;
import com.example.android.common.logger.LogFragment;
import com.example.android.common.logger.LogWrapper;
import com.example.android.common.logger.MessageOnlyLogFilter;
/**
* A simple launcher activity containing a summary sample description
* and a few action bar buttons.
*/
public class MainActivity extends SampleActivityBase {
public static final String TAG = "MainActivity";
public static final String FRAGTAG = "BeamLargeFilesFragment";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView sampleOutput = (TextView) findViewById(R.id.sample_output);
sampleOutput.setText(Html.fromHtml(getString(R.string.intro_message)));
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
BeamLargeFilesFragment fragment = new BeamLargeFilesFragment();
transaction.add(fragment, FRAGTAG);
transaction.commit();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
/** Create a chain of targets that will receive log data */
#Override
public void initializeLogging() {
// Wraps Android's native log framework.
LogWrapper logWrapper = new LogWrapper();
// Using Log, front-end to the logging chain, emulates android.util.log method signatures.
Log.setLogNode(logWrapper);
// Filter strips out everything except the message text.
MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
logWrapper.setNext(msgFilter);
// On screen logging via a fragment with a TextView.
LogFragment logFragment = (LogFragment) getSupportFragmentManager()
.findFragmentById(R.id.log_fragment);
msgFilter.setNext(logFragment.getLogView());
logFragment.getLogView().setTextAppearance(this, R.style.Log);
logFragment.getLogView().setBackgroundColor(Color.WHITE);
Log.i(TAG, "Ready");
}
}
From the beamlargedata sample code provided by android studio
When no suitable NFC device is in range the NFC controller will constantly search all technologies for a tag or peer-to-peer device. It does this by sending out short bursts separated by no field activity (to save power).
If you have a newer device it is also very likely that the NFC Controller will only generate a very weak RF field to save power. This field is not strong enough to power a NFC tag but is strong enough for the chip to detect if there is something resonating at 13.56Mhz.
With standard Android you cannot change this behaviour. There is no programatical way in the API to enable the mode you're looking for.
However, if you can stretch your requirements a bit you can likely get something close to what you want.
Option 1:
Enable the Reader-Mode. Call enableReaderMode using the EXTRA_READER_PRESENCE_CHECK_DELAY extra. Set this to the a very high value.
Now, if a tag enters the RF field the NFC controller won't check for presence that often anymore. You can activate your RF field by touching a tag, then removing it.
The RF field will be stable until the presence check delay expires.
Option 2:
If rooting the device is an option, you can hack yourself into the low level NFC stack. Each NFC controller that I've worked with so far has one or more test modes for antenna calibration. Just outputting an RF field is one of the very common test modes.
Reading the source-code of the nfc-stack will likely show you how to enable such a mode. That takes some digging in the source-code and is not for the faint heart, but it is doable.
Related
I need a bit of help phrased in easy to understand terms. I've tried asking this question on multiple forums, but keep getting answers back that assume some knowledge even though I specified that I have only rudimentary skills in Android building and Java.
The user Skynet was very helpful when I asked my initial question here, but the research he/she prompted me to do proved difficult to follow up on.
https://stackoverflow.com/questions/28403243/how-to-make-an-app-that-syncs-via-internet
I want to make an app with a textview that updates via internet everytime the user open the app.
What is the best way to do this? And what would I have to do to do it?
Thank you in advance!
To get an idea of how new to this I am, here's an app I've published: https://play.google.com/store/apps/details?id=theveshtheva.debatebreaker
EDIT: I'm trying something but it doesn't seem to work. Could someone tell me what I'm doing wrong?
The webpage I'm trying to pull data from is here:
http://ktjdaily.blogspot.com/2015/02/menu-of-day.html
Here's my activity java file:
package theveshtheva.practice;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import android.widget.TextView;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
public class onlinetext extends ActionBarActivity {
private String HTML;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_onlinetext);
/*FROM HERE*/
TextView outtext = (TextView) findViewById(R.id.textView);
try {
getHTML();
} catch (Exception e) {
e.printStackTrace();
}
outtext.setText("" + HTML);
/*TO HERE*/
}
private void getHTML() throws IOException
{
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet("http://ktjdaily.blogspot.com/2015/02/menu-of-day.html"); //URL!
HttpResponse response = httpClient.execute(httpGet, localContext);
String result = "";
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line;
while ((line = reader.readLine()) != null) {
result += line + "\n";
HTML = result;
}
}
#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_onlinetext, 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.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
And here's the Manifest file, where I've set permissions:
<?xml version="1.0" encoding="utf-8" ?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="theveshtheva.practice">
<uses-permission android:name="android.permission.INTERNET" />
<application android:allowBackup="true" android:icon="#drawable/ic_launcher" android:label="#string/app_name" android:theme="#style/AppTheme">
<activity android:name=".onlinetext" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
There are HTTP apis already in Android that do this. There's like an Earthquake monitor sample application that pulls XML via HTTP in a background service.
Start there.
I feel like there is a lot of questions on how to sync android apps with online services or backend systems in general. So basically, I will try to expose here some ways you may have of doing so and I will try to keep it as simple as possible:
1)The world outside your mobile application
Ok, so you want to make an app that sends and retrieves information from through the internet...fine! But first of all, before even thinking about your app, have you thought about your server? the online service that holds the info your app should manipulate? So, yes! Your server/service should be ready and working when you start to think about writing an application that will do any online sync. By the way, a reasonable advice would be to start facing the term "application" as your whole service environment , including mobile apps and everything, not just one single mobile application per say.
If you have your own online service good to go or you just need to use 3rd party online services that are also ready, then that's the end of step 1.
2)Communicating with the outside world
Here you already have your functional online service. Now you need to set ways of communicating with it. Think as the "communication part" as a different project. Don't think it as just a bridge between your mobile app and your backend system. Think it as a bridge for any application from any environment to your system. A unique way that apps can reach your system and your system can reach them, exchanging valuable information for what they concern. We have some options here, but I will stick with the RESTApi. I won't describe here what is a RESTApi and how you actually write code around it(I guess that must be one of your biggest concerns), because someone already did in this epic SO question.
What you really need to understand here is the whole concept and then later you can checkout some frameworks(there are a lot) to actually implement it(you'll see that is the easiest part). To end the step 2, here is a REALLY simple diagram to show it (not the best, I know):
3) Finally, your android app
As using RESTApi , we're going to handle http requests. In order to do so, we have many ways of doing it in our android application. I will provide some code using the built-in HttpClient for better understanding : RestClient.java . This class is a real basic rest client that will do POST and GET http requests by just:
RestClient client = new RestClient();
client.execute("http://youronlineservice.com:3430/api/somegetrequest",RequestMethod.GET);
client.execute("http://youronlineservice.com:3430/api/somepostrequest",RequestMethod.POST);
Now, when dealing with the android environment, be careful with NetworkOnMainThreadException:
The exception that is thrown when an application attempts to perform a networking operation on its main thread.
Therefore, I strong recommend the use of AsyncTask when dealing with simple http requests, because:
AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
AsyncTask is designed to be a helper class around Thread and Handler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent package such as Executor, ThreadPoolExecutor and FutureTask.
An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called onPreExecute, doInBackground, onProgressUpdate and onPostExecute.
For ending, as you may be wondering, when you do a http request for your api you have to handle the response that will come. As you will figure out, there will be various types you can treat responses depending on the format you designed your api to work.
Mainly, you'll probably work with XML or JSON. But don't worry! There are plenty of stuff on how working with these formats in your android applications, including some awesome frameworks that you better discover yourself to see what fits you best.
After you're done with this, you may want to check some other stuff to increase the sync experience in your app, such as:
http://developer.android.com/training/sync-adapters/creating-sync-adapter.html
http://developer.android.com/reference/android/app/Service.html
And keep in mind that the best references you can get are here: http://developer.android.com/training/index.html
Hope it can help you and others!
I have two issues with this, my very first android app. The first is that I noticed after I installed the app the battery started draining about twice as fast as before. I read an article on this that stated sometimes programmers make an error which causes this. This being my first app, the probability is pretty high that this is the case.
The second issue is that I can save my variables when the app is turned off, but when the phone is turned off the data is lost.
As for the code, it's mostly bits and pieces from stuff I've found online and tried to incorporate. It's a simple calculator with three variables. Ideally, I'd like to store b and c, but allow the user to overwrite them. Variable a will change with each use, so no need to store that.
Here's my Main:
package com.kwagz.calc;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
String g, e;
String b; //changed(sorry)
String c; //changed
SharedPreferences sh_Pref;
Editor toEdit;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadSavedPreferences();
}
public void calculateClickHandler(View view) {
if (view.getId() == R.id.button1) {
EditText a = (EditText)findViewById(R.id.a);
EditText b = (EditText)findViewById(R.id.b);
EditText c = (EditText)findViewById(R.id.c);
TextView output = (TextView)findViewById(R.id.textView9);
double gp = Double.parseDouble(a.getText().toString());
int ab = Integer.parseInt(b.getText().toString());
int ac = Integer.parseInt(c.getText().toString());
double t = ((gp / ab) * ac);
output.setText(String.format("%.2f", t));
}
}
public void sharedPreferences() {
SharedPreferences saved_values =//there's no linebreak here in my code
PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
SharedPreferences.Editor editor=saved_values.edit();
editor.putString("b", b);
editor.putString("c", c);
editor.commit();
}
private void loadSavedPreferences() {
SharedPreferences saved_values =//there's no linebreak here in my code
PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
b = saved_values.getString("b", g);
}
}
From reading what you said, the only logical explanation forming in my head is: You are starting background service from your App, while background service is running it makes app run all the time which explains why variables are stored until phone is turned off (when background service gets killed).
Okay, let's take your questions one at a time. The battery problem could be a number of things, without knowing more details about your program I couldn't possibly diagnose it completely. Android does have some good power saving tips. The key item is to minimize the use of connectivity devices to no more than is required. The two biggest culprits are GPS and Internet connections. If your app isn't running, then the only way it could be running the batteries is if there's threads in the background, or maybe something like an AlarmService.
You are using SharedPreferences correctly, the value should be saved, but I think you should but the saving code in onSaveInstanceState(). If you do that, it should work fine.
EDIT
Upon closer inspection, you're fundementally saving the wrong thing. You should save the value of the EditText, not the EditText itself. In fact, I'd simply remove all references to String a,b,c, move the EditText definitions to the top to replace them, and do something like this:
editor.putString("b", b.getText().toString());
b.setText(saved_values.getString("b", g));
I've conducted several tests in an effort to recreate the issue, with no success. I'm still working on the sharedPreferences thing, but the battery drain (I suspect) was caused by another app which just happened to coincide with the installation of mine.
As I mentioned in my note to arleitiss, my Y!Mail was showing the highest amount of battery drain. A day or two after posting the note my account started acting up and then became "inactive". Once I reset it, the app no longer appears on the Battery list.
Thanks for all the input!
Is it possible to capture MMI result in Android?
I need to do things like put on hold, merge calls, etc. and as the only telephony events in android are NEW_OUTGOING_CALL, RINGING, OFFHOOK and IDLE, I need to get the result when i dial any MMI code like Held Code.
Is it possible?
The best solution for me would be to find some way to discover when an outgoing call gets actually connected. Maybe has somebody find any workaround for that?
I made some progress in that question reading system logs (LogCat) and searching for determinate strings, but it seems that logs differs between models and SO versions so this is not a consistent aproach.
Thanks for your help!
Maybe you can get it using RIL(Radio Interface Layer)
try something like:
1) adb device shell
2) logcat -b radio
// Navigate to the page that you have dial *#06# in dialpad then execute jar below to get the IMEI result
import com.android.uiautomator.core.UiObject;
import com.android.uiautomator.testrunner.UiAutomatorTestCase;
import com.android.uiautomator.core.UiSelector;
import com.android.uiautomator.core.UiObjectNotFoundException;
import com.android.uiautomator.core.UiScrollable;
import android.util.Log;
public class SIM_Info_Reader_png extends UiAutomatorTestCase{
public void getPromptedIMEI() throws UiObjectNotFoundException {
UiObject list = new UiObject(new UiSelector().resourceId("android:id/text1"));
int i = 0;
System.out.println("IMEI=" + list.getText());
}
}
I am completely new to android, and pretty much a Java newb.
I have a simple app that I am building to get the hang of android's development environment - and things like click events, etc..
The app loads, and I am able to change the text in a textfield using a button handler. However, when I import the location class, and try to do a simple GPS call, the application crashes.
The problem is, everything looks good in Eclipse (error console) - and I'm not seeing any exceptions in the android emulator (DevTools). I have the logcat window open, but I haven't done anything in eclipse/code to send logcat anything (do I need to?)
Can anyone see something wrong with this? Is there a better way to troubleshoot?
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.*;
import android.location.*;
public class locationDisplay extends Activity {
private EditText text;
private Location GPSLocation;
double dblLat;
double dblong;
String strLat;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); // bind the layout to the activity
text = (EditText) findViewById(R.id.EditText01);
text.setText("No button pressed");
}
// Handler for each button -- Button01 is when it crashes
public void myClickHandler(View view) {
switch (view.getId()) {
case R.id.Button01:
dblLat = GPSLocation.getLatitude();
strLat = Double.toString(dblLat);
text.setText(strLat);
break;
case R.id.Button02:
text.setText("Button 2 was clicked");
break;
case R.id.Button03:
text.setText("Button 3 was clicked");
break;
}
}
You shouldn't need to write anything to get the default messages in LogCat; uncaught exception reports should appear automatically when your program crashes. However, sometimes LogCat and your emulator get disconnected from each other and the messages simply all disappear. Simply close Eclipse and the emulator, restart them both, and the messages should reappear. An easy way to tell whether the link has been re-established is during the boot-up of the emulator. Just as the flashing "ANDROID" text in the fancy font disappears bringing you to the lockscreen, you should see about a hundred lines of text flash by on LogCat. If that doesn't happen, then LogCat isn't getting its messages.
The way to display debugging messages in Android is to use the Log.d("some name for your log statements so you can filter the LogCat messages", "The actual debug statement here");. You'll often find people using things like a static final String LOG_TAG in their application so that they can make sure their logs always have the same tag, and hence, the filter never misses a message.
As for your actual code here, Rpond is right, you never initialised your GPSLocation object.
You GPSLocation object is null. You need to access the LocationService to get a current location. And with the emulator you will need to manually send locations.
Location Services
Sometimes LogCat 'forgets' you have a device/emulator connected and running. It seems like this happens after you have a device and an emulator online at the same time and then you disconnect one of them. If you are getting nothing from LogCat, go to Window>Show View>Other>Devices and then click the device that you want to log.
I'm developing an application for the android OS, I'm just starting, but I can't get the GPS on the emulator to work.
I've read on the internet that you need to send a geo fix to the emulator in order to enable the gps locationProvider. I'm both using the DDMS and telnet to try to send it, but logcat never tells me the it recived a new fix, and my apolication still sees the gps as disabled
here's my code
package eu.mauriziopz.gps;
import java.util.Iterator;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
public class ggps extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LocationManager l =(LocationManager) getSystemService(Context.LOCATION_SERVICE);
List<String> li = l.getAllProviders();
for (Iterator<String> iterator = li.iterator(); iterator.hasNext();) {
String string = iterator.next();
Log.d("gps", string);
}
if (l.getLastKnownLocation("gps")==null)
Log.d("gps", "null");
}
}
I've read that the DDMS may not work properly on a non english OS, but telnet should work!
update: the gps is enabled in the settings
Turns out, that since I was developing for Android 1.5 (and not Google API 1.5) the map (and looks like other features) were disabled.
As soon as I changed the target platform, my error disappeared.
btw thanks all
To test if the geofix is working you could use the Google Maps app with "My Location"
Make sure that the gps in enabled in the settings. If still the problem persists, you just go to the application named Navigation in the main menu, run it and exit. Now try your application.
You can enable location controls under emulator control in DDMS perspective by selecting a particular device. without selecting a device it will not work
I supose is fixed yet, but in the code you should use as provider a string returned by the LocationManager service, instead of "gps" as you put in l.getLastKnownLocation("gps").