ADK toolkit Android+Arduino store variable issue - java

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.

Related

Android MediaBrowserService customize audio src and meta data

I am building a audio player i have completed all the Songs browsing (UI) activities and to handle audio playback i am using google sample audio player this and i read all the src from this sample and there is class MusicLibrary in sample code and it contains a sample list of songs like below
public class MusicLibrary {
private static final TreeMap<String, MediaMetadataCompat> music = new TreeMap<>();
private static final HashMap<String, Integer> albumRes = new HashMap<>();
private static final HashMap<String, String> musicFileName = new HashMap<>();
static {
createMediaMetadataCompat(
"Jazz_In_Paris",
"Jazz in Paris",
"Media Right Productions",
"Jazz & Blues",
"Jazz",
103,
TimeUnit.SECONDS,
"http://www.noiseaddicts.com/samples_1w72b820/2537.mp3",
R.drawable.album_jazz_blues,
"https://upload.wikimedia.org/wikipedia/en/a/ac/Audioslave_-_Audioslave.jpg");
createMediaMetadataCompat(
"The_Coldest_Shoulder",
"The Coldest Shoulder",
"The 126ers",
"Youtube Audio Library Rock 2",
"Rock",
160,
TimeUnit.SECONDS,
"http://www.noiseaddicts.com/samples_1w72b820/4201.mp3",
R.drawable.album_youtube_audio_library_rock_2,
"https://theflagcompany.in/wp-content/uploads/2018/10/Indian-National-Flag-300x300.jpeg");
}
but i am unable to find a method which shows how to add a song in current playlist from other activities for example in my current app there is search activity where user can search any song from internet and i want to add track from this search activity by two different ways 1. add and play song 2. only add song in the end of playlist.
Sample code track object use album art image from drawable folder but in my app i need to show album art from internet (Last FM API) not from local folder i tried to edit MusicLibrary class and created a bitmap from URI unable to make it work so this is alos i need to modify in sample code.
Sample code contains only on simple activity where when you open it opens a audio player interface but in my app in HomeActivity there are some fragments and a mini player at bottom now like below
Please help me with these two things
add songs to player from my code
use internet image for METADATA_KEY_ALBUM_ART
i just want to merge these two things and i am new to android so no luck please guide me so that i can complete my project. Thanks in advance :)
My Main Activity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//add song in sample player service from this method
public void addSongQue(Song song) {
title = song.getTile;
artist = song.getArtist;
mp3Url = song.getSrc;
albumArtImage = song.getAlbumArt;
.......
...
}
}
Sample Code Player Activity full sample src is here
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.media.MediaBrowserCompat;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaControllerCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.android.mediasession.R;
import com.example.android.mediasession.client.MediaBrowserHelper;
import com.example.android.mediasession.service.MusicService;
import com.example.android.mediasession.service.contentcatalogs.MusicLibrary;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private ImageView mAlbumArt;
private TextView mTitleTextView;
private TextView mArtistTextView;
private ImageView mMediaControlsImage;
private MediaSeekBar mSeekBarAudio;
private MediaBrowserHelper mMediaBrowserHelper;
private boolean mIsPlaying;
//https://github.com/googlesamples/android-MediaBrowserService
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTitleTextView = findViewById(R.id.song_title);
mArtistTextView = findViewById(R.id.song_artist);
mAlbumArt = findViewById(R.id.album_art);
mMediaControlsImage = findViewById(R.id.media_controls);
mSeekBarAudio = findViewById(R.id.seekbar_audio);
final ClickListener clickListener = new ClickListener();
findViewById(R.id.button_previous).setOnClickListener(clickListener);
findViewById(R.id.button_play).setOnClickListener(clickListener);
findViewById(R.id.button_next).setOnClickListener(clickListener);
mMediaBrowserHelper = new MediaBrowserConnection(this);
mMediaBrowserHelper.registerCallback(new MediaBrowserListener());
}
#Override
public void onStart() {
super.onStart();
mMediaBrowserHelper.onStart();
}
#Override
public void onStop() {
super.onStop();
mSeekBarAudio.disconnectController();
mMediaBrowserHelper.onStop();
}
/**
* Convenience class to collect the click listeners together.
* <p>
* In a larger app it's better to split the listeners out or to use your favorite
* library.
*/
private class ClickListener implements View.OnClickListener {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_previous:
mMediaBrowserHelper.getTransportControls().skipToPrevious();
break;
case R.id.button_play:
if (mIsPlaying) {
mMediaBrowserHelper.getTransportControls().pause();
} else {
mMediaBrowserHelper.getTransportControls().play();
}
break;
case R.id.button_next:
mMediaBrowserHelper.getTransportControls().skipToNext();
break;
}
}
}
/**
* Customize the connection to our {#link android.support.v4.media.MediaBrowserServiceCompat}
* and implement our app specific desires.
*/
private class MediaBrowserConnection extends MediaBrowserHelper {
private MediaBrowserConnection(Context context) {
super(context, MusicService.class);
}
#Override
protected void onConnected(#NonNull MediaControllerCompat mediaController) {
mSeekBarAudio.setMediaController(mediaController);
}
#Override
protected void onChildrenLoaded(#NonNull String parentId,
#NonNull List<MediaBrowserCompat.MediaItem> children) {
super.onChildrenLoaded(parentId, children);
final MediaControllerCompat mediaController = getMediaController();
// Queue up all media items for this simple sample.
for (final MediaBrowserCompat.MediaItem mediaItem : children) {
mediaController.addQueueItem(mediaItem.getDescription());
}
// Call prepare now so pressing play just works.
mediaController.getTransportControls().prepare();
}
}
/**
* Implementation of the {#link MediaControllerCompat.Callback} methods we're interested in.
* <p>
* Here would also be where one could override
* {#code onQueueChanged(List<MediaSessionCompat.QueueItem> queue)} to get informed when items
* are added or removed from the queue. We don't do this here in order to keep the UI
* simple.
*/
private class MediaBrowserListener extends MediaControllerCompat.Callback {
#Override
public void onPlaybackStateChanged(PlaybackStateCompat playbackState) {
mIsPlaying = playbackState != null &&
playbackState.getState() == PlaybackStateCompat.STATE_PLAYING;
mMediaControlsImage.setPressed(mIsPlaying);
}
#Override
public void onMetadataChanged(MediaMetadataCompat mediaMetadata) {
if (mediaMetadata == null) {
return;
}
mTitleTextView.setText(
mediaMetadata.getString(MediaMetadataCompat.METADATA_KEY_TITLE));
mArtistTextView.setText(
mediaMetadata.getString(MediaMetadataCompat.METADATA_KEY_ARTIST));
mAlbumArt.setImageBitmap(MusicLibrary.getAlbumBitmap(
MainActivity.this,
mediaMetadata.getString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID)));
}
#Override
public void onSessionDestroyed() {
super.onSessionDestroyed();
}
#Override
public void onQueueChanged(List<MediaSessionCompat.QueueItem> queue) {
super.onQueueChanged(queue);
}
}
}
MusicLibrary Class where two sample songs
import android.content.ContentResolver;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v4.media.MediaBrowserCompat;
import android.support.v4.media.MediaMetadataCompat;
import com.example.android.mediasession.BuildConfig;
import com.example.android.mediasession.R;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;
public class MusicLibrary {
private static final TreeMap<String, MediaMetadataCompat> music = new TreeMap<>();
private static final HashMap<String, Integer> albumRes = new HashMap<>();
private static final HashMap<String, String> musicFileName = new HashMap<>();
static {
createMediaMetadataCompat(
"Jazz_In_Paris",
"Jazz in Paris",
"Media Right Productions",
"Jazz & Blues",
"Jazz",
103,
TimeUnit.SECONDS,
"http://www.noiseaddicts.com/samples_1w72b820/2537.mp3",
R.drawable.album_jazz_blues,
"https://upload.wikimedia.org/wikipedia/en/a/ac/Audioslave_-_Audioslave.jpg");
createMediaMetadataCompat(
"The_Coldest_Shoulder",
"The Coldest Shoulder",
"The 126ers",
"Youtube Audio Library Rock 2",
"Rock",
160,
TimeUnit.SECONDS,
"http://www.noiseaddicts.com/samples_1w72b820/4201.mp3",
R.drawable.album_youtube_audio_library_rock_2,
"https://theflagcompany.in/wp-content/uploads/2018/10/Indian-National-Flag-300x300.jpeg");
}
public static String getRoot() {
return "root";
}
private static String getAlbumArtUri(String albumArtResName) {
return ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
BuildConfig.APPLICATION_ID + "/drawable/" + albumArtResName;
}
public static String getMusicFilename(String mediaId) {
return musicFileName.containsKey(mediaId) ? musicFileName.get(mediaId) : null;
}
private static int getAlbumRes(String mediaId) {
return albumRes.containsKey(mediaId) ? albumRes.get(mediaId) : 0;
}
public static Bitmap getAlbumBitmap(Context context, String mediaId) {
return BitmapFactory.decodeResource(context.getResources(),
MusicLibrary.getAlbumRes(mediaId));
}
public static List<MediaBrowserCompat.MediaItem> getMediaItems() {
List<MediaBrowserCompat.MediaItem> result = new ArrayList<>();
for (MediaMetadataCompat metadata : music.values()) {
result.add(
new MediaBrowserCompat.MediaItem(
metadata.getDescription(), MediaBrowserCompat.MediaItem.FLAG_PLAYABLE));
}
return result;
}
public static MediaMetadataCompat getMetadata(Context context, String mediaId) {
MediaMetadataCompat metadataWithoutBitmap = music.get(mediaId);
Bitmap albumArt = getAlbumBitmap(context, mediaId);
// Since MediaMetadataCompat is immutable, we need to create a copy to set the album art.
// We don't set it initially on all items so that they don't take unnecessary memory.
MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
for (String key :
new String[]{
MediaMetadataCompat.METADATA_KEY_MEDIA_ID,
MediaMetadataCompat.METADATA_KEY_ALBUM,
MediaMetadataCompat.METADATA_KEY_ARTIST,
MediaMetadataCompat.METADATA_KEY_GENRE,
MediaMetadataCompat.METADATA_KEY_TITLE
}) {
builder.putString(key, metadataWithoutBitmap.getString(key));
}
builder.putLong(
MediaMetadataCompat.METADATA_KEY_DURATION,
metadataWithoutBitmap.getLong(MediaMetadataCompat.METADATA_KEY_DURATION));
builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, albumArt);
return builder.build();
}
private static void createMediaMetadataCompat(
String mediaId,
String title,
String artist,
String album,
String genre,
long duration,
TimeUnit durationUnit,
String musicFilename,
int albumArtResId,
String albumArtResName) {
music.put(
mediaId,
new MediaMetadataCompat.Builder()
.putString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID, mediaId)
.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, album)
.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist)
.putLong(MediaMetadataCompat.METADATA_KEY_DURATION,
TimeUnit.MILLISECONDS.convert(duration, durationUnit))
.putString(MediaMetadataCompat.METADATA_KEY_GENRE, genre)
.putString(
MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI,
getAlbumArtUri(albumArtResName))
.putString(
MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI,
getAlbumArtUri(albumArtResName))
.putString(MediaMetadataCompat.METADATA_KEY_TITLE, title)
.build());
albumRes.put(mediaId, albumArtResId);
musicFileName.put(mediaId, musicFilename);
}
}

React Native: write in AsyncStorage with 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.

Substring in Java Eclipse Project

I'm pretty new to this. I'm working on an app in eclipse to read card reader input. Currently, the card reader as usual reads out the card details all in a single row of entry (its a tract 2 reader). It will be changed to a track1 card reader, then I can use the cardHolderName text. Here's a sample card output
;1234567890111213=12345678901113141516?
I would like to;
remove the first ";" everytime a card is read
Add the first 16 digits (after the ";") to a textfield
Remove the "="
display the first 4 digits after the "=" sign in another textfield
So the two textfields should display:
Textfield1:1234567890111213
Textfield2: 12/34
I tried using the substring() method in the setText lines, but it didn't provide any results. Can anyone help identify where I'm making a mistake ?
The .java code i am working on is below; Much appreciated!
package com.square;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class Payments extends Activity {
private UpdateBytesHandler updateBytesHandler;
private UpdateBitsHandler updateBitsHandler;
private TextView decodedStringView;
private TextView strippedBinaryView;
private TextView holderName;
private TextView expiryDate;
private TextView cardNumber;
private Button startBtn;
private Button stopBtn;
private MagRead read;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startBtn = (Button)findViewById(R.id.startbtn);
stopBtn = (Button)findViewById(R.id.stopbtn);
stopBtn.setEnabled(false);
decodedStringView = (TextView)findViewById(R.id.bytes);
strippedBinaryView = (TextView)findViewById(R.id.bits);
holderName = (TextView)findViewById(R.id.holderNameReal);
cardNumber = (TextView)findViewById(R.id.cardNumberReal);
expiryDate = (TextView)findViewById(R.id.expiry);
read = new MagRead();
read.addListener(new MagReadListener() {
#Override
public void updateBytes(String bytes) {
Message msg = new Message();
msg.obj = bytes;
updateBytesHandler.sendMessage(msg);
}
#Override
public void updateBits(String bits) {
Message msg = new Message();
msg.obj = bits;
updateBitsHandler.sendMessage(msg);
}
});
MicListener ml = new MicListener();
startBtn.setOnClickListener(ml);
stopBtn.setOnClickListener(ml);
updateBytesHandler = new UpdateBytesHandler();
updateBitsHandler = new UpdateBitsHandler();
}
#Override
protected void onDestroy() {
super.onDestroy();
read.release();
}
/**
* Listener called with the mic status button is clicked, and when the zero level or noise thresholds are changed
*/
private class MicListener implements OnClickListener{
/**
* Called when the mic button is clicked
* #param
*/
#Override
public void onClick(View v) {
if(v == stopBtn){//stop listening
stopBtn.setEnabled(false);
startBtn.setEnabled(true);
read.stop();
}else if(v == startBtn) {//start listening
stopBtn.setEnabled(true);
startBtn.setEnabled(false);
read.start();
}
}
}
private class UpdateBytesHandler extends Handler {
#Override
public void handleMessage(Message msg) {
String bytes = (String)msg.obj;
decodedStringView.setText(bytes);
}
}
private class UpdateBitsHandler extends Handler {
#Override
public void handleMessage(Message msg) {
String bits = (String)msg.obj;
strippedBinaryView.setText(bits);
}
}
private class UpdateHolderName extends Handler {
#Override
public void handleMessage(Message msg) {
String holderN = (String)msg.obj;
holderName.setText(holderN);
}
}
private class UpdateCardNumber extends Handler {
#Override
public void handleMessage(Message msg) {
String cardN = (String)msg.obj;
cardNumber.setText(cardN);
}
}
private class UpdateExpiry extends Handler {
#Override
public void handleMessage(Message msg) {
String exp = (String)msg.obj;
expiryDate.setText(exp);
}
}
}`
Consider this to your string
String data = ";1234567890111213=12345678901113141516?"
String first= data.substring(1, 17);
String second= data.substring(18, data.length()-1);
For more understanding, follow this tutorial
Check the java String method substring(i,j)
String code = ";1234567890111213=12345678901113141516?";
String first = code.substring(1,17);
String second = code.substring(18,19) + "/" + code.substring(20,21);
IMPORTANT substring() returns a new String !
Returns a new string that is a substring of this string.
So you must store the result in a variable.

Cannot initiate the type View.onclicklistner

I am getting this error on line 174
code was working fine but after last update I am getting this error that Cannot initiate the type View.onclicklistner
this is client code for chat functionality using websockets
how to fix this???
package de.lauridmeyer.com.tests;
import org.jwebsocket.api.WebSocketClientEvent;
import org.jwebsocket.api.WebSocketClientTokenListener;
import org.jwebsocket.api.WebSocketPacket;
import org.jwebsocket.client.plugins.rpc.Rpc;
import org.jwebsocket.client.plugins.rpc.RpcListener;
import org.jwebsocket.client.plugins.rpc.Rrpc;
import org.jwebsocket.client.token.BaseTokenClient;
import org.jwebsocket.kit.WebSocketException;
import org.jwebsocket.token.Token;
import org.jwebsocket.token.TokenFactory;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class SimpleJWAndroidClientActivity extends Activity implements WebSocketClientTokenListener{
//GUI Elements
private static TextView log;
private static TextView Chatlog;
private static EditText ipadress;
private static EditText Message;
private static Button send;
private static Button conBtn;
private String entered_msg=null;
TextView customDialog_TextView;
Button customDialog_Yes, customDialog_No;
static final int CUSTOM_DIALOG_ID = 0;
public static String decision=null;
//stores if the SLider is changed by the user or the server
private static Boolean isDragging=false;
//stores the connection status
private static Boolean connected=false;
//used for the connection
private static BaseTokenClient btc = new BaseTokenClient();//create a new instance of the base token client
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
log = (TextView)findViewById(R.id.log);//Textview to Display Messages
ipadress=(EditText)findViewById(R.id.ipadress);//inputfield for the ipadress
Chatlog=(TextView)findViewById(R.id.chat);
conBtn= (Button)findViewById(R.id.conBtn);//(dis)connection button
Message=(EditText)findViewById(R.id.Message);
send= (Button)findViewById(R.id.Send);
//add the listener for the slider and the (dis)connection Button
conBtn.setOnClickListener(buttonConnectOnClickListener);
//add the listener for the websocket connection
btc.addListener(this);//add this class as a listener
btc.addListener(new RpcListener());//add an rpc listener
Rpc.setDefaultBaseTokenClient(btc);//set it to the default btc
Rrpc.setDefaultBaseTokenClient(btc);//same here
//set the connection status to "not connected" on startup
changeConnectionStatus(false);
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
entered_msg = Message.getText().toString();
Token firstToken = TokenFactory.createToken("com.lauridmeyer.tests.LauridsPlugIn","Welcomemessage");
firstToken.setString("message",entered_msg);//add the message to the token
try {
btc.sendToken(firstToken);//try to send the token to the server
} catch (WebSocketException ex) {
outputText("error:"+ex.getMessage());//log errors
}
}
});
}
private OnClickListener buttonConnectOnClickListener = new OnClickListener() {
public void onClick(View v){
if(!connected){//if not connected
try{
String ipAdress=ipadress.getText().toString();//get the ip-adress from the inputfield
outputText("connecting to "+ipAdress+" ...");//debug
btc.open(ipAdress);//try to open the connection to your server
}catch(Exception e){
outputText("Error while connecting...");//log errors
}
}else{//if connected
try{
btc.close();//try to close
}catch(Exception e){
outputText(e.toString());//log errors
}
}
}
};
// private static SeekBar.OnSeekBarChangeListener seekbarchangedListener = new SeekBar.OnSeekBarChangeListener(){
// //Method is fired everytime the seekbar is changed
// #Override
// public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// if(isDragging && connected){//if the ssekbar is changed by the user and not by the server
// //create a new Token with the namspace, and type
// Token tempToken = TokenFactory.createToken("com.lauridmeyer.tests.LauridsPlugIn","sliderChanged");
// tempToken.setInteger("value",progress);//add an integer to the token
// try {
// btc.sendToken(tempToken);//try to send the token to the server
// } catch (WebSocketException ex) {
// outputText("error:"+ex.getMessage());//log errors
// }
// }
// }
//
// #Override
// public void onStartTrackingTouch(SeekBar seekBar) {
// isDragging=true;//turn the sending mechanism on
// }
//
// #Override
// public void onStopTrackingTouch(SeekBar seekBar) {
// isDragging=false;//turn the sending mechanism off
// }
// };
/* Method is called when the connection status has changed
* connected <-> disconnected */
public static void changeConnectionStatus(Boolean isConnected) {
connected=isConnected;//change variable
//seekBar.setEnabled(isConnected);//enable/disable seekbar
if(isConnected){//if connection established
outputText("successfully connected to server");//log
conBtn.setText("DISCONNECT");//change Buttontext
}else{
outputText("disconnected from Server!");//log
conBtn.setText("CONNECT");//change Buttontext
}
}
/* Method prints text to the log textfield*/
public static void outputText(String msg) {
log.append(msg+"\n");
}
/* Message handler is used to process incoming tokens from the server*/
private Handler messageHandler = new Handler() {
#Override
public void handleMessage(Message aMessage) {
if(aMessage.what==0){//if it's a token
Token aToken =(Token) aMessage.obj;//get the received token
//if the namespace matches my plugin
if(aToken.getNS().equals("com.lauridmeyer.tests.LauridsPlugIn")){
//and it's a command that the slider has changed
//String wM = aToken.getString("Welcomemessage");
if(aToken.getString("reqType").equals("sliderHasChanged")){
int value=aToken.getInteger("value");//get the slider value
isDragging=false;//make sure that the slider changes are not recognized as user inputs
//seekBar.setProgress(value);//move the slider to the recieved position
}
if(aToken.getString("reqType").equals("Welcomemessage")){
String message=aToken.getString("Welcomemessage");//get the slider value (here)
Chatlog.setOnClickListener(new View.OnClickListener());
Toast.makeText(getApplicationContext(),message,Toast.LENGTH_LONG).show();
}
}
}
}
};
#Override
public void processOpened(WebSocketClientEvent aEvent) {
changeConnectionStatus(true);//when connected change the status
}
#Override
public void processClosed(WebSocketClientEvent aEvent) {
changeConnectionStatus(false);//when disconnected change the status
}
#Override
public void processToken(WebSocketClientEvent aEvent, Token aToken) {
//for some reason you can't process the token directly
//you have to use the messagehandler
Message lMsg = new Message();//create a new mess
lMsg.what = 0;
lMsg.obj = aToken;
messageHandler.sendMessage(lMsg);
}
//following Methods are not used in this example, but have to be there :)
#Override
public void processPacket(WebSocketClientEvent aEvent, WebSocketPacket aPacket) {
}
#Override
public void processOpening(WebSocketClientEvent aEvent) {
}
#Override
public void processReconnecting(WebSocketClientEvent aEvent) {
}
}
The line:
Chatlog.setOnClickListener(new View.OnClickListener());
It doesn't look like you're overriding a onClick() method.

custom ColorDialogPreference - saving/retrieving as sharedpreference

I'm having trouble implementing this color picker into my live wallpaper. It works just fine out of the box by itself (I can add it to my preferences menu, open up the widget and select a color), however I want to use that selected color to detail an EditText field that the user will see on the homescreen canvas. I can easily achieve this by changing ColorDialogPreference.java's int color to a static variable and calling it from the WallpaperService class directly:
int mColor = com.my.app.ColorDialogPreference.color;
But since it's static, the color gets reset once the process gets destroyed.
I've tried saving the variable via a SharedPreferences Editor inside my PreferencesActivity.java (see below), but can't seem to retrieve that variable in the WallpaperService class.
PreferencesActivity.java:
package com.my.app;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
public class MyPreferencesActivity extends PreferenceActivity
implements SharedPreferences.OnSharedPreferenceChangeListener {
#SuppressWarnings("deprecation")
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences preferences =
getSharedPreferences("prefs", MODE_WORLD_WRITEABLE);
getPreferenceManager().setSharedPreferencesName("preferenceKeyName");
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("preferenceKeyName", Color.GRAY);
editor.commit();
getPreferenceManager().setSharedPreferencesName("text_to_display");
getPreferenceManager().getSharedPreferences().
registerOnSharedPreferenceChangeListener(this);
addPreferencesFromResource(R.xml.prefs);
}
#SuppressWarnings("deprecation")
protected void onDestroy() {
getPreferenceManager().getSharedPreferences().
unregisterOnSharedPreferenceChangeListener(this);
super.onDestroy();
}
#SuppressWarnings("deprecation")
protected void onResume() {
super.onResume();
getPreferenceManager().getSharedPreferences().
registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
getPreferenceManager().getSharedPreferences().
registerOnSharedPreferenceChangeListener(this);
}
}
WallpaperService.java:
package com.my.app;
import java.util.List;
import java.util.Random;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.service.wallpaper.WallpaperService;
import android.view.SurfaceHolder;
public class MyWallpaperService extends WallpaperService {
public MyWallpaperService() {
super();
}
#Override
public Engine onCreateEngine() {
return new MyWallpaperEngine();
}
public class MyWallpaperEngine extends Engine
implements OnSharedPreferenceChangeListener {
Context ctx = getApplicationContext();
SharedPreferences sharedPreferences2 =
getSharedPreferences("prefs", MODE_WORLD_READABLE);
private int mColor = sharedPreferences2.getInt("preferenceKeyName",
Color.RED);
private boolean mVisible = false;
Paint p = new Paint();
float x1 = 0;
float y1 = 60;
private final Handler mHandler = new Handler();
private final Runnable mUpdateDisplay = new Runnable() {
#Override
public void run() {
draw();
}};
private void draw() {
SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas();
if (c != null) {
String text = "1. " + mText;
c.drawRect(0, 0, c.getWidth(), c.getHeight(), p);
p.setColor(mColor);
c.drawText(text, x, y, p);
}
}
}
} finally {
if (c != null)
holder.unlockCanvasAndPost(c);
}
mHandler.removeCallbacks(mUpdateDisplay);
if (mVisible) {
mHandler.postDelayed(mUpdateDisplay, 16);
}
}
private final Handler handler = new Handler();
private final Runnable drawRunner = new Runnable() {
#Override
public void run() {
draw();
}
};
#Override
public void onVisibilityChanged(boolean visible) {
super.onVisibilityChanged(visible);
mVisible = visible;
if (visible) {
mText = sharedPreferences.getString("text_to_display",
"default");
draw();
} else {
mHandler.removeCallbacks(mUpdateDisplay);
}
}
#Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
mVisible = false;
handler.removeCallbacks(drawRunner);
mHandler.removeCallbacks(mUpdateDisplay);
}
#Override
public void onDestroy() {
super.onDestroy();
mVisible = false;
mHandler.removeCallbacks(mUpdateDisplay);
}
#Override
public void onSurfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
draw();
}
}
#Override
public void onSharedPreferenceChanged(
SharedPreferences sharedPreferences, String key) {
// TODO Auto-generated method stub
}
}
}
And my prefs.xml:
`<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceScreen android:title="Set Text" android:summary="Some summary" >
<EditTextPreference android:key="text_to_display" android:title="Some text" />
</PreferenceScreen>
<PreferenceScreen android:title="Colors" android:summary="Any color you want!" >
<com.my.app.ColorPickerPreference
android:defaultValue="0xffffffff"
android:key="preferenceKeyName"
android:title="#string/pref_name"
android:summary="#string/pref_summary" />
</PreferenceScreen>
</PreferenceScreen>`
If I display the value of int color on the canvas, all that ever comes up is "-65535". I know that PreferencesActivity works to some degree, because retrieving "text_to_display", which is an EditText value, works just fine. Something else that is worth noting: if the process gets killed at all (reboot phone or FC), the color that I selected in the widget stays that color if I go back to the widget after having the process killed, so it seems to be saving inside ColorDialogPreference.java, but nowhere else?
Please consider using this color picker: github.com/chiralcode/Android-Color-Picker. It can be used as a preference on PreferenceScreen. Value will be stored in shared preferences with the key you provided.
You should also consider cleaning up your code. My proposition is to change MyPreferencesActivity into this:
public class MyPreferencesActivity extends PreferenceActivity {
#SuppressWarnings("deprecation")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getPreferenceManager().setSharedPreferencesName("sharedPreferencesFilename");
addPreferencesFromResource(R.xml.prefs);
}
}
This is all the code you need. It looks like that you do not fully understand how shared preferences works.
Your code doesn't work, because you are writing preferences to files such as "preferenceKeyName" and "text_to_display", but you are reading them from "prefs".

Categories

Resources