0

我目前正在开发一个从 SQL Server 表中获取详细信息的 Android 应用程序。感谢之前帮助我了解 AsyncTasks 和 JSON 的所有人,我现在可以检索对象了。但是,我从 Android 设备更新表格的尝试并不顺利。

首先,我将从表开始:我有一个由触发器填充的 JobStatus 表,该触发器在将新记录输入到 Jobs 表时运行。运行触发器时,会填充这 4 列,即:-

  • JobStatusID
  • 作业 ID
  • QLSJobID
  • 工作类型

但是,其余 4 个默认为 null,预计将通过 Android 应用程序操作进行更新。他们是:-

  • 纬度
  • 经度
  • 时间完成
  • 日期完成

我已经改编了从这里获得的 WCF Web 服务来执行操作。它本质上是一个 POST 更新操作。

现在,对于 Android 代码。从本质上讲,Android 应用程序发生的情况是,仅当捕获保存/签名按钮时才会更新 JobStatus 条目。为此,用户必须输入他们的姓名并签署 Job,以便将所有信息发送回 JobStatus 表。这是代码:

package com.signonglass;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONStringer;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnCancelListener;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore.Images;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class CaptureSignature extends Activity implements LocationListener
{
    private final static String getJobURI = "http://192.168.0.105:8095/CentralMonitoring/CentralMonitor.svc/getJobStatus/";
    private final static String jobURI = "http://192.168.0.105:8095/CentralMonitoring/CentralMonitor.svc/UpdateJobStatus";

    final Date currentTime = new Date();
    final SimpleDateFormat sdf = new SimpleDateFormat("EEE, MMM d, yyyy HH:mm:ss a z"); 

    //Live Connections
    //private final static String jobURI = "http://192.168.14.9:8092/CentralMonitoring/CentralMonitor.svc/UpdateJobStatus";
    //private final static String getJobURI = "http://192.168.14.9:8092/CentralMonitoring/CentralMonitor.svc/getJobStatus/";
    JSONStringer jobStatToUpdate;
    LinearLayout mContent;
    signature mSignature;
    Button mClear, mGetSign, mCancel;
    public static String tempDir;
    public int count = 1;
    public String current = null;
    private Bitmap mBitmap;
    View mView;
    File mypath;

    //additional variables for capturing details
    Consignments cObj;
    public Handler mHandler;
    JobStatus js = new JobStatus();
    JobStatus jsUpdate;
    double latitude;
    double longitude;
    String datetime;
    TextView tvLoc;
    Location location;
    String transAdd;

    private String uniqueId;
    private EditText yourName;

    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.signature);

        cObj = (Consignments)this.getIntent().getSerializableExtra("Consignment");
        //tempDir = Environment.getExternalStorageDirectory() + "/" + getResources().getString(R.string.external_dir) + "/";

        ContextWrapper cw = new ContextWrapper(getApplicationContext());
        File directory = cw.getDir(getResources().getString(R.string.external_dir), Context.MODE_PRIVATE);

        prepareDirectory();

        Calendar c = Calendar.getInstance();
        c.setTimeZone(TimeZone.getDefault());

        uniqueId = cObj.getJobType() + Integer.toString(cObj.getConsignmentID());

        current = uniqueId + ".jpg";
        mypath = new File(directory, current);

        //Control Properties
        mContent = (LinearLayout) findViewById(R.id.signing);
        mSignature = new signature(this, null);
        mSignature.setBackgroundColor(Color.WHITE);
        mContent.addView(mSignature, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        mClear = (Button)findViewById(R.id.clear);
        mGetSign = (Button)findViewById(R.id.getsign);
        mGetSign.setEnabled(false);
        mCancel = (Button)findViewById(R.id.cancel);
        mView = mContent;

        yourName = (EditText)findViewById(R.id.yourName);

        /* Use the LocationManager class to obtain GPS locations */
        LocationManager mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
        Criteria criteria = new Criteria();

        criteria.setAccuracy(Criteria.ACCURACY_FINE);
        criteria.setPowerRequirement(Criteria.POWER_LOW);
        String provider = mlocManager.getBestProvider(criteria, true);
        location = mlocManager.getLastKnownLocation(provider);

        mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, CaptureSignature.this);
        tvLoc = (TextView)findViewById(R.id.textView1);
        tvLoc.setText("Latitude: "+ location.getLatitude() +", Longitude: "+ location.getLongitude());



        mClear.setOnClickListener(new OnClickListener() 
        {        
            public void onClick(View v) 
            {
                Log.v("log_tag", "Panel Cleared");
                mSignature.clear();
                mGetSign.setEnabled(false);
            }
        });

        mGetSign.setOnClickListener(new OnClickListener() 
        {        
            public void onClick(View v) 
            {
                Log.v("log_tag", "Panel Saved");
                boolean error = captureSignature();
                if(!error)
                {
                    new updateJobStatus().execute(js);
                    mView.setDrawingCacheEnabled(true);
                    mSignature.save(mView);
                    Bundle b = new Bundle();
                    b.putString("status", "done");
                    Intent intent = new Intent();
                    intent.putExtras(b);
                    setResult(RESULT_OK,intent);
                    finish(); 
                }
            }
        });

        //Cancel method - to create pop up button 
        mCancel.setOnClickListener(new OnClickListener() 
        {        
            public void onClick(View v) 
            {
                Log.v("log_tag", "Panel Canceled");
                Bundle b = new Bundle();
                b.putString("status", "cancel");
                Intent intent = new Intent();
                intent.putExtras(b);
                setResult(RESULT_OK,intent);  
                finish();
            }
        });

        new getJobStatus().execute(uniqueId);
    }

    public class getJobStatus extends AsyncTask<String, String, JobStatus>
    {
        private ProgressDialog progressDialog = new ProgressDialog(CaptureSignature.this);
        InputStream inputStream = null;
        String theString = "";
        StringBuilder builder;

        protected void onPreExecute()
        {
            progressDialog.setMessage("Getting " + uniqueId +" to be updated...");
            progressDialog.show();
            progressDialog.setOnCancelListener(new OnCancelListener()
            {
                public void onCancel(DialogInterface arg0)
                {
                    getJobStatus.this.cancel(true);
                }
            });
        }

        @Override
        protected JobStatus doInBackground(String... params)
        {
            try
            {
                DefaultHttpClient client = new DefaultHttpClient();
                String theString = new String("");
                //http get request
                HttpGet request = new HttpGet(getJobURI + cObj.getJobType() + cObj.getConsignmentID());
                //set the hedear to get the data in JSON format
                request.setHeader("Accept", "application/json");
                request.setHeader("Content-type", "application/json");

                //get the response
                HttpResponse response = client.execute(request);
                HttpEntity entity = response.getEntity();
                InputStream is = entity.getContent();
                BufferedReader reader = new BufferedReader(new InputStreamReader(is));

                StringBuilder builder = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null)
                {
                    builder.append(line);
                }
                is.close();

                theString = builder.toString();

                JSONObject jsObj = new JSONObject(theString);
                JSONArray jstat = jsObj.getJSONArray("getJobStatusResult");

                for(int i = 0; i < jstat.length(); i++)
                {
                    JSONObject jst = jstat.getJSONObject(i);
                    js.JobStatusID = jst.getInt("JobStatusID");
                    js.JobID = jst.getInt("JobID");
                    js.JobType = jst.getString("jobType");
                    js.QlsJobID = jst.getInt("qlsJobID");
                    /*js.DateComplete = jst.getString("dateComplete");
                    js.TimeComplete = jst.getString("timeComplete");
                    js.Latitude = jst.getDouble("latitude");
                    js.Longitude = jst.getDouble("longitude");*/
                }   
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
            return js;
        }

        protected void onPostExecute(JobStatus jobStatus)
        {
            this.progressDialog.dismiss();
            jsUpdate = js;
        }
    }


    public class updateJobStatus extends AsyncTask<JobStatus, String, JSONStringer>
    {
        private ProgressDialog progressDialog = new ProgressDialog(CaptureSignature.this);
        InputStream inputStream = null;
        String theString = "";
        StringBuilder builder;

        protected void onPreExecute()
        {
            progressDialog.setMessage("Updating " + uniqueId +"...");
            progressDialog.show();
            progressDialog.setOnCancelListener(new OnCancelListener()
            {
                public void onCancel(DialogInterface arg0)
                {
                    updateJobStatus.this.cancel(true);
                }
            });
        }

        @Override
        protected JSONStringer doInBackground(JobStatus... arg0)
        {
            HttpPut request = new HttpPut(jobURI);

            try
            {
                    sdf.setTimeZone(TimeZone.getTimeZone("AEST"));
                    jobStatToUpdate = new JSONStringer()
                    .object()
                    .key("JobStatusID").value(js.getJobStatusID())
                    .key("JobID").value(js.getJobID())
                    .key("dateComplete").value(js.getDate())
                    .key("latitude").value(js.getLat())
                    .key("longitude").value(js.getClass())
                    .key("timeComplete").value(js.getTime())
                    .key("qlsjobID").value(js.getQLSID())
                    .endObject();

                    StringEntity entity = new StringEntity(jobStatToUpdate.toString());
                    request.setEntity(entity);

                    DefaultHttpClient httpClient = new DefaultHttpClient();
                    HttpResponse response = httpClient.execute(request);

                Log.d("WebInvoke", "Saving : " + response.getStatusLine().getStatusCode()); 
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
            return jobStatToUpdate;
        }


    }


    @Override
    protected void onDestroy()
    {
        //Log.w("GetSignature", "onDestory");
        //super.onDestroy();
    }

    private boolean captureSignature()
    {

        boolean error = false;
        String errorMessage = "";


        if(yourName.getText().toString().equalsIgnoreCase(""))
        {
            errorMessage = errorMessage + "Please enter your Name\n";
            error = true;
        }   

        if(error)
        {
            Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
            toast.setGravity(Gravity.TOP, 105, 50);
            toast.show();
        }

        return error;
    }

    private boolean prepareDirectory() 
    {
        try
        {
            if (makedirs()) 
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        catch (Exception e) 
        {
            e.printStackTrace();
            Toast.makeText(this, "Could not initiate File System.. Is Sdcard mounted properly?", Toast.LENGTH_SHORT).show();
            return false;
        }
    }

    private boolean makedirs() 
    {
        File tempdir = new File(tempDir);
        if (!tempdir.exists())
            tempdir.mkdirs();

        if (tempdir.isDirectory()) 
        {
            File[] files = tempdir.listFiles();
            for (File file : files) 
            {
                if (!file.delete()) 
                {
                    System.out.println("Failed to delete " + file);
                }
            }
        }
        return (tempdir.isDirectory());
    }

    public class signature extends View 
    {
        private static final float STROKE_WIDTH = 5f;
        private static final float HALF_STROKE_WIDTH = STROKE_WIDTH / 2;
        private Paint paint = new Paint();
        private Path path = new Path();

        private float lastTouchX;
        private float lastTouchY;
        private final RectF dirtyRect = new RectF();

        public signature(Context context, AttributeSet attrs) 
        {
            super(context, attrs);
            paint.setAntiAlias(true);
            paint.setColor(Color.BLACK);
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeJoin(Paint.Join.ROUND);
            paint.setStrokeWidth(STROKE_WIDTH);
        }

        public void save(View v) 
        {
            Log.v("log_tag", "Width: " + v.getWidth());
            Log.v("log_tag", "Height: " + v.getHeight());
            if(mBitmap == null)
            {
                mBitmap =  Bitmap.createBitmap (mContent.getWidth(), mContent.getHeight(), Bitmap.Config.RGB_565);;
            }
            Canvas canvas = new Canvas(mBitmap);
            try
            {
                FileOutputStream mFileOutStream = new FileOutputStream(mypath);

                v.draw(canvas); 
                mBitmap.compress(Bitmap.CompressFormat.PNG, 90, mFileOutStream); 
                mFileOutStream.flush();
                mFileOutStream.close();
                String url = Images.Media.insertImage(getContentResolver(), mBitmap, "title", null);
                Log.v("log_tag","url: " + url);

            }
            catch(Exception e) 
            { 
                Log.v("log_tag", e.toString()); 
            } 
        }

        public void clear() 
        {
            path.reset();
            invalidate();
        }

        @Override
        protected void onDraw(Canvas canvas) 
        {
            canvas.drawPath(path, paint);
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) 
        {
            float eventX = event.getX();
            float eventY = event.getY();
            mGetSign.setEnabled(true);

            switch (event.getAction()) 
            {
            case MotionEvent.ACTION_DOWN:
                path.moveTo(eventX, eventY);
                lastTouchX = eventX;
                lastTouchY = eventY;
                return true;

            case MotionEvent.ACTION_MOVE:

            case MotionEvent.ACTION_UP:

                resetDirtyRect(eventX, eventY);
                int historySize = event.getHistorySize();
                for (int i = 0; i < historySize; i++) 
                {
                    float historicalX = event.getHistoricalX(i);
                    float historicalY = event.getHistoricalY(i);
                    expandDirtyRect(historicalX, historicalY);
                    path.lineTo(historicalX, historicalY);
                }
                path.lineTo(eventX, eventY);
                break;

            default:
                debug("Ignored touch event: " + event.toString());
                return false;
            }

            invalidate((int) (dirtyRect.left - HALF_STROKE_WIDTH),
                    (int) (dirtyRect.top - HALF_STROKE_WIDTH),
                    (int) (dirtyRect.right + HALF_STROKE_WIDTH),
                    (int) (dirtyRect.bottom + HALF_STROKE_WIDTH));

            lastTouchX = eventX;
            lastTouchY = eventY;

            return true;
        }

        private void debug(String string)
        {

        }

        private void expandDirtyRect(float historicalX, float historicalY) 
        {
            if (historicalX < dirtyRect.left) 
            {
                dirtyRect.left = historicalX;
            } 
            else if (historicalX > dirtyRect.right) 
            {
                dirtyRect.right = historicalX;
            }

            if (historicalY < dirtyRect.top) 
            {
                dirtyRect.top = historicalY;
            } 
            else if (historicalY > dirtyRect.bottom) 
            {
                dirtyRect.bottom = historicalY;
            }
        }

        private void resetDirtyRect(float eventX, float eventY) 
        {
            dirtyRect.left = Math.min(lastTouchX, eventX);
            dirtyRect.right = Math.max(lastTouchX, eventX);
            dirtyRect.top = Math.min(lastTouchY, eventY);
            dirtyRect.bottom = Math.max(lastTouchY, eventY);
        }
    }

    @Override
    public void onLocationChanged(Location mlocation)
    {
        tvLoc.setText("Latitude: "+ location.getLatitude() +", Longitude: "+ location.getLongitude());
    }

    @Override
    public void onProviderDisabled(String provider)
    {
        // TODO Auto-generated method stub
        Toast.makeText(getApplicationContext(), "GPS Disabled", Toast.LENGTH_SHORT ).show();
    }

    @Override
    public void onProviderEnabled(String provider)
    {
        // TODO Auto-generated method stub
        Toast.makeText(getApplicationContext(), "Gps Enabled", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras)
    {
        // TODO Auto-generated method stub

    }
}

这里的代码是我从这里得到的代码的组合,并进行了一些修改。我已经注释掉了一些东西——它可能会导致错误,但在这一点上,我更着迷于更新 JobStatus 对象。

而且我确信上面的代码,尤其是 UpdateJobTask AsyncTask 需要大量修复。

我运行它没有任何错误,但无论哪种方式都是错误日志:-

05-29 10:33:37.214: W/dalvikvm(17704): threadid=1: thread exiting with uncaught exception (group=0x40f13258)
05-29 10:33:37.226: E/AndroidRuntime(17704): FATAL EXCEPTION: main
05-29 10:33:37.226: E/AndroidRuntime(17704): android.app.SuperNotCalledException: Activity {com.signonglass/com.signonglass.CaptureSignature} did not call through to super.onDestroy()
05-29 10:33:37.226: E/AndroidRuntime(17704):    at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3260)
05-29 10:33:37.226: E/AndroidRuntime(17704):    at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3289)
05-29 10:33:37.226: E/AndroidRuntime(17704):    at android.app.ActivityThread.access$1200(ActivityThread.java:134)
05-29 10:33:37.226: E/AndroidRuntime(17704):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1280)
05-29 10:33:37.226: E/AndroidRuntime(17704):    at android.os.Handler.dispatchMessage(Handler.java:99)
05-29 10:33:37.226: E/AndroidRuntime(17704):    at android.os.Looper.loop(Looper.java:154)
05-29 10:33:37.226: E/AndroidRuntime(17704):    at android.app.ActivityThread.main(ActivityThread.java:4624)
05-29 10:33:37.226: E/AndroidRuntime(17704):    at java.lang.reflect.Method.invokeNative(Native Method)
05-29 10:33:37.226: E/AndroidRuntime(17704):    at java.lang.reflect.Method.invoke(Method.java:511)
05-29 10:33:37.226: E/AndroidRuntime(17704):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:809)
05-29 10:33:37.226: E/AndroidRuntime(17704):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:576)
05-29 10:33:37.226: E/AndroidRuntime(17704):    at dalvik.system.NativeStart.main(Native Method)

提前感谢您的提示和建议!:)

4

1 回答 1

0

要修复错误日志,您应该在 onDestroy() 中调用 super.onDestroy()。

于 2013-05-29T01:46:26.650 回答