我已经制作了一个将数据发送到我的mysql服务器的表单应用程序。
该应用的工作原理:
当应用程序没有互联网时...如果我有互联网,用户输入数据并提交,但如果我没有互联网访问,并且用户仍然在互联网再次激活时发送数据保存的所有数据都传输到我的mysql服务器
问题
目前一切正常,当有互联网连接时,它会毫无困难地同步。 出于测试目的,我关闭了互联网,然后我添加了一些数据 但是当我打开互联网时,它就没有了系统
我发现了几件事,但我在初学者水平。我找不到任何样品。
我很好地与您分享我的所有代码,以了解我的问题
MainActivity.java
package com.example.hp.myapplication6;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity implements View.OnClickListener
{
/*
* this is the url to our webservice
* make sure you are using the ip instead of localhost
* it will not work if you are using localhost
* */
public static final String URL_SAVE_NAME = "http://192.168.1.100/SqliteSync/saveName.php";
//database helper object
private DatabaseHelper db;
//View objects
private Button buttonSave;
private EditText editTextName;
private ListView listViewNames;
private EditText editTextPrenom;
private EditText editTextAdess;
//List to store all the names
private List<Name> names;
//1 means data is synced and 0 means data is not synced
public static final int NAME_SYNCED_WITH_SERVER = 1;
public static final int NAME_NOT_SYNCED_WITH_SERVER = 0;
//a broadcast to know weather the data is synced or not
public static final String DATA_SAVED_BROADCAST = "net.simplifiedcoding.datasaved";
//Broadcast receiver to know the sync status
private BroadcastReceiver broadcastReceiver;
//adapterobject for list view
private NameAdapter nameAdapter;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerReceiver(new NetworkStateChecker(), new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
//initializing views and objects
db = new DatabaseHelper(this);
names = new ArrayList<>();
buttonSave = (Button) findViewById(R.id.buttonSave);
editTextName = (EditText) findViewById(R.id.editTextName);
listViewNames = (ListView) findViewById(R.id.listViewNames);
editTextPrenom = (EditText) findViewById(R.id.editTextPrenom);
editTextAdess = (EditText) findViewById(R.id.geoadress);
//adding click listener to button
buttonSave.setOnClickListener(this);
//calling the method to load all the stored names
loadNames();
//the broadcast receiver to update sync status
broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//loading the names again
loadNames();
}
};
//registering the broadcast receiver to update sync status
registerReceiver(broadcastReceiver, new IntentFilter(DATA_SAVED_BROADCAST));
}
/*
* this method will
* load the names from the database
* with updated sync status
* */
private void loadNames() {
names.clear();
Cursor cursor = db.getNames();
if (cursor.moveToFirst()) {
do {
Name name = new Name(
cursor.getString(cursor.getColumnIndex(DatabaseHelper.COLUMN_NAME)),
cursor.getString(cursor.getColumnIndex(DatabaseHelper.COLUMN_PRENOM)),
cursor.getString(cursor.getColumnIndex(DatabaseHelper.COLUMN_ADRESS)),
cursor.getInt(cursor.getColumnIndex(DatabaseHelper.COLUMN_STATUS))
);
names.add(name);
} while (cursor.moveToNext());
}
nameAdapter = new NameAdapter(this, R.layout.names, names);
listViewNames.setAdapter(nameAdapter);
}
/*
* this method will simply refresh the list
* */
private void refreshList()
{
nameAdapter.notifyDataSetChanged();
}
/*
* this method is saving the name to ther server
* */
private void saveNameToServer() {
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Saving Name...");
progressDialog.show();
final String name = editTextName.getText().toString().trim();
final String prenom = editTextPrenom.getText().toString().trim();
final String geoadress = editTextAdess.getText().toString().trim();
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL_SAVE_NAME,
new Response.Listener<String>(){
@Override
public void onResponse(String response) {
progressDialog.dismiss();
try {
JSONObject obj = new JSONObject(response);
if (!obj.getBoolean("error")) {
//if there is a success
//storing the name to sqlite with status synced
saveNameToLocalStorage(name,prenom,geoadress, NAME_SYNCED_WITH_SERVER);
} else {
//if there is some error
//saving the name to sqlite with status unsynced
saveNameToLocalStorage(name,prenom,geoadress, NAME_NOT_SYNCED_WITH_SERVER);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
//on error storing the name to sqlite with status unsynced
saveNameToLocalStorage(name,prenom,geoadress, NAME_NOT_SYNCED_WITH_SERVER);
}
}) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("name", name);
params.put("prenom", prenom);
params.put("geoadress",geoadress );
return params;
}
};
VolleySingleton.getInstance(this).addToRequestQueue(stringRequest);
}
//saving the name to local storage
private void saveNameToLocalStorage(String name,String prenom, String geoadress, int status) {
editTextName.setText("");
editTextPrenom.setText("");
editTextAdess.setText("");
db.addName(name,prenom,geoadress, status);
Name n = new Name(name,prenom,geoadress, status);
names.add(n);
refreshList();
}
@Override
public void onClick(View view)
{
saveNameToServer();
}
}
AndroidManifist.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.hp.myapplication6">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="com.example.hp.myapplication6.NetworkStateChecker">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
</application>
</manifest>
NetworkStateCheker.java
package com.example.hp.myapplication6;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
public class NetworkStateChecker extends BroadcastReceiver
{
//context and database helper object
private Context context;
private DatabaseHelper db;
@Override
public void onReceive(Context context, Intent intent)
{
this.context = context;
db = new DatabaseHelper(context);
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
//if there is a network
if (activeNetwork != null) {
//if connected to wifi or mobile data plan
if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI || activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
//getting all the unsynced names
Cursor cursor = db.getUnsyncedNames();
if (cursor.moveToFirst()) {
do {
//calling the method to save the unsynced name to MySQL
saveName(
cursor.getInt(cursor.getColumnIndex(DatabaseHelper.COLUMN_ID)),
cursor.getString(cursor.getColumnIndex(DatabaseHelper.COLUMN_NAME)),
cursor.getString(cursor.getColumnIndex(DatabaseHelper.COLUMN_PRENOM)),
cursor.getString(cursor.getColumnIndex(DatabaseHelper.COLUMN_ADRESS))
);
} while (cursor.moveToNext());
}
}
}
}
/*
* method taking two arguments
* name that is to be saved and id of the name from SQLite
* if the name is successfully sent
* we will update the status as synced in SQLite
* */
private void saveName(final int id, final String name, final String prenom, final String geoadress) {
StringRequest stringRequest = new StringRequest(Request.Method.POST, MainActivity.URL_SAVE_NAME,
new Response.Listener<String>(){
@Override
public void onResponse(String response) {
try {
JSONObject obj = new JSONObject(response);
if (!obj.getBoolean("error")) {
//updating the status in sqlite
db.updateNameStatus(id, MainActivity.NAME_SYNCED_WITH_SERVER);
//sending the broadcast to refresh the list
context.sendBroadcast(new Intent(MainActivity.DATA_SAVED_BROADCAST));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
})
{
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("name", name);
params.put("prenom", prenom);
params.put("geoadress", geoadress);
return params;
}
};
VolleySingleton.getInstance(context).addToRequestQueue(stringRequest);
}
}
NameAdapter.java
package com.example.hp.myapplication6;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
public class NameAdapter extends ArrayAdapter<Name>
{
//storing all the names in the list
private List<Name> names;
//context object
private Context context;
public NameAdapter(@NonNull Context context, int resource, @NonNull List<Name> names)
{
super(context, resource, names);
this.context = context;
this.names = names;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent)
{
//getting the layoutinflater
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//getting listview itmes
View listViewItem = inflater.inflate(R.layout.names, null, true);
TextView textViewName = (TextView) listViewItem.findViewById(R.id.textViewName);
ImageView imageViewStatus = (ImageView) listViewItem.findViewById(R.id.imageViewStatus);
//getting the current name
Name name = names.get(position);
//setting the name to textview
textViewName.setText(name.getName());
//if the synced status is 0 displaying
//queued icon
//else displaying synced icon
if (name.getStatus() == 0)
imageViewStatus.setBackgroundResource(R.drawable.stopwatch);
else
imageViewStatus.setBackgroundResource(R.drawable.success);
return listViewItem;
}
}
Name.java
package com.example.hp.myapplication6;
public class Name
{
private String name;
private String prenom;
private String geoadress;
private int status;
public Name(String name,String prenom,String geoadress, int status) {
this.name = name;
this.prenom = prenom;
this.geoadress = geoadress;
this.status = status;
}
public String getName()
{
return name;
}
public int getStatus()
{
return status;
}
}
VolleySingleton.java
package com.example.hp.myapplication6;
import android.content.Context;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
public class VolleySingleton
{
private static VolleySingleton mInstance;
private RequestQueue mRequestQueue;
private static Context mCtx;
private VolleySingleton(Context context) {
mCtx = context;
mRequestQueue = getRequestQueue();
}
public static synchronized VolleySingleton getInstance(Context context) {
if (mInstance == null) {
mInstance = new VolleySingleton(context);
}
return mInstance;
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
// getApplicationContext() is key, it keeps you from leaking the
// Activity or BroadcastReceiver if someone passes one in.
mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
}
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> req) {
getRequestQueue().add(req);
}
}
DataBaseHelper.java
package com.example.hp.myapplication6;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DatabaseHelper extends SQLiteOpenHelper
{
//Constants for Database name, table name, and column names
public static final String DB_NAME = "NamesDB";
public static final String TABLE_NAME = "contacts";
public static final String COLUMN_ID = "id";
public static final String COLUMN_NAME = "name";
public static final String COLUMN_PRENOM = "prenom";
public static final String COLUMN_ADRESS = "geoadress";
public static final String COLUMN_STATUS = "status";
//database version
private static final int DB_VERSION = 1;
public DatabaseHelper(Context context)
{
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db)
{
String sql = "CREATE TABLE " + TABLE_NAME + "(" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COLUMN_NAME + " VARCHAR, " + COLUMN_PRENOM + " VARCHAR, " + COLUMN_ADRESS + " VARCHAR, " + COLUMN_STATUS + " TINYINT);";
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int OldVersion, int NewVersion)
{
String sql = "DROP TABLE IF EXISTS contacts";
db.execSQL(sql);
onCreate(db);
}
/*
* This method is taking two arguments
* first one is the name that is to be saved
* second one is the status
* 0 means the name is synced with the server
* 1 means the name is not synced with the server
* */
public boolean addName(String name,String prenom,String geoadress, int status) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COLUMN_NAME, name);
contentValues.put(COLUMN_PRENOM, prenom);
contentValues.put(COLUMN_PRENOM, geoadress);
contentValues.put(COLUMN_STATUS, status);
db.insert(TABLE_NAME, null, contentValues);
db.close();
return true;
}
/*
* This method taking two arguments
* first one is the id of the name for which
* we have to update the sync status
* and the second one is the status that will be changed
* */
public boolean updateNameStatus(int id, int status) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COLUMN_STATUS, status);
db.update(TABLE_NAME, contentValues, COLUMN_ID + "=" + id, null);
db.close();
return true;
}
/*
* this method will give us all the name stored in sqlite
* */
public Cursor getNames() {
SQLiteDatabase db = this.getReadableDatabase();
String sql = "SELECT * FROM " + TABLE_NAME + " ORDER BY " + COLUMN_ID + " ASC;";
Cursor c = db.rawQuery(sql, null);
return c;
}
/*
* this method is for getting all the unsynced name
* so that we can sync it with database
* */
public Cursor getUnsyncedNames() {
SQLiteDatabase db = this.getReadableDatabase();
String sql = "SELECT * FROM " + TABLE_NAME + " WHERE " + COLUMN_STATUS + " = 0;";
Cursor c = db.rawQuery(sql, null);
return c;
}
}
activityMain.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.hp.myapplication6.MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="@+id/relativeLayout">
</RelativeLayout>
<EditText
android:id="@+id/editTextName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/relativeLayout"
android:layout_weight="3"
android:hint="Enter nom" />
<EditText
android:id="@+id/editTextPrenom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/editTextName"
android:layout_weight="3"
android:hint="Enter prenom" />
<Button
android:id="@+id/buttonSave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/geoadress"
android:layout_weight="1"
android:text="Save" />
<ListView
android:id="@+id/listViewNames"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"></ListView>
<EditText
android:id="@+id/geoadress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/editTextPrenom"
android:ems="10"
android:hint="geoadress"
android:inputType="textPersonName" />
</RelativeLayout>
names.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="Name"
android:layout_alignParentLeft="true"
android:id="@+id/textViewName"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:background="@drawable/success"
android:layout_alignParentRight="true"
android:id="@+id/imageViewStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
答案 0 :(得分:0)
public boolean isOnline(Context mContext){
ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
//should check null because in airplane mode it will be null
return (netInfo != null && netInfo.isConnected());
}