The latest update of Bluestacks is sending a network broadcast every 2 seconds from port 10505.
Beacon-v1|pcName|WindowsPC
OpenSensor-v2|54321
to IP 255.255.255.255
this wasnt happening with the previous version. is this some autosync announcement waiting to talk with another device? i dont want bluestacks talking to other networked devices unless i tell it to do so. i havent checked off or agreed to anything yet that says it requires a network broadcast like this.
even if it's only 53 bytes it's still network pollution to me. how can i turn this off until i actually want it ? thanks
package com.example.test5;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBAdapter {
private static final String TAG = "DBAdapter";
private static final String DATABASE_NAME = "TestDB"; //Database Name 'TestDB'
private static final int DATABASE_VERSION =1; //Change Version to upgrade db
private final Context context;
private DatabaseHelper DBHelper;
private SQLiteDatabase db;
public DBAdapter(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL("create table USER(Id INTEGER NOT NULL PRIMARY KEY,USER_ID TEXT NOT NULL,USER_NAME TEXT NOT NULL,PASSWORD TEXT NOT NULL, ACTIVE_YN TEXT NOT NULL default 'Y')");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion)
{
db.execSQL("DROP TABLE IF EXISTS USER");
onCreate(db);
}
}
//---opens the database---
public DBAdapter open() throws SQLException
{
db = DBHelper.getWritableDatabase();
return this;
}
//---closes the database---
public void close()
{
DBHelper.close();
}
//---insert a User into the database---
public void insertUser(String USER_ID,String USER_NAME,String PASSWORD)
{
ContentValues initialValues = new ContentValues();
initialValues.put("USER_ID", USER_ID);
initialValues.put("USER_NAME", USER_NAME);
initialValues.put("PASSWORD", PASSWORD);
db.insert("USER", null, initialValues);
}
//---updates
public boolean updateUserStatusById(String USER_NAME,String USER_ID )
{
ContentValues args = new ContentValues();
args.put("USER_NAME", USER_NAME);
return db.update("USER", args,
"USER_ID='" + USER_ID+"'", null) > 0;
}
//executing query and it returns fields which are specified in the query ..........
public Cursor getQueryResult(String MY_QUERY) throws SQLException
{
return db.rawQuery(MY_QUERY, null);
}
}
Nandakishore P
I find this to be an annoyance as well and would like to turn it off. So far, I have found that the offending executable is:
C:\program files (x86)\bluestacks\hd-frontend.exe
And in C:\ProgramData\BlueStacks\Logs\BlueStacksUsers.log there are entries for:
2015-12-10 08:46:56.378000 HD-Frontend( 2632: 4588): 1 INFO OpenSensor: Beacon port 10505, interval 2000, host name MYHOSTNAME
Having a block entry every two seconds on my firewall is unacceptable!
Related
I am creating in memory PCollection and writing it into postgres sql. now, when I insert data into table, few records may throw exception and will not be inserted. how to extract such failed insert records when I start pipeline?
below is the code I have written for pipeline:
PipelineOptions options = PipelineOptionsFactory.create();
options.setRunner(FlinkRunner.class);
Pipeline p = Pipeline.create(options);
// Preparing dummy data
Collection<Stock> stockList = Arrays.asList(new Stock("AAP", 2000,"Apple Inc"),
new Stock("MSF", 3000, "Microsoft Corporation"),
new Stock("NVDA", 4000, "NVIDIA Corporation"),
new Stock("INT", 3200, "Intel Corporation"));
// Reading dummy data and save it into PCollection<Stock>
PCollection<Stock> data = p.apply(Create.of(stockList)
.withCoder(SerializableCoder.of(Stock.class)));
//insert
#SuppressWarnings("unused")
PDone insertData = data.apply(JdbcIO.<Stock>write()
.withDataSourceConfiguration(JdbcIO.DataSourceConfiguration
.create("org.postgresql.Driver","jdbc:postgresql://localhost:5432/postgres")
.withUsername("postgres").withPassword("sachin"))
.withStatement("insert into stocks values(?, ?, ?)")
.withPreparedStatementSetter(new JdbcIO.PreparedStatementSetter<Stock>() {
private static final long serialVersionUID = 1L;
public void setParameters(Stock element, PreparedStatement query) throws SQLException {
query.setString(1, element.getSymbol());
query.setLong(2, element.getPrice());
query.setString(3, element.getCompany());
}
}));
p.run().waitUntilFinish();
After going through all apache beam programming guide, i did not get any clue, So, copied JdbcIO and modified execute batch where I have separated inserted successful record and insert failed record by using TupleTags. now, It is working.
below is code for modified JdbcIO:
private static class WriteFn<T> extends DoFn<T, T> {
private static final int DEFAULT_BATCH_SIZE = 1;
private final Write<T> spec;
private DataSource dataSource;
private Connection connection;
private PreparedStatement preparedStatement;
**private TupleTag<T> validTupleTag;
private TupleTag<T> inValidTupleTag;**
private int batchCount;
public WriteFn(Write<T> spec) {
this.spec = spec;
}
#Setup
public void setup() throws Exception {
dataSource = spec.getDataSourceConfiguration().buildDatasource();
connection = dataSource.getConnection();
connection.setAutoCommit(false);
preparedStatement = connection.prepareStatement(spec.getStatement());
validTupleTag = spec.getValidTupleTag();
inValidTupleTag = spec.getInvalidTupleTag();
}
#StartBundle
public void startBundle() {
batchCount = 0;
}
#ProcessElement
public void processElement(#Element T record, MultiOutputReceiver out)
throws Exception {
preparedStatement.clearParameters();
spec.getPreparedStatementSetter().setParameters(record,
preparedStatement);
preparedStatement.addBatch();
batchCount++;
if (batchCount >= DEFAULT_BATCH_SIZE) {
if (batchCount > 0) {
try {
preparedStatement.executeBatch();
connection.commit();
**out.get(validTupleTag).output(record);**
} catch (SQLException e1) {
//TODO add logger
**out.get(inValidTupleTag).output(record);**
}
batchCount = 0;
}
}
}
and client code:
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.apache.beam.runners.flink.FlinkRunner;
import org.apache.beam.sdk.Pipeline;
import org.apache.beam.sdk.PipelineResult.State;
import org.apache.beam.sdk.coders.SerializableCoder;
import org.apache.beam.sdk.options.PipelineOptions;
import org.apache.beam.sdk.options.PipelineOptionsFactory;
import org.apache.beam.sdk.transforms.Create;
import org.apache.beam.sdk.transforms.DoFn;
import org.apache.beam.sdk.transforms.ParDo;
import org.apache.beam.sdk.values.PCollection;
import org.apache.beam.sdk.values.PCollectionTuple;
import org.apache.beam.sdk.values.TupleTag;
/**
* #author sachin
* #date 18-Nov-2021
*/
public class BeamTest {
static List<Stock> stocks = new ArrayList<>();
public static void main(String[] args) {
System.setProperty("java.specification.version", "1.8");
process();
// read();
}
public static void process() {
final TupleTag<Stock> VALID = new TupleTag<Stock>() {
};
final TupleTag<Stock> INVALID = new TupleTag<Stock>() {
};
PipelineOptions options = PipelineOptionsFactory.create();
options.setRunner(FlinkRunner.class);
Pipeline p = Pipeline.create(options);
// Preparing dummy data
Collection<Stock> stockList = Arrays.asList(
new Stock("AAP", 2000, "Apple Inc"),
new Stock("MSF", 3000, "Microsoft Corporation"),
new Stock("NVDA", 4000, "NVIDIA Corporation"),
new Stock("INT", 3200, "Intel Corporation"));
// Reading dummy data and save it into PCollection<Stock>
PCollection<Stock> data =
p.apply(Create.of(stockList).
withCoder(SerializableCoder.of(Stock.class)));
// insert
PCollectionTuple pCollectionTupleResult = data.apply("write",
CustomJdbcIOWrite.<Stock>write()
.withDataSourceConfiguration(CustomJdbcIOWrite.DataSourceConfiguration
.create("org.postgresql.Driver",
"jdbc:postgresql://localhost:5432/postgres")
.withUsername("postgres").withPassword("sachin"))
.withStatement("insert into stocks values(?, ?,
?)").withValidTag(VALID).withInValidTag(INVALID)
.withPreparedStatementSetter(new
CustomJdbcIOWrite.PreparedStatementSetter<Stock>() {
private static final long serialVersionUID = 1L;
public void setParameters(Stock element,
PreparedStatement query) throws SQLException {
query.setString(1, element.getSymbol());
query.setLong(2, element.getPrice());
query.setString(3, element.getCompany());
}
}));
// get failed PCollection using INVALID tupletag
PCollection<Stock> failedPcollection =
pCollectionTupleResult.get(INVALID)
.setCoder(SerializableCoder.of(Stock.class));
failedPcollection.apply(ParDo.of(new DoFn<Stock, Stock>() {
private static final long serialVersionUID = 1L;
#ProcessElement
public void process(ProcessContext pc) {
System.out.println("Failed pCollection element:" +
pc.element().getCompany());
}
}));
//get failed PCollection using INVALID tupletag
PCollection<Stock> insertedPcollection =
pCollectionTupleResult.get(VALID)
.setCoder(SerializableCoder.of(Stock.class));
insertedPcollection.apply(ParDo.of(new DoFn<Stock, Stock>() {
private static final long serialVersionUID = 1L;
#ProcessElement
public void process(ProcessContext pc) {
System.out.println("Inserted pCollection element:" +
pc.element().getCompany());
}
}));
// run pipeline
State state = p.run().waitUntilFinish();
System.out.println("Data inserted successfully with state : " +
state);
}
}
below is the output as new Stock("NVDA", 4000, "NVIDIA Corporation") is intentianlly not inserted as my db column accept only 3 char "NVD" and not 4 chars "NVDA":
Inserted pCollection element:Microsoft Corporation
Failed pCollection element:NVIDIA Corporation
Inserted pCollection element:Intel Corporation
Inserted pCollection element:Apple Inc
Data inserted successfully with state : DONE
Full Details and github link
I want to use pre-populated database in Android Room. I found a way to make it through using the callback, and filled up the database files.
But something is wrong, I'm sure that the database is copied normally, but it remains empty in the device monitor and android emulator. Can you please help me
public abstract class AppDatabase extends RoomDatabase {
private static AppDatabase INSTANCE;
private static final String DB_NAME = "base.db";
static Context ctx;
public abstract Dao dao();
public static AppDatabase getDatabase(Context context) {
if (INSTANCE == null) {
ctx = context;
synchronized (AppDatabase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context,
AppDatabase.class, DB_NAME)
.allowMainThreadQueries()
.addCallback(rdc)
.build();
}
}
}
return INSTANCE;
}
private static RoomDatabase.Callback rdc = new RoomDatabase.Callback() {
public void onCreate(SupportSQLiteDatabase db) {
new PopulateDbAsync(INSTANCE, ctx).execute();
Log.d("db create ", "table created when db created first time in onCreate");
}
public void onOpen(#NonNull SupportSQLiteDatabase db) {
ContentValues contentValues = new ContentValues();
}
};
private static class PopulateDbAsync extends AsyncTask<Void, Void, Void> {
private Dao dao;
AssetManager assetManager = ctx.getAssets();
PopulateDbAsync(AppDatabase db, Context context) {
Dao = db.Dao();
ctx = context;
}
#Override
protected Void doInBackground(final Void... params) {
String DB_PATH = "/data/data/mypackage/databases/";
String DB_NAME = "base.db";
try {
Log.d("AppDatabase","Trying copy database file");
OutputStream myOutput = new FileOutputStream(DB_PATH + DB_NAME);
byte[] buffer = new byte[1024];
int length;
InputStream myInput = ctx.getAssets().open("base.db");
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
myInput.close();
myOutput.flush();
myOutput.close();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
}
I solved after spending 6 hours on researching and R & D .
Context is that : - I want to put already existing finaldb.db(which is present inside assests folder) into room database .
Step 1 :
copy this framework files from here link
Step 2 :
You need to migrate , chill i have code :)
#Database(entities = {Status.class}, version = 1,exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
public abstract DataDao StatusDao();
private static AppDatabase INSTANCE;
public static AppDatabase getDatabase(Context context) {
if (INSTANCE == null) {
INSTANCE = createDatabase(context);
}
return (INSTANCE);
}
private static final Migration MIGRATION_2_3 = new Migration(1, 2) {
#Override
public void migrate(#NonNull SupportSQLiteDatabase database) {
Log.d("kkkk","bc");
String SQL_CREATE_TABLE = "CREATE TABLE IF NOT EXISTS 'Status' " +
"( 'id' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT," +
" 'category' TEXT NOT NULL," +
" 'sub_category' TEXT NOT NULL," +
" 'content' TEXT NOT NULL," +
" 'favourite' INTEGER DEFAULT(0))";
database.execSQL(SQL_CREATE_TABLE);
}
};
private static AppDatabase createDatabase(Context context) {
RoomDatabase.Builder<AppDatabase> builder =
Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class,
context.getString(R.string.dbase_name));
return (builder.openHelperFactory(new AssetSQLiteOpenHelperFactory())
.allowMainThreadQueries()
.addMigrations(MIGRATION_2_3)
.build());
}
}
In MIGRATION_2_3 you have to create table exactly same as current database(which is present in assests folder)
want to learn about migration
Step 3 :
Now table is created successfully in room database !
In case of crash see your logcat , in which its written in understandable form .
You cannot, properly, do the copy of the database in the onCreate method.
When the onCreate method is called the database has been created (the created database is passed to the method). You have to do the copy before the onCreate method and before the database is opened.
You could override's the RoomDatabase init method and do the copy from that method or do the copy before invoking the databaseBuilder.
I'm solved it.
Database class:
#Database(entities = {Entity1.class, Entity2.class, Entity3.class}, version = 1, exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
private static AppDatabase INSTANCE;
public abstract Entity1Dao 1Dao();
public abstract Entity2Dao 2Dao();
public abstract Entity3Dao 3Dao();
public static AppDatabase getDatabase(Context context) {
if (INSTANCE == null) {
INSTANCE = createDatabase(context);
}
return (INSTANCE);
}
private static AppDatabase createDatabase(Context context) {
RoomDatabase.Builder<AppDatabase> builder =
Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class,
context.getString(R.string.dbase_name));
return (builder.openHelperFactory(new AssetSQLiteOpenHelperFactory())
.allowMainThreadQueries()
.build());
}
}
Also you should get SQL Helpers, link
My issue is a little bit different than the OP.
I was copying the database file from internal storage which I downloaded from the internet, not from assets. And java.lang.RuntimeException: Unable to copy database file is raised because I didn't grant READ_EXTERNAL_STORAGE before this, or in general granting WRITE_EXTERNAL_STORAGE as READ_EXTERNAL_STORAGE is included in WRITE_EXTERNAL_STORAGE and already need the write permission for downloading the file.
Error this line :
mDataBase = SQLiteDatabase.openDatabase(dbPath, "123", null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
When open the database . but whats Wrong? how to open database with password? Can any one help me?
I set the password on SQLITE Db Browser > File> Set encryption
open this password in android part
When Open then show error
error : net.sqlcipher.database.SQLiteException: file is not a database: , while compiling: select count(*) from sqlite_master
Can any one help me to solve it? thanks in advance
import android.content.Context;
import android.database.SQLException;
//import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import net.sqlcipher.database.SQLiteDatabase;
import net.sqlcipher.database.SQLiteDatabase;
import net.sqlcipher.database.SQLiteOpenHelper;
import net.sqlcipher.database.SQLiteDatabase.CursorFactory;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.File;
import net.sqlcipher.database.SQLiteDatabase;
import android.app.Activity;
import android.os.Bundle;
public class DatabaseHelper extends SQLiteOpenHelper {
private static String TAG = DatabaseHelper.class.getName();
private static String DB_PATH = "";
private static String DB_NAME = "ec.db";// Database name
private SQLiteDatabase mDataBase;
private final Context mContext;
File databaseFile=null;
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, 1);
DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
this.mContext = context;
SQLiteDatabase.loadLibs(context);
File databaseFile = context.getDatabasePath(DB_NAME);
databaseFile.mkdirs();
}
public void createDataBase() throws IOException {
// If database not exists copy it from the assets
boolean mDataBaseExist = checkDataBase();
if (!mDataBaseExist) {
this.getWritableDatabase("123");
this.close();
try {
// Copy the database from assests
copyDataBase();
Log.e(TAG, "createDatabase database created");
} catch (IOException mIOException) {
throw new Error(mIOException.toString() + " : " + DB_PATH
+ DB_NAME);// "ErrorCopyingDataBase"
}
}
}
private boolean checkDataBase() {
File dbFile = new File(DB_PATH + DB_NAME);
return dbFile.exists();
}
// Copy the database from assets
private void copyDataBase() throws IOException {
InputStream mInput = mContext.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream mOutput = new FileOutputStream(outFileName);
byte[] mBuffer = new byte[4096];
int mLength;
while ((mLength = mInput.read(mBuffer)) > 0) {
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
mOutput.close();
mInput.close();
}
// Open the database, so we can query it
public boolean openDataBase() throws SQLException {
String mPath = DB_PATH + DB_NAME;
//File dbFile = new File(DB_PATH + DB_NAME);
//File databaseFile = mContext.getDatabasePath(DB_NAME);
//databaseFile.mkdirs();
//databaseFile.delete();
SQLiteDatabase.loadLibs(mContext);
String dbPath = mContext.getDatabasePath("ec.db").getPath();
//databaseFile.delete();
SQLiteDatabase.loadLibs(mContext);
//mDataBase = SQLiteDatabase.openOrCreateDatabase(databaseFile, "123", null);
//mDataBase = SQLiteDatabase.openDatabase(mPath, "123",null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
mDataBase = SQLiteDatabase.openDatabase(dbPath, "123", null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
return mDataBase != null;
}
#Override
public synchronized void close() {
if (mDataBase != null)
mDataBase.close();
super.close();
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
i created a database with sqlcipher V3.5.7 and then changed the sqlcipher version to V4.1.3 and had this problem
in build.gradle i changed
implementation "net.zetetic:android-database-sqlcipher:4.1.3#aar"
to
implementation 'net.zetetic:android-database-sqlcipher:3.5.7#aar'
and the problem solved
You are referencing the password string value of 123456Sa, however your call within createDataBase uses the value of 123 as a password to getWritableDatabase.
I was getting this exception only in obfuscation case.
I added default constructors for both ByteArraySerializer and ByteArrayDeserializer classes.
Note: don't add above classes as inner classes. Declare these classes independently add keep these classes in proguard-rules.
Short version: what is the best practice way to access maintain a history for certain messages from both an activity and from a service?
Long version:
I have an activity and a service, which both may be running or not. I want to keep a message log (history) in an object an persist it in a file and be able to e.g. delete entries.
When I have such history in the service and one in the activity I run into sync problems. So, any advice, what the best solution would be?
ideally I could use the methods from the history class in both the service and activity. Probably not possible.
I could write and read the file in each action. Probably not very efficient in the long run.
do I really need to setup a service for the history and handle all actions with it via intents?
It is a bit similiar to "proper way to access DB from both Activity and a started Service?", but with just an own class instead of a SQLite DB.
Any advice?
Conclusion: Use a ContentProvider with a SQLite-DB. Short version of the code:
package com.example.history;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
public class HistoryContentProvider extends ContentProvider {
static final String PROVIDER_NAME = "com.example.HistoryContentProvider";
static final String URL = "content://" + PROVIDER_NAME + "/history";
static final Uri CONTENT_URI = Uri.parse(URL);
static final String id = "id";
static final String normalized_number = "normalized_number";
static final String display_name = "display_name";
static final int uriCode = 1;
static final UriMatcher uriMatcher;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(PROVIDER_NAME, "history", uriCode);
}
#Override
public boolean onCreate() {
Context context = getContext();
DatabaseHelper dbHelper = new DatabaseHelper(context);
db = dbHelper.getWritableDatabase();
if (db != null) {
return true;
}
return false;
}
#Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(TABLE_NAME);
Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
#Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case uriCode:
return "vnd.android.cursor.dir/history";
default:
throw new IllegalArgumentException("Unsupported URI: " + uri);
} }
#Override
public Uri insert(Uri uri, ContentValues values) {
long rowID = db.insert(TABLE_NAME, "", values);
if (rowID > 0) {
Uri _uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
getContext().getContentResolver().notifyChange(_uri, null);
return _uri;
}
throw new SQLException("Failed to add a record into " + uri);
}
#Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int count = 0;
switch (uriMatcher.match(uri)) {
case uriCode:
count = db.delete(TABLE_NAME, selection, selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
return count;
}
#Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int count = 0;
switch (uriMatcher.match(uri)) {
case uriCode:
count = db.update(TABLE_NAME, values, selection, selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
return count;
}
private SQLiteDatabase db;
static final String DATABASE_NAME = "historyDb";
static final String TABLE_NAME = "history";
static final int DATABASE_VERSION = 3;
static final String CREATE_DB_TABLE = " CREATE TABLE " + TABLE_NAME
+ " (id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ normalized_number + " TEXT NOT NULL, "
+ display_name + " TEXT NOT NULL, ";
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_DB_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
}
I have an activity and a service, which both may be running or not. I
want to keep a message log (history) in an object an persist it in a
file and be able to e.g. delete entries.
What you are describing there sounds exactly like a ContentProvider! Link to documentation.
You can use a ContentResolver instance to access data in the ContentProvider from anywhere, be it Activity or Service. The ContentProvider and ContentResolver already handle most of the work for you and basically you just need to implement how you want to save the data in the ContentProvider. The rest is already taken care of! The ContentProvider may have been designed to be used with a SQLiteDatabase - and I would recommend that you use a database - but there is nothing preventing you from saving the data in another way.
If you are not looking for DB style persistence, then maybe a Queue with File backed persistence is what you are looking for:
This maybe of use
https://github.com/square/tape/blob/master/tape/src/main/java/com/squareup/tape/QueueFile.java
Tip: Create a QueueFile singleton in your App class, and access it from your Activities or services.
I have made a TCP client for android using socket. However, the program that I have does not allow me to dynamically input the server address. Also i cannot use intent to transfer String from MainActivity because my TcpClient.java does not extends to Activity. What logic shall I implement so that I can dynamically set server address and connect to any server I wish..
MainActivity.java
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_settings:
Intent i = new Intent(this, Preferences.class);
startActivityForResult(i, RESULT_SETTINGS);
break;
}
return true;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case RESULT_SETTINGS:
saveData();
break;
}
}
public class connectTask extends AsyncTask<String,String,TcpClient> {
#Override
protected TcpClient doInBackground(String... message) {
//we create a TCPClient object and
mTcpClient = new TcpClient(new TcpClient.OnMessageReceived() {
#Override
//here the messageReceived method is implemented
public void messageReceived(String message) {
//this method calls the onProgressUpdate
publishProgress(message);
}
});
mTcpClient.run(serverip, serverport);
return null;
}
}
//call it at Activity startup onStart() for example
public void loadData(){
int mode = Activity.MODE_PRIVATE;
SharedPreferences mySharedPreferences;
mySharedPreferences = getSharedPreferences(MYPREFS, mode);
serverip = mySharedPreferences.getString("IP", serverip);
serverport = mySharedPreferences.getInt("Port", serverport);
}
// Call it whenever you modify the values
public void saveData()
{
int mode = Activity.MODE_PRIVATE;
SharedPreferences mySharedPreferences;
mySharedPreferences = getSharedPreferences(MYPREFS, mode);
SharedPreferences.Editor editor = mySharedPreferences.edit();
editor.putString("IP", serverip);
editor.putInt("Port", serverport);
editor.commit();
Toast.makeText(getBaseContext(),
"Server Settings Saved" + serverip + serverport ,
Toast.LENGTH_LONG).show();
}
}
This is not saving the data. Its showing null0 on the Toast.Also these are the variables declared for the above code
public static final String MYPREFS = "192.168.1.3";
public String serverip;
public int serverport;
Preferences.java
package com.example.homauto;
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class Preferences extends PreferenceActivity{
#SuppressWarnings("deprecation")
#Override
protected void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}
I am a newbie to programming..
Here is the website from where i took the references..Android TCP Connection tutorial
Ok, there are a couple of thing you can do in order to pass the IP and Port to the TCPClient class. For me the easiest one is to declare the run method as follows:
public void run(String srvIP, int srvPort)
{
mRun = true;
try {
//here you must put your computer's IP address.
InetAddress serverAddr = InetAddress.getByName(srvIP);
Log.e("TCP Client", "C: Connecting...");
//create a socket to make the connection with the server
Socket socket = new Socket(serverAddr, srvPort);
You must call it like this:
mTcpClient.run("ServerIP", ServerPort);
like this: mTcpClient.run("192.168.1.25", 4444);
Other possibility is to change the create method and put those parameters there,
// You have to remove the final in these variables
public static String SERVERIP = "192.168.0.102"; //your computer IP address
public static int SERVERPORT = 4444;
public TCPClient(String srvIP, int srvPort, OnMessageReceived listener) {
SERVERIP=srvIP;
SERVERPORT=srvPort;
mMessageListener = listener;
}
and you instantiate the class like this:
mTcpClient = new TcpClient(ServerIP, ServerPort, new TcpClient.OnMessageReceived()
Now, in your application (main activity) you need to put a dialog or another activity in order to ask the user for the IP and port to connect to before you launch the TCPClient class, in your case the AsyncTask.
I'd put an action bar menu and when clicked show a dialog to ask for those values.
Also, you may save the values so that you have them for future use (in MainActivity):
// call it at Activity startup onStart() for example
public void loadData()
{
int mode = Activity.MODE_PRIVATE;
SharedPreferences mySharedPreferences;
mySharedPreferences = getSharedPreferences(Typedefs.saveConfigsFileName, mode);
serverIP = mySharedPreferences.getString("IP", serverIP);
serverPort = mySharedPreferences.getInt("Port", serverPort);
}
// Call it whenever you modify the values
public void saveData()
{
int mode = Activity.MODE_PRIVATE;
SharedPreferences mySharedPreferences;
mySharedPreferences = getSharedPreferences(Typedefs.saveConfigsFileName, mode);
SharedPreferences.Editor editor = mySharedPreferences.edit();
editor.putString("IP", serverIP);
editor.putInt("Port", serverPort);
editor.commit();
}