java - 在启动时将位置发送到 Google 表单(如何在启动时运行 MainActivity)

标签 java android android-studio google-forms

所以我几乎是 Android Studio 的初学者,但我已经差不多了。我的目标是将经度、纬度和一些其他数据传输到 google 上的表格。当我按下按钮 (button2) 时它工作,但我希望它启动 Activity 以在启动时发送数据。所以我得到了一个引导接收器,但它只启动应用程序而不启动发送数据的 Activity 。希望有人能帮助我。如果有什么不清楚的地方,请询问。

我的服务.java:

package com.test.example.phonelocationnew;

import android.app.Service;
import android.content.Intent;
import android.view.View;
import android.widget.Toast;
import android.os.IBinder;

public class MyService extends Service
{
@Override
public void onCreate(){

}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
    Toast.makeText(this, "Service started...", Toast.LENGTH_LONG).show();
    return START_STICKY;
}

@Override
public void onDestroy()
{
    super.onDestroy();
    Toast.makeText(this, "Service destroyed...", Toast.LENGTH_LONG).show();
}
@Override
public IBinder onBind(Intent intent) {
    return null;
}
}

BootReceiver.java:

package com.test.example.phonelocationnew;

import android.content.Context;
import android.content.BroadcastReceiver;
import android.content.Intent;

public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {

    if (intent.getAction().equalsIgnoreCase(Intent.ACTION_BOOT_COMPLETED)) {
        Intent serviceIntent = new Intent(context, MyService.class);
        context.startService(serviceIntent);
    }
}
}

主要 Activity .java:

    package com.test.example.phonelocationnew;

import android.Manifest;
import android.content.res.Configuration;
import android.location.GpsSatellite;
import android.os.AsyncTask;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.app.Activity;
import android.telephony.TelephonyManager;
import android.widget.Button;
import android.widget.Toast;


import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;

import android.view.View;
import android.widget.TextView;

import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import java.net.*;
import java.util.concurrent.TimeUnit;


public class MainActivity extends Activity implements LocationListener{

    public static final MediaType FORM_DATA_TYPE = MediaType.parse("application/x-www-form-urlencoded; charset=utf-8");
    //URL derived from form URL
    public static final String URL = "URL";
    //input element ids found from the live form page
    public static final String LAT="entry_1903202747";
    public static final String LONG="entry_1549783406";
    public static final String MOD="entry_1161588883";
    public static final String MAN="entry_852582911";
    public static final String IMEI="entry_738564261";
    public static final String EXIP="entry_1256979126";
    public static final String ACC="entry_1601482207";


    private Context context;

    LocationManager locationmanager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout);
        context=this;

        Intent intent = new Intent(this, MyService.class);
        startService(intent);

        Button button2 = (Button)findViewById(R.id.button2);

        final TextView textView3 = (TextView) findViewById(R.id.textView3);
        final TextView textView5 = (TextView) findViewById(R.id.textView5);
        final TextView textView12 = (TextView) findViewById(R.id.textView12);
        final TextView textView13 = (TextView) findViewById(R.id.textView13);
        final TextView textView14 = (TextView) findViewById(R.id.textView14);
        final TextView textView7 = (TextView) findViewById(R.id.textView7);
        final TextView textView15 = (TextView) findViewById(R.id.textView15);



        locationmanager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        Criteria cri = new Criteria();
        String provider = locationmanager.getBestProvider(cri, false);

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},0);
        }

        if (provider != null & !provider.equals("")) {
            Location location = locationmanager.getLastKnownLocation(provider);
            locationmanager.requestLocationUpdates(provider, 30000, 0, this); //original (provider,minimalTime,minimalDistance,this); (provider,1800000,0,this) = 30 minutes; 0 distance change

            if (location != null) {
                onLocationChanged(location);
            } else {
                Toast.makeText(getApplicationContext(), "location not found", Toast.LENGTH_LONG).show();
            }
        } else {
            Toast.makeText(getApplicationContext(), "Provider is null", Toast.LENGTH_LONG).show();
        }

    }


    @Override
    public void onLocationChanged(Location location) {

        TextView textView3 = (TextView) findViewById(R.id.textView3);
        TextView textView5 = (TextView) findViewById(R.id.textView5);
        TextView textView12 = (TextView) findViewById(R.id.textView12);
        TextView textView13 = (TextView) findViewById(R.id.textView13);
        TextView textView14 = (TextView) findViewById(R.id.textView14);
        TextView textView7 = (TextView) findViewById(R.id.textView7);
        TextView textView15 = (TextView) findViewById(R.id.textView15);


        TelephonyManager mngr = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);

        String strLat="LA "+location.getLatitude();
        String strLong="LO "+location.getLongitude();
        String strAcc=""+location.getAccuracy();
        String strMod=""+ Build.MODEL;
        String strMan=""+ Build.MANUFACTURER;
        String strId=""+ mngr.getDeviceId();

        try{
            URL whatismyip = new URL("http://checkip.amazonaws.com/");
            BufferedReader in = new BufferedReader(new InputStreamReader(whatismyip.openStream()));

            String ip = in.readLine(); //you get the IP as a String
            String strIp =""+ip;
            textView7.setText(strIp);
        }catch(Exception ex) {
            textView7.setText("ERROR");
        }

        textView3.setText(strLat);
        textView5.setText(strLong);
        textView12.setText(strMod);
        textView13.setText(strMan);
        textView14.setText(strId);
        textView15.setText(strAcc);

        final PostDataTask postDataTask = new PostDataTask();
        postDataTask.execute(URL, textView3.getText().toString(), textView5.getText().toString(), textView12.getText().toString(), textView13.getText().toString(), textView14.getText().toString(), textView7.getText().toString(), textView15.getText().toString());

    }

    //Start Service
    public void startService(View view){
        Intent intent = new Intent(this,MyService.class);
        startService(intent);
    }
    //Stop Service
    public void stopService(View view){
        Intent intent = new Intent(this,MyService.class);
        stopService(intent);
    }
    @Override
    public void onStatusChanged(String s, int i, Bundle bundle){
    }

    @Override
    public void onProviderEnabled(String s){
    }

    @Override
    public void onProviderDisabled(String s){
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setContentView(R.layout.layout);
    }

    //AsyncTask to send data as a http POST request
    private class PostDataTask extends AsyncTask<String, Void, Boolean> {

        @Override
        protected Boolean doInBackground(String... contactData) {

            Boolean result = true;
            String url = contactData[0];
            String LATs = contactData[1];

            String LONGs = contactData[2];
            String modS = contactData[3];
            String manS = contactData[4];
            String idS = contactData[5];
            String ipS = contactData[6];
            String accS = contactData[7];

            String postBody="";

            try {
                //all values must be URL encoded to make sure that special characters like & | ",etc.
                //do not cause problems
                postBody = LAT + "=" + URLEncoder.encode(LATs,"UTF-8") +
                        "&" + LONG + "=" + URLEncoder.encode(LONGs,"UTF-8") +
                        "&" + MOD + "=" + URLEncoder.encode(modS,"UTF-8") +
                        "&" + MAN + "=" + URLEncoder.encode(manS,"UTF-8") +
                        "&" + IMEI + "=" + URLEncoder.encode(idS,"UTF-8") +
                        "&" + EXIP + "=" + URLEncoder.encode(ipS,"UTF-8") +
                        "&" + ACC + "=" + URLEncoder.encode(accS,"UTF-8");
            } catch (UnsupportedEncodingException ex) {
                result=false;
            }

            try{
                //Create OkHttpClient for sending request
                OkHttpClient client = new OkHttpClient();
                //Create the request body with the help of Media Type
                RequestBody body = RequestBody.create(FORM_DATA_TYPE, postBody);
                Request request = new Request.Builder()
                        .url(url)
                        .post(body)
                        .build();
                //Send the request
                Response response = client.newCall(request).execute();
            }catch (IOException exception){
                result=false;
            }
            return result;
        }

        @Override
        protected void onPostExecute(Boolean result){
            //Print Success or failure message accordingly
//            try {
//                Thread.sleep(1800000);
//            } catch(InterruptedException ex) {
//                Thread.currentThread().interrupt();
//            }
            Toast.makeText(context,result?"Message successfully sent!":"There was some error in sending message. Please try again after some time.",Toast.LENGTH_LONG).show();
        }

    }
}

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.test.example.phonelocationnew" >

    <uses-permission android:name="android.permission.INTERNET"/>
    <!--<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>-->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

    <uses-sdk  android:maxSdkVersion="21"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        android:configChanges="keyboardHidden|orientation">

        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main"
            android:theme="@style/AppTheme.NoActionBar" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver
            android:name=".BootReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>

        </receiver>

        <service android:name=".MyService" />

    </application>

</manifest>

布局.xml:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity"
    android:background="#620606"
    android:focusable="false"
    android:focusableInTouchMode="false"
    android:nestedScrollingEnabled="false">


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="Latitude = "
        android:id="@+id/textView"
        android:textColor="#ffffff"
        android:textStyle="bold"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:id="@+id/textView3"
        android:layout_alignTop="@+id/textView"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:text="..." />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="Longtitude = "
        android:id="@+id/textView4"
        android:textColor="#ffffff"
        android:textStyle="bold"
        android:layout_below="@+id/textView"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:id="@+id/textView5"
        android:layout_alignTop="@+id/textView4"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:text="..." />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Stop Service"
        android:id="@+id/button"
        android:onClick="stopService"
        android:layout_gravity="center_horizontal"
        android:backgroundTint="#3b2525"
        android:textColor="#ffffff"
        android:layout_alignTop="@+id/button2"
        android:layout_toRightOf="@+id/button2"
        android:layout_toEndOf="@+id/button2" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start Service"
        android:onClick="startService"
        android:id="@+id/button2"
        android:backgroundTint="#3b2525"
        android:textColor="#ffffff"
        android:layout_alignParentBottom="true"
        android:layout_toRightOf="@+id/textView11"
        android:layout_toEndOf="@+id/textView11" />


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="Model = "
        android:id="@+id/textView9"
        android:textColor="#ffffff"
        android:textStyle="bold"
        android:layout_below="@+id/textView8"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="Manufacturer = "
        android:id="@+id/textView10"
        android:textColor="#ffffff"
        android:textStyle="bold"
        android:layout_below="@+id/textView9"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="IMEI = "
        android:id="@+id/textView11"
        android:textColor="#ffffff"
        android:textStyle="bold"
        android:layout_below="@+id/textView10"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="..."
        android:id="@+id/textView12"
        android:layout_above="@+id/textView10"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="..."
        android:id="@+id/textView13"
        android:layout_alignBottom="@+id/textView10"
        android:layout_alignRight="@+id/textView12"
        android:layout_alignEnd="@+id/textView12" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="..."
        android:id="@+id/textView14"
        android:layout_alignTop="@+id/textView11"
        android:layout_alignRight="@+id/textView13"
        android:layout_alignEnd="@+id/textView13" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="External/WIFI IP = "
        android:id="@+id/textView6"
        android:textColor="#ffffff"
        android:textStyle="bold"
        android:layout_below="@+id/textView11"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="..."
        android:id="@+id/textView7"
        android:layout_alignTop="@+id/textView6"
        android:layout_alignRight="@+id/textView14"
        android:layout_alignEnd="@+id/textView14" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="Accuracy (meter) = "
        android:id="@+id/textView8"
        android:textColor="#ffffff"
        android:textStyle="bold"
        android:layout_below="@+id/textView4"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="..."
        android:id="@+id/textView15"
        android:layout_alignTop="@+id/textView8"
        android:layout_alignLeft="@+id/textView12"
        android:layout_alignStart="@+id/textView12" />


</RelativeLayout>

所以为了更好地理解我在我的应用程序中真正想要的是什么,下面是一个解释:

我希望我的 MainActivity 在我的 Android 设备启动时运行,因此它会在我每次启动手机时在后台将位置数据发送到谷歌表单。

最佳答案

boot receiver 没有问题,它可以正确启动你的服务。

问题出在您的服务上,它除了 toast 之外什么都不做。实际的数据发送工作是由 MainActivity 完成的,每次位置发生变化时,无论您点击按钮 2 是否启动服务,即使您点击按钮停止服务,它也会继续,因为,再次,服务不会什么都不做。

您需要做的是将发送数据的代码部分从 MainActivity 移动到服务。

此外,像这样的应用程序将成为出色的电池 killer 。我会降低数据的频率,只获取对您真正重要的内容。

像这样:

public class MyService extends Service {

    private AlarmManager alarmMgr;
    private PendingIntent alarmIntent;
    private double longitude;
    private double latitude;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        //Here you get lat and long
        try {
            LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
            lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 10, locationListener);
            Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
            longitude = location.getLongitude();
            latitude = location.getLatitude();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }


        //You have your latitude and longitude data
        //They are stored in the respective variables
        //Start an AsyncTask to send them wherever you want
        //You could adapt the one in your MainActivity here
        //Or create a different and separate class


        //Here you set an alarm to start the service again in ~15 minutes
        int minutesApart = 15;
        Intent repeat = new Intent(MyService.this, MyService.class);
        alarmIntent = PendingIntent.getService(MyService.this, 0, repeat, 0);
        alarmMgr = (AlarmManager)this.getSystemService(Context.ALARM_SERVICE);
        alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + minutesApart * 1000, alarmIntent);    

        return START_STICKY;
    }


    private final LocationListener locationListener = new LocationListener() {
        public void onLocationChanged(Location location) {
            longitude = location.getLongitude();
            latitude = location.getLatitude();
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {

        }

        @Override
        public void onProviderEnabled(String provider) {

        }

        @Override
        public void onProviderDisabled(String provider) {

        }
    };


    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {
        if (alarmMgr!= null) {
            alarmMgr.cancel(alarmIntent);
        }
        super.onDestroy();
    }
}

您唯一需要做的就是创建 AsyncTask 方法来发送纬度和经度。

附言此服务只能在内存不足时由操作系统停止(当一些内存被释放时它会再次启动),并通过按下 MainActivity 中的“按钮”。

关于java - 在启动时将位置发送到 Google 表单(如何在启动时运行 MainActivity),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34616581/

相关文章:

java - System.loadLibrary() 从静态 block 返回异常

android - Flutter 中的导航堆栈和启动模式是如何处理的?

android - 如何配置警告对话的标题

android - 裁剪ImageViews的Canvas方法

android - GoogleCloudMessaging.unregister 是否删除 token

java - Caused by : java. lang.OutOfMemoryError: Failed to allocate a 341712908 byte allocation with 3854436 free bytes and 90MB 直到OOM

java - 关闭 java InputStream 后内存未释放

android - 如何在按钮单击时显示 DatePickerDialog?

android - 在 Android Studio(在 Mac 上)中启动 AVD(Android 虚拟设备)时遇到问题

java - Vaadin 可视化编辑器中没有可见组件