所以我几乎是 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/