React Native: write in AsyncStorage with java - java

So I have this text on the java-side that arrives from an Intent, which I'd like to save to AsyncStorage to being able to access it through React afterwards.
Any chance I can achieve this?
I have:
package com.myapp;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.content.Intent;
import com.facebook.react.LifecycleState;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactRootView;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler {
private ReactInstanceManager mReactInstanceManager;
private ReactRootView mReactRootView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.addPackage(new MainReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
mReactRootView.startReactApplication(mReactInstanceManager, "BrowseItLater", null);
setContentView(mReactRootView);
// This code is from http://developer.android.com/training/sharing/receive.html
Intent intent = getIntent();
String action = intent.getAction();
String type = intent.getType();
if (Intent.ACTION_SEND.equals(action) && type != null) {
handleSendText(intent);
}
}
void handleSendText(Intent intent) {
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
if (sharedText != null) {
// How can I handle this ????
}
}
// ...
}
Or is there any other solution to make MainActivity.java communicate with JS?

After quite some fight I finally found a solution. It doesn't use AsyncStorage as I read in the source code AsyncStorage could actually be located differently (SQLite, or something else) depending on the phone. Would be dirty to duplicate this logic.
Instead, I created a module like the doc suggests and passed the inputText as an argument to the .addPackage(new EphemeralStoragePackage(inputText)) call in MainActivity.java.
The module exposes a method readOnceAsync to the JS world, which I can later call with:
NativeModules.EphemeralStorage.readOnceAsync((text :string) => {
if (text.length) {
this._addValue(text); // this method is in charge of storing in AsyncStorage
}
})
Here's the detail:
// android/app/src/main/java/com/appname/modules/ephemeralstorage/EphemeralStorageModule.java
package com.browseitlater.modules.ephemeralstorage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;
import java.util.Map;
public class EphemeralStorageModule extends ReactContextBaseJavaModule {
private String inputText;
public EphemeralStorageModule(ReactApplicationContext reactContext, String _inputText) {
super(reactContext);
this.inputText = _inputText;
}
#Override
public String getName() {
return "EphemeralStorage";
}
public String getInputText() {
return inputText;
}
#ReactMethod
public void readOnceAsync(Callback successCallback) {
successCallback.invoke(getInputText());
this.inputText = null;
}
}
And
// android/app/src/main/java/com/appname/modules/ephemeralstorage/EphemeralStoragePackage.java
package com.browseitlater.modules.ephemeralstorage;
import android.app.Activity;
import java.util.*;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
public class EphemeralStoragePackage implements ReactPackage {
private String inputText;
public EphemeralStoragePackage(String _inputText) {
super();
this.inputText = _inputText;
}
#Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new EphemeralStorageModule(reactContext, getInputText()));
return modules;
}
#Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
#Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
public String getInputText() {
return inputText;
}
}
Finally in MainActivity.java, my onCreate method looks like:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactRootView = new ReactRootView(this);
Intent intent = getIntent();
String action = intent.getAction();
String type = intent.getType();
String inputText = intent.getStringExtra(Intent.EXTRA_TEXT);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.addPackage(new MainReactPackage())
.addPackage(new EphemeralStoragePackage(inputText))
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
mReactRootView.startReactApplication(mReactInstanceManager, "BrowseItLater", null);
setContentView(mReactRootView);
}

If you don't want to write a native module, you can do this in MainActivity.java
Declare a global variable inside MainActivity class (don't forget to import com.facebook.react.modules.storage.ReactDatabaseSupplier):
private ReactDatabaseSupplier mReactDatabaseSupplier;
Inside onCreatemethod initialize the global variable:
mReactDatabaseSupplier = ReactDatabaseSupplier.getInstance(getApplicationContext());
Declare a private method to save the key/value pair inside AsyncStorage
private void saveKeyValuePair(String key, String value) {
String sql = "INSERT OR REPLACE INTO catalystLocalStorage VALUES (?, ?);";
SQLiteStatement statement = mReactDatabaseSupplier.get().compileStatement(sql);
try {
mReactDatabaseSupplier.get().beginTransaction();
statement.clearBindings();
statement.bindString(1, key);
statement.bindString(2, value);
statement.execute();
mReactDatabaseSupplier.get().setTransactionSuccessful();
} catch (Exception e) {
Log.w("YOUR_TAG", e.getMessage(), e);
} finally {
try {
mReactDatabaseSupplier.get().endTransaction();
} catch (Exception e) {
Log.w("YOUR_TAG", e.getMessage(), e);
}
}
}
Then you can save key/value pairs like this (inside onCreate, for example):
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactDatabaseSupplier = ReactDatabaseSupplier.getInstance(getApplicationContext());
saveKeyValuePair("myAsyncStorageKey", "myValueInAsyncStorageKey");
}
This is a simple way to save in AsyncStorage of a React Native application. Consider writing a native module.

Related

How can I populate a ListView on a SecondActivity with data from FirstActivity in Android?

I'm working on a book-searching app project. The user enters a title, and the app searches Google Books for it.
I initially had one activity and layout. I decided to use two layouts (one for user to enter title, and the other displays results); had to create another activity because the results layout was throwing an exception about 'null' object reference.
After creating the second activity, I used an intent to transfer List data between the two activities; no sooner did I find out that I had to use a Serialize or Parcelable object for the purpose.
Following instructions at Pass list of objects from one activity to other activity in android & https://www.vogella.com/tutorials/AndroidParcelable/article.html, I failed at implementing both, because Serialize sent an empty ArrayList (thus, an empty results page, even though there're book hits) and Parcelable was throwing out different exceptions everytime I used it, probably because I'm using an ArrayAdapter to populate the ListView with books.
I don't think I'm ready to implement the API at https://www.vogella.com/tutorials/AutoValue/article.html and can't use Fragments as well. A better structure would be to use a single activity, View.GONE the background image I so much cherish, and display list of book objects under the search field. But it would be good to make a follow-up on Serialize & Parcelable -- for future projects.
So, fellow developers, what's the solution to this?
FirstActivity screenshot
SecondActivity screeenshot
Here's my code:
MainActivity:
package project.android.gbookslisting;
import android.app.LoaderManager;
import android.content.Intent;
import android.content.Loader;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import androidx.appcompat.app.AppCompatActivity;
import static project.android.gbookslisting.ResultsActivity.adapter;
//import android.support.v4.content.AsyncTaskLoader;
//import android.support.v7.app.AppCompatActivity;
public class ParamsActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<Book>>, Serializable {
private static final int LOADER_ID = 0;
private static String LOG_TAG = ParamsActivity.class.getName();
EditText text;
String query;
private LoaderManager loaderManager = getLoaderManager();
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.parameters);
Button query = findViewById(R.id.search_button);
text = findViewById(R.id.deets_field);
query.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick (View view) {
if (text.getText().toString().length() > 0) { loaderManager.initLoader(LOADER_ID, null, ParamsActivity.this);
} else if (text.getText().length() < 1) {
text.setHint("Please enter book title/details");
text.setHintTextColor(Color.RED);
}
}
});
}
#Override
public Loader<List<Book>> onCreateLoader (int i, Bundle bundle) {
query = text.getText().toString();
return new BookLoader(this, query);
}
#Override
public void onLoadFinished (Loader<List<Book>> loader, List<Book> data) {
// If there is a valid list of {#link Book}s, then add them to the adapter's dataset. This will trigger the ListView to update.
if (data != null && !data.isEmpty()) {
data = new ArrayList<Book>();
Intent i = new Intent(getApplicationContext(), ResultsActivity.class);
i.putExtra("data", (Serializable) data);
startActivity(i);
}
}
#Override
public void onLoaderReset (Loader loader) {
adapter = new Adapt(this, new ArrayList<Book>());
adapter.clear();
}
}
SecondActivity:
package project.android.gbookslisting;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import java.io.Serializable;
import java.util.ArrayList;
import androidx.appcompat.app.AppCompatActivity;
public class ResultsActivity extends AppCompatActivity implements Serializable {
static Adapt adapter;
static TextView emptyResult;
ListView bookEntries;
String LOG_TAG = ResultsActivity.class.getName();
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hits_page);
Intent i = getIntent();
ArrayList<Book> books = (ArrayList<Book>) i.getSerializableExtra("data");
emptyResult = findViewById(R.id.matches_nill);
emptyResult.setText(R.string.matches0);
if (!books.isEmpty()) {
emptyResult.setVisibility(View.GONE);
// Create a new adapter that takes a rich (or otherwise empty) list of books as input
adapter = new Adapt(this, new ArrayList<Book>());
// Get the list of books from {#link Search}
bookEntries = findViewById(R.id.catalog);
bookEntries.setAdapter(adapter);
bookEntries.setEmptyView(emptyResult);
bookEntries.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick (AdapterView<?> adapterView, View view, int position, long l) {
// Find the current book that was clicked on
Book currentBook = adapter.getItem(position);
// Convert the String URL into a URI object (to pass into the Intent constructor)
Uri bookUri = Uri.parse(currentBook.getPage());
// Create a new intent to view the book URI
Intent websiteIntent = new Intent(Intent.ACTION_VIEW, bookUri);
// Send the intent to launch a new activity
startActivity(websiteIntent);
}
});
// adapter.clear();
adapter.addAll(books);
} else {
emptyResult.setVisibility(View.VISIBLE);
emptyResult.setText(R.string.matches0);
}
}
}
Book obj.:
package project.android.gbookslisting;
import java.io.Serializable;
import java.util.Date;
public class Book {
private String book_title;
private String author;
private String publishing_year;
private String page;
public Book (String theTitle, String theAuthor, String theYear, String thePage) {
this.book_title = theTitle;
this.author = theAuthor;
this.publishing_year = theYear;
this.page = thePage;
}
public Book setBook_title (String book_title) {
this.book_title = book_title;
return this;
}
public Book setAuthor (String author) {
this.author = author;
return this;
}
public Book setPublishing_year (String publishing_year) {
this.publishing_year = publishing_year;
return this;
}
public Book setPage (String page) {
this.page = page;
return this;
}
protected String getAuthor () {
return author;
}
protected String getPublishing_year () { return publishing_year; }
protected String getPage () {
return page;
}
protected String getBook_title () {
return book_title;
}
}
You can declare the a variable that will handle your data = new ArrayList<Book>(); as public static.. However it's not recommended for high level codebase but for the structures of yours, you can implement it.
just declare a variable like this above protected void onCreate() in FirstActivity ..
public static List<Book> book_data = new ArrayList<>();
and transfer the data from public void onLoadFinished (Loader<List<Book>> loader, List<Book> data) to book_data
#Override
public void onLoadFinished (Loader<List<Book>> loader, List<Book> data) {
// If there is a valid list of {#link Book}s, then add them to the adapter's dataset. This will trigger the ListView to update.
if (data != null && !data.isEmpty()) {
//data = new ArrayList<Book>();
book_data = data;
Intent i = new Intent(getApplicationContext(), ResultsActivity.class);
startActivity(i);
}
}`
You can also try to debug it if it contains a value
Log.d(TAG, String.valueOf(data.size()));
and in SecondActivity
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hits_page);
List<Book> books = new ArrayList<>();
books = FirstActivity.book_data; //Get the data from the First Activity
....
....
}
All right, so I was able to correct my implementation of the Parcelable interface and the FirstActivity now passes data to SecondActivity. This is it:
package project.android.gbookslisting;
import android.os.Parcel;
import android.os.Parcelable;
public class Book implements Parcelable {
private String book_title;
private String author;
private String publishing_year;
private String page;
public Book (String theTitle, String theAuthor, String theYear, String thePage) {
this.book_title = theTitle;
this.author = theAuthor;
this.publishing_year = theYear;
this.page = thePage;
}
public Book(Parcel in) {
this.book_title = in.readString();
this.author = in.readString();
this.publishing_year = in.readString();
this.page = in.readString();
}
public static final Creator<Book> CREATOR = new Creator<Book>() {
#Override
public Book createFromParcel (Parcel in) {
return new Book(in);
}
#Override
public Book[] newArray (int size) {
return new Book[size];
}
};
protected String getAuthor () { return author; }
protected String getPublishing_year () { return publishing_year; }
protected String getPage () {
return page;
}
protected String getBook_title () {
return book_title;
}
#Override
public int describeContents () {
return 0;
}
#Override
public void writeToParcel (Parcel parcel, int flags) {
parcel.writeString(book_title);
parcel.writeString(author);
parcel.writeString(publishing_year);
parcel.writeString(page);
}
}
I've shared the repository on GitHub #GBooks Listing, pending more features/updates.
ResultsActivity
Sure looks lame, but I'll improve the theming & whatever affects appearance. Thanks.

Mapbox navigation useroffroute function override not working

Offroute not triggered
I am using navigation launcher.I have tried using navigation view too.But the useroffroute function is not getting triggered.
package com.example.lenovo.offroutetest;
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
import android.os.Bundle;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
// classes needed to initialize map
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.maps.MapView;
// classes needed to add the location component
import com.mapbox.geojson.Point;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import android.location.Location;
import android.widget.Toast;
import com.mapbox.mapboxsdk.geometry.LatLng;
import android.support.annotation.NonNull;
import com.mapbox.mapboxsdk.location.LocationComponent;
import com.mapbox.mapboxsdk.location.modes.CameraMode;
import com.mapbox.services.android.navigation.ui.v5.NavigationLauncherOptions;
import com.mapbox.android.core.permissions.PermissionsListener;
import com.mapbox.android.core.permissions.PermissionsManager;
// classes needed to add a marker
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
// classes to calculate a route
import com.mapbox.services.android.navigation.ui.v5.NavigationView;
import com.mapbox.services.android.navigation.ui.v5.NavigationViewOptions;
import com.mapbox.services.android.navigation.ui.v5.route.NavigationMapRoute;
import com.mapbox.services.android.navigation.v5.instruction.Instruction;
import com.mapbox.services.android.navigation.v5.milestone.BannerInstructionMilestone;
import com.mapbox.services.android.navigation.v5.milestone.Milestone;
import com.mapbox.services.android.navigation.v5.milestone.MilestoneEventListener;
import com.mapbox.services.android.navigation.v5.milestone.RouteMilestone;
import com.mapbox.services.android.navigation.v5.milestone.Trigger;
import com.mapbox.services.android.navigation.v5.milestone.TriggerProperty;
import com.mapbox.services.android.navigation.v5.navigation.MapboxNavigation;
import com.mapbox.services.android.navigation.v5.navigation.MapboxNavigationOptions;
import com.mapbox.services.android.navigation.v5.navigation.NavigationRoute;
import com.mapbox.api.directions.v5.models.DirectionsResponse;
import com.mapbox.api.directions.v5.models.DirectionsRoute;
import com.mapbox.services.android.navigation.v5.offroute.OffRouteListener;
import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress;
import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener;
import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress;
import com.mapbox.services.android.navigation.v5.navigation.NavigationEventListener;
import okhttp3.Route;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import android.util.Log;
// classes needed to launch navigation UI
import android.view.View;
import android.widget.Button;
import com.mapbox.services.android.navigation.ui.v5.NavigationLauncher;
import org.intellij.lang.annotations.Identifier;
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback, MapboxMap.OnMapClickListener, OffRouteListener,PermissionsListener,MilestoneEventListener, ProgressChangeListener,NavigationEventListener{
private MapView mapView;
// variables for adding location layer
private MapboxMap mapboxMap;
private PermissionsManager permissionsManager;
private Location originLocation;
// variables for adding a marker
private Marker destinationMarker;
private LatLng originCoord;
private LatLng destinationCoord;
// variables for calculating and drawing a route
private Point originPosition;
private Point destinationPosition;
private DirectionsRoute currentRoute;
private static final String TAG = "DirectionsActivity";
private NavigationMapRoute navigationMapRoute;
private Button button;
private MapboxNavigation navigation;
private NavigationView navigationView;
private CoordinatorLayout coordinatorLayout;
private boolean running;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Mapbox.getInstance(this,"pk.eyJ1IjoicHJpeWFuZ2EiLCJhIjoiY2pwYzQ1OGxpMGgybTNscGhsbjA0cXlvcSJ9.MJD97KhqBQifpKRrPGtomg");
//MapboxNavigationOptions options = MapboxNavigationOptions.builder().isDebugLoggingEnabled(true).build();
//MapboxNavigationOptions opt=MapboxNavigationOptions.builder().build()
navigation=new MapboxNavigation(MainActivity.this,"pk.eyJ1IjoicHJpeWFuZ2EiLCJhIjoiY2pwYzQ1OGxpMGgybTNscGhsbjA0cXlvcSJ9.MJD97KhqBQifpKRrPGtomg");
//navigation.addOffRouteListener(offRouteListener);
//navigation.addMilestoneEventListener(this);
navigation.addMilestone(new BannerInstructionMilestone.Builder().setIdentifier(1).setTrigger(Trigger.all(Trigger.eq(TriggerProperty.LAST_STEP, TriggerProperty.TRUE))).setInstruction(new Instruction() {
#Override
public String buildInstruction(RouteProgress routeProgress) {
return "I AM HERE";
}
}).build());
setContentView(R.layout.activity_main);
mapView = findViewById(R.id.mapView);
//navigationView=findViewById(R.id.navigationView);
//navigationView.onCreate(savedInstanceState);
//navigationView.initialize(this);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(this);
}
#Override
public void onMilestoneEvent(RouteProgress routeProgress, String instruction, Milestone milestone) {
//exampleInstructionPlayer.play(instruction);
Log.e("milestone","reached");
Toast.makeText(getApplicationContext(),"Milestone triggered",Toast.LENGTH_SHORT).show();
}
#Override
public void onMapReady(MapboxMap mapboxMap) {
this.mapboxMap = mapboxMap;
enableLocationComponent();
originCoord = new LatLng(originLocation.getLatitude(), originLocation.getLongitude());
mapboxMap.addOnMapClickListener(this);
button = findViewById(R.id.startButton);
/*navigation.addOffRouteListener(new OffRouteListener() {
#Override
public void userOffRoute(Location location) {
Snackbar snackbar = Snackbar
.make(coordinatorLayout, "User rerouting", Snackbar.LENGTH_LONG);
snackbar.show();
Toast.makeText(getApplicationContext(), "Off route", Toast.LENGTH_SHORT).show();
//File path = getApplicationContext().getFilesDir();
//File path=getApplicationContext().getExternalFilesDir(null);
try {
File path=getApplicationContext().getFilesDir();
Toast.makeText(getApplicationContext(),String.valueOf(path),Toast.LENGTH_SHORT).show();
File file = new File(path, "off_route.txt");
FileOutputStream stream = new FileOutputStream(file);
stream.write(("Offroute"+location.toString()).getBytes());
stream.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
});*/
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//NavigationViewOptions navopt=NavigationViewOptions.builder().directionsRoute(currentRoute).shouldSimulateRoute(false).build();
boolean simulateRoute = false;
NavigationLauncherOptions options = NavigationLauncherOptions.builder()
.directionsRoute(currentRoute)
.shouldSimulateRoute(simulateRoute)
.build();
// Call this method with Context from within an Activity
NavigationLauncher.startNavigation(MainActivity.this, options);
//navigation.startNavigation(currentRoute);
//navigation.startNavigation(currentRoute);
//navigationView.startNavigation(navopt);
}
});
}
#Override
public void onProgressChange(Location location, RouteProgress routeProgress)
{
}
#Override
public void onMapClick(#NonNull LatLng point){
if (destinationMarker != null) {
mapboxMap.removeMarker(destinationMarker);
}
destinationCoord = point;
destinationMarker = mapboxMap.addMarker(new MarkerOptions()
.position(destinationCoord)
);
destinationPosition = Point.fromLngLat(destinationCoord.getLongitude(), destinationCoord.getLatitude());
originPosition = Point.fromLngLat(originCoord.getLongitude(), originCoord.getLatitude());
getRoute(originPosition, destinationPosition);
button.setEnabled(true);
button.setBackgroundResource(R.color.mapboxBlue);
/*try {
//File path=getApplicationContext().getFilesDir();
File path=getApplicationContext().getExternalFilesDir(null);
Toast.makeText(getApplicationContext(),String.valueOf(path.getAbsolutePath()),Toast.LENGTH_SHORT).show();
//File path = getApplicationContext().getExternalFilesDir(null);
File file = new File(path, "off_route.txt");
//Log.e("Writing to file","file");
FileOutputStream stream = new FileOutputStream(file);
stream.write("Offroute am there".getBytes());
Toast.makeText(getApplicationContext(),"I ma here",Toast.LENGTH_LONG).show();
stream.close();
}
catch (Exception e)
{
Toast.makeText(getApplicationContext(),e.toString(),Toast.LENGTH_LONG).show();
e.printStackTrace();
}*/
}
#Override
public void userOffRoute(Location location) {
//Snackbar snackbar = Snackbar
// .make(coordinatorLayout, "User rerouting", Snackbar.LENGTH_LONG);
//snackbar.show();
Toast.makeText(getApplicationContext(), "Off route detected.........", Toast.LENGTH_SHORT).show();
//File path = getApplicationContext().getFilesDir();
//File path=getApplicationContext().getExternalFilesDir(null);
try {
File path=getApplicationContext().getExternalFilesDir(null);
Toast.makeText(getApplicationContext(),String.valueOf(path),Toast.LENGTH_SHORT).show();
File file = new File(path, "useroff.txt");
FileOutputStream stream = new FileOutputStream(file);
stream.write(("Offroute"+location.toString()).getBytes());
stream.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
#Override
public void onRunning(boolean running)
{
this.running=running;
if(running)
{
//navigation.addOffRouteListener(this);
//navigation.addProgressChangeListener(this);
}
}
private void getRoute(Point origin, Point destination) {
NavigationRoute.builder(this)
.accessToken(Mapbox.getAccessToken())
.origin(origin)
.destination(destination)
.build()
.getRoute(new Callback<DirectionsResponse>() {
#Override
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
// You can get the generic HTTP info about the response
Log.d(TAG, "Response code: " + response.code());
if (response.body() == null) {
Log.e(TAG, "No routes found, make sure you set the right user and access token.");
return;
} else if (response.body().routes().size() < 1) {
Log.e(TAG, "No routes found");
return;
}
currentRoute = response.body().routes().get(0);
// Draw the route on the map
if (navigationMapRoute != null) {
navigationMapRoute.removeRoute();
} else {
navigationMapRoute = new NavigationMapRoute(navigation, mapView, mapboxMap, R.style.NavigationMapRoute);
}
navigationMapRoute.addRoute(currentRoute);
}
#Override
public void onFailure(Call<DirectionsResponse> call, Throwable throwable) {
Log.e(TAG, "Error: " + throwable.getMessage());
}
});
}
#SuppressWarnings( {"MissingPermission"})
private void enableLocationComponent() {
// Check if permissions are enabled and if not request
if (PermissionsManager.areLocationPermissionsGranted(this)) {
// Activate the MapboxMap LocationComponent to show user location
// Adding in LocationComponentOptions is also an optional parameter
LocationComponent locationComponent = mapboxMap.getLocationComponent();
locationComponent.activateLocationComponent(this);
locationComponent.setLocationComponentEnabled(true);
// Set the component's camera mode
locationComponent.setCameraMode(CameraMode.TRACKING);
originLocation = locationComponent.getLastKnownLocation();
} else {
permissionsManager = new PermissionsManager(this);
permissionsManager.requestLocationPermissions(this);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
#Override
public void onExplanationNeeded(List<String> permissionsToExplain) {
Toast.makeText(this, R.string.user_location_permission_explanation, Toast.LENGTH_LONG).show();
}
#Override
public void onPermissionResult(boolean granted) {
if (granted) {
enableLocationComponent();
} else {
Toast.makeText(this, R.string.user_location_permission_not_granted, Toast.LENGTH_LONG).show();
finish();
}
}
#Override
protected void onStart() {
super.onStart();
mapView.onStart();
}
#Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
#Override
protected void onPause() {
super.onPause();
mapView.onPause();
}
#Override
protected void onStop() {
super.onStop();
mapView.onStop();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
#Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
}
I expect the function useroffroute overridden by me gets triggered.But no trigger happens as in am not able to see the toast message and file creation when the user goes offroute.
So the first thing to address here is that this will definitely not work with NavigationLauncher. That object is really meant to be a full-featured solution to get nav up and running quickly with minimal customization. So it is not quite as flexible and doesn't allow you to modify your offRoute listeners. This is only possible with NavigationView.
It's easy to miss, but the documentation for how to override the default reroute behavior is actually outlined in the Map Matching docs: https://docs.mapbox.com/android/navigation/overview/map-matching/#map-matching-with-mapboxnavigation
With that in mind, it looks like you're missing one crucial step in your code. When you add an offRouteListener to you navigation object, you need to carry through and override the userOffRoute function. Which would end up looking like this:
navigation.addOffRouteListener(new OffRouteListener() {
#Override
public void userOffRoute(Location location) {
Toast.makeText(getApplicationContext(), "Off route detected.........", Toast.LENGTH_SHORT).show();
// Make sure you call for a new DirectionsRoute object
// and end by calling MapboxNavigation#startNavigation on a successful
}
});

Android - get the value of global variable from every function

I use Android Studio to make an app. I have a file named 'GlobalVariables.java' and this code in it:
public class GlobalVariables extends Application {
public String CallingActivity;
public String getCallVariable() {
return CallingActivity;
}
public void setCallVariable(String Value) {
CallingActivity = Value;
}
}
In the manifest file I have:
<application android:name=".GlobalVariables" .....
I also have a LanguageActivity.java file which has this code:
package com.testApp;
//import android.content.Intent;
//import android.support.v7.app.ActionBarActivity;
import android.app.ListActivity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
public class LanguageActivity extends ListActivity {
// public class CountrycodeActivity extends ListActivity {
public static final String TAG = "MyActivity";
// public static String RESULT_CONTRYCODE = "countrycode";
public String[] countrynames;
private TypedArray imgs;
private List<Country> countryList;
Locale myLocale;
Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
populateCountryList();
ArrayAdapter<Country> adapter = new CountryListArrayAdapter(this, countryList);
setListAdapter(adapter);
getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ReadWriteFile RWFile = new ReadWriteFile();
if (position == 0) {
ChangeLanguage("el", getBaseContext());
try {
RWFile.LangWrite("en",getBaseContext());
Log.e(TAG, "LANG === en");
} catch (IOException e) {
e.printStackTrace();
}
}else{
ChangeLanguage("en", getBaseContext());
try {
RWFile.LangWrite("en",getBaseContext());
Log.e(TAG, "LANG === en");
} catch (IOException e) {
e.printStackTrace();
}
}
imgs.recycle(); //recycle images
finish();
}
});
}
private void populateCountryList() {
countryList = new ArrayList<Country>();
countrynames = getResources().getStringArray(R.array.country_names);
//countrycodes = getResources().getStringArray(R.array.country_codes);
imgs = getResources().obtainTypedArray(R.array.country_flags);
for(int i = 0; i < countrynames.length; i++){
countryList.add(new Country(countrynames[i], imgs.getDrawable(i)));
}
}
public class Country {
private String name;
// private String code;
private Drawable flag;
public Country(String name, Drawable flag){
this.name = name;
// this.code = code;
this.flag = flag;
}
public String getName() {
return name;
}
public Drawable getFlag() {
return flag;
}
// public String getCode() {
// return code;
// }
}
public void ChangeLanguage(String value, Context context){
Resources res = context.getResources();
DisplayMetrics dm = res.getDisplayMetrics();
android.content.res.Configuration conf = res.getConfiguration();
conf.locale = new Locale(value.toLowerCase());
res.updateConfiguration(conf, dm);
GlobalVariables mApp = ((GlobalVariables)getApplicationContext());
String Activity = mApp.getCallVariable();
if (Activity.equals("Login")){
final Intent intent = new Intent(LanguageActivity.this, LoginActivity.class);
startActivity(intent);
}else if (Activity.equals("Signup")){
final Intent intent = new Intent(LanguageActivity.this, SignupActivity.class);
startActivity(intent);
}
}
}
When I run the code, the app craches with this error:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
If I change
GlobalVariables mApp = ((GlobalVariables)getApplicationContext());
String Activity = mApp.getCallVariable();
to
String Activity = ((GlobalVariables) this.getApplication()).getCallVariable();
then I get error:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.testApp.GlobalVariables.getCallVariable()' on a null object reference
I did many tries but nothing helped. What will solve my problem anyway?
Why do I do this? I want to know which Activity called ChangeLanguage() to restart it to show the selected language.
Dependency injection will solve your problem. If you use dagger2, solve this kind of problem will be better, because will be easier create singletons. If you want i can post here how you can do this. Comment below this answer if you want me to edit this with dagger2 basics.
Add this to the AndroidManifest.xml:
<application
android:name=".GlobalVariables"/>
Try:
public class GlobalVariables extends Application {
public String CallingActivity;
public staric GlobalVariables instance;
#Override
public void onCreate()
{super.onCreate();
this.instance = this;
}
public String getCallVariable() {
return CallingActivity;
}
public void setCallVariable(String Value) {
CallingActivity = Value;
}
public static GlobalVariables getInstance()
{
return instance;
}
}
String Activity = GlobalVariables.getInstance().getCallVariable();
Try replacing the line
GlobalVariables mApp = ((GlobalVariables)getApplicationContext());
with:
GlobalVariables mApp = new GlobalVariables();
And in line :
String Activity = mApp.getCallVariable();
Replace 'Activity' with 'activity' because Activity is a pre-defined word.
Edit 1: IS this is how you tried:
GlobalVariables mApp = GlobalVariables.getInstance();
mApp.setCallVariable(value);
mApp.getCallVariable();

ADK toolkit Android+Arduino store variable issue

I'm writing a program which is supposed to run "forever". The program is Android application for tablet which exchanges data with Arduino. I have already implemented the code for Arduino and Android, and it exchanges data very well. However, after 2 cycles of work, my instance of AdkManager becomes NULL. As I've read before, Android will null variables from time to time because it has limited resources. However here's the problem - the AdkManager has confirmed bug that once it has been closed, it can't be reopened. Thus I can't re-initiate the AdkManager instance and I need to store it somehow. So far I've been using Application extension. The code is below:
MyApplication:
package org.udoo.androidadkdemobidirect;
import android.app.Application;
import android.content.Context;
import android.hardware.usb.UsbManager;
import me.palazzetti.adktoolkit.AdkManager;
/**
* Created by admin on 8/18/16.
*/
public class MyApplication extends Application {
private String someVariable;
public String getSomeVariable() {
return someVariable;
}
public void setSomeVariable(String someVariable) {
this.someVariable = someVariable;
}
public static class sAdkManager{
private static sAdkManager ourInstance = null;
public static sAdkManager getInstance() {
if (ourInstance==null)
ourInstance = new sAdkManager();
return ourInstance;
}
private static AdkManager mAdkManager = null;
public void write(String s){
mAdkManager.writeSerial(s);
}
public String read(){
return mAdkManager.readSerial();
}
public void open(){
mAdkManager.open();
}
public void close(){
mAdkManager.close();
}
public boolean checkNull(){
return mAdkManager==null;
}
public static void init(Context context){
if(mAdkManager==null) {
mAdkManager = new AdkManager((UsbManager) context.getSystemService(Context.USB_SERVICE));
context.registerReceiver(mAdkManager.getUsbReceiver(), mAdkManager.getDetachedFilter());
}
}
private sAdkManager() {
}
}
}
MainActivity:
package org.udoo.androidadkdemobidirect;
import me.palazzetti.adktoolkit.AdkManager;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.hardware.usb.UsbManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.TextView;
import android.widget.ToggleButton;
//import org.udoo.androidadkdemobidirect.sAdkManager;
public class MainActivity extends Activity{
// private static final String TAG = "UDOO_AndroidADKFULL";
private static String mAdkManager=null;
private ToggleButton buttonLED;
private TextView distance;
private AdkReadTask mAdkReadTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//
//// register a BroadcastReceiver to catch UsbManager.ACTION_USB_ACCESSORY_DETACHED action
// registerReceiver(mAdkManager.getUsbReceiver(), mAdkManager.getDetachedFilter());
buttonLED = (ToggleButton) findViewById(R.id.toggleButtonLed);
distance = (TextView) findViewById(R.id.textViewIntro);
// mAdkManager.open();
TextView tv = (TextView) findViewById(R.id.ppm);
if (mAdkManager==null){
tv.setText("ADK is null. init()");
mAdkManager = new String ("sometext");
}
else{
tv.setText("ADK is not null.");
}
if (MyApplication.sAdkManager.getInstance().checkNull()) {
distance.setText("Null before init");
MyApplication.sAdkManager.init(this);
}
if (MyApplication.sAdkManager.getInstance().checkNull()) {
distance.setText("Null after init");
}
MyApplication.sAdkManager.getInstance().open();
mAdkReadTask = new AdkReadTask();
mAdkReadTask.execute();
}
#Override
public void onResume() {
super.onResume();
}
#Override
public void onPause() {
super.onPause();
}
#Override
public void onDestroy() {
MyApplication.sAdkManager.getInstance().close();
// unregisterReceiver(mAdkManager.getUsbReceiver());
super.onDestroy();
}
// ToggleButton method - send message to SAM3X
public void blinkLED(View v){
if (buttonLED.isChecked()) {
TextView tvdbg = (TextView) findViewById(R.id.ppm);
tvdbg.setText("send 1");
// writeSerial() allows you to write a single char or a String object.
//mAdkManager.writeSerial("1");
MyApplication.sAdkManager.getInstance().write("1");
// mAdkManager.writeSerial("8");
} else {
//mAdkManager.writeSerial("0");
MyApplication.sAdkManager.getInstance().write("0");
}
}
/*
* We put the readSerial() method in an AsyncTask to run the
* continuous read task out of the UI main thread
*/
private class AdkReadTask extends AsyncTask<Void, String, Void> {
private boolean running = true;
public void pause(){
running = false;
}
protected Void doInBackground(Void... params) {
// Log.i("ADK demo bi", "start adkreadtask");
while(running) {
// if (mAdkManager.serialAvailable())
// publishProgress(mAdkManager.readSerial()) ;
publishProgress(MyApplication.sAdkManager.getInstance().read());
}
return null;
}
protected void onProgressUpdate(String... progress) {
distance.setText("You put "+((int)progress[0].charAt(0)-48) + " iqos butts\tRFID OK");
next();
// Log.i(TAG, "received: " + (int)progress[0].charAt(0));
}
}
private void next() {
final Intent intent = new Intent(this, BRActivity.class );
new android.os.Handler().postDelayed(
new Runnable() {
public void run() {
mAdkReadTask.pause();
mAdkReadTask = null;
startActivity(intent);
}
},
3000);
}
}
There are just 2 Activities for now - MainActivity and BRActivity. BRActivity is just a view with "return" button which comes back to MainActivity.
Also what I find interesting - I output the readSerial in TextView to see what I got in reader thread. However on cycle#2 i don't get any output to TextView, but Activity still changes to the next one.
[EDIT]
Apparently the problem was solved when the thread was nulling. However, I still don't get the text update, but I magically get to another screen. Please advice.

after logged in ,remain in home_screen until logout

I want to send the username and password to the server and it returns a response whether the username and password matches. I do not want to ask for login each time my app starts, instead I want to remain in the home_screen until I logout from my android app. How can I do this? any example will be thankfull..
package com.example.test5;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.DialogInterface.OnClickListener;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity implements OnClickListener{
private EditText username;
private EditText password;
private Button login;
static String u;
static String p;
Context context = MainActivity.this;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
username = (EditText)findViewById(R.id.editText1);//Visibility
password = (EditText)findViewById(R.id.editText2);//Visibility
login = (Button)findViewById(R.id.button1);//Visibility
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
u = username.getText().toString();
p = password.getText().toString();
Toast.makeText(MainActivity.this, "Checking User Login",Toast.LENGTH_SHORT).show();
new MyAsyncTask_Login(context).execute(u,p);
}
});
}
#Override
public void onClick(DialogInterface dialog, int which) {
}
}
my asynctask class
package com.example.test5;
import java.io.StringReader;
import java.util.LinkedList;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.XmlResourceParser;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.widget.Toast;
public class MyAsyncTask_Login extends AsyncTask<String, Void, String>{
public static final String MyPREFERENCES = "MyPrefs" ; //editor: never used
public static final String userName = "name";
public static final String Password = "password";
SharedPreferences sharedpreferences; //editor: never used
private Context context;
public MyAsyncTask_Login(Context context) {
this.context = context;
}
#Override
protected String doInBackground(String... params) {
String response = new Login_WebService().checkLogin(params[0], params[1]);
return response;
}
#Override
protected void onPostExecute(String result) {
String strResponse = result;
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser parser = factory.newPullParser();
parser.setInput(new StringReader(strResponse));
List<String> tags = new LinkedList<String>();
tags.add("valid");
for (int type = parser.next(); type != XmlResourceParser.END_DOCUMENT; type = parser.next()) {
if (type == XmlResourceParser.START_TAG) {
String name = parser.getName();
if (tags.contains(name)) {
type = parser.next();
if (parser.getText().trim().equals("1")) {
Toast.makeText(context, "logged in succesfully.",Toast.LENGTH_SHORT).show();
try {
String user = MainActivity.u;
String pass = MainActivity.p;
Intent i = new Intent(context,Home_page.class);
context.startActivity(i);
}
catch (Exception e) {
Toast.makeText(context, e.toString(),Toast.LENGTH_SHORT).show();
}
}
else {
Toast.makeText(context, "Invalid User",Toast.LENGTH_SHORT).show();
}
}
}
}
}
catch (Exception e) {
}
}
}
You can do like this:
Save your login data in shared Preferences.
When the user login:
protected void doInBackground(Activity... params) {
Activity activity = (Activity) params[0];
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);//Pass activity in params o
Editor editor = prefs.edit();
editor.putString("username",u);
editor.putString("password",p);
editor.commit();
}
in on create when the user restart the app read the shared preferences:
u = prefs.getString("username", "");
p = prefs.getString("password", "");
if(u.equals("") || p.equals(""))
//user needs new login
else
//user already login
To make logout put "" in sharedpreferences.

Categories

Resources