2014年10月13日更新:添加了togglegps.class
您好我有一个简单的项目,有两个按钮来启动和停止gps服务。
一旦我点击开始按钮启动服务,应用程序就会关闭。
我得到以下logcat
10-12 14:23:18.424: I/Choreographer(1300): Skipped 36 frames! The application may be doing too much work on its main thread.
10-12 14:23:18.504: D/gralloc_goldfish(1300): Emulator without GPU emulation detected.
10-12 14:24:07.794: E/Google(1300): Service Created
10-12 14:24:07.834: D/AndroidRuntime(1300): Shutting down VM
10-12 14:24:07.864: W/dalvikvm(1300): threadid=1: thread exiting with uncaught exception (group=0xb2a3fba8)
10-12 14:24:07.894: E/AndroidRuntime(1300): FATAL EXCEPTION: main
10-12 14:24:07.894: E/AndroidRuntime(1300): Process: com.example.newtrack, PID: 1300
10-12 14:24:07.894: E/AndroidRuntime(1300): java.lang.RuntimeException: Unable to start service com.example.newtrack.AndroidLocationServices@b2d1b4e8 with Intent { cmp=com.example.newtrack/.AndroidLocationServices }: java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.location.GPS_ENABLED_CHANGE from pid=1300, uid=10052
10-12 14:24:07.894: E/AndroidRuntime(1300): at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2719)
10-12 14:24:07.894: E/AndroidRuntime(1300): at android.app.ActivityThread.access$2100(ActivityThread.java:135)
10-12 14:24:07.894: E/AndroidRuntime(1300): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1293)
10-12 14:24:07.894: E/AndroidRuntime(1300): at android.os.Handler.dispatchMessage(Handler.java:102)
10-12 14:24:07.894: E/AndroidRuntime(1300): at android.os.Looper.loop(Looper.java:136)
10-12 14:24:07.894: E/AndroidRuntime(1300): at android.app.ActivityThread.main(ActivityThread.java:5017)
10-12 14:24:07.894: E/AndroidRuntime(1300): at java.lang.reflect.Method.invokeNative(Native Method)
10-12 14:24:07.894: E/AndroidRuntime(1300): at java.lang.reflect.Method.invoke(Method.java:515)
10-12 14:24:07.894: E/AndroidRuntime(1300): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
10-12 14:24:07.894: E/AndroidRuntime(1300): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
10-12 14:24:07.894: E/AndroidRuntime(1300): at dalvik.system.NativeStart.main(Native Method)
10-12 14:24:07.894: E/AndroidRuntime(1300): Caused by: java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.location.GPS_ENABLED_CHANGE from pid=1300, uid=10052
10-12 14:24:07.894: E/AndroidRuntime(1300): at android.os.Parcel.readException(Parcel.java:1465)
10-12 14:24:07.894: E/AndroidRuntime(1300): at android.os.Parcel.readException(Parcel.java:1419)
10-12 14:24:07.894: E/AndroidRuntime(1300): at android.app.ActivityManagerProxy.broadcastIntent(ActivityManagerNative.java:2373)
10-12 14:24:07.894: E/AndroidRuntime(1300): at android.app.ContextImpl.sendBroadcast(ContextImpl.java:1127)
10-12 14:24:07.894: E/AndroidRuntime(1300): at android.content.ContextWrapper.sendBroadcast(ContextWrapper.java:365)
10-12 14:24:07.894: E/AndroidRuntime(1300): at com.example.newtrack.ToggleGPS.turnGPSOn(ToggleGPS.java:53)
10-12 14:24:07.894: E/AndroidRuntime(1300): at com.example.newtrack.AndroidLocationServices.onStart(AndroidLocationServices.java:58)
10-12 14:24:07.894: E/AndroidRuntime(1300): at android.app.Service.onStartCommand(Service.java:450)
10-12 14:24:07.894: E/AndroidRuntime(1300): at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2702)
10-12 14:24:07.894: E/AndroidRuntime(1300): ... 10 more
10-12 14:24:11.544: I/Process(1300): Sending signal. PID: 1300 SIG: 9
我无法启动服务的原因是什么? 什么可以添加到主要活动?
清单具有所有权限并且服务已注册
以下是我的主要活动
package com.example.newtrack;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//start the service
public void onClickStartServie(View V)
{
//start the service from here //MyService is your service class name
startService(new Intent(this, AndroidLocationServices.class));
}
//Stop the started service
public void onClickStopService(View V)
{
//Stop the running service from here//MyService is your service class name
//Service will only stop if it is already running.
stopService(new Intent(this, AndroidLocationServices.class));
}
}
如上所述,只有两个onclicks用于启动和停止服务
调用的主要服务是以下
package com.example.newtrack;
import org.json.JSONArray;
import org.json.JSONObject;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.util.Log;
public class AndroidLocationServices extends Service {
WakeLock wakeLock;
private LocationManager locationManager;
public AndroidLocationServices() {
// TODO Auto-generated constructor stub
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
PowerManager pm = (PowerManager) getSystemService(this.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DoNotSleep");
// Toast.makeText(getApplicationContext(), "Service Created",
// Toast.LENGTH_SHORT).show();
Log.e("Google", "Service Created");
}
@Override
@Deprecated
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
new ToggleGPS(getApplicationContext()).turnGPSOn();
// Toast.makeText(getApplicationContext(), "Service Started",
// Toast.LENGTH_SHORT).show();
Log.e("Google", "Service Started");
locationManager = (LocationManager) getApplicationContext()
.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
5000, 5, listener);
}
private LocationListener listener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
Log.e("Google", "Location Changed");
if (location == null)
return;
if (isConnectingToInternet(getApplicationContext())) {
JSONArray jsonArray = new JSONArray();
JSONObject jsonObject = new JSONObject();
try {
Log.e("latitude", location.getLatitude() + "");
Log.e("longitude", location.getLongitude() + "");
jsonObject.put("latitude", location.getLatitude());
jsonObject.put("longitude", location.getLongitude());
jsonArray.put(jsonObject);
Log.e("request", jsonArray.toString());
new LocationWebService().execute(new String[] {
Constants.TRACK_URL, jsonArray.toString() });
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
};
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
new ToggleGPS(getApplicationContext()).turnGPSOff();
wakeLock.release();
}
public static boolean isConnectingToInternet(Context _context) {
ConnectivityManager connectivity = (ConnectivityManager) _context
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity != null) {
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null)
for (int i = 0; i < info.length; i++)
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
return false;
}
}
我也发布了我的清单
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.newtrack"
android:versionCode="1"
android:versionName="1.0" >
<!-- Permissions to record locations -->
<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.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.newtrack.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.example.newtrack.AndroidLocationServices" />
<receiver android:name="AlarmReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
我用来开启gps的课程如下
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.provider.Settings;
/**
*
* @author Atish Agrawal
*
*/
public class ToggleGPS {
Context context;
public ToggleGPS(Context context) {
this.context = context;
}
public boolean canToggleGPS() {
PackageManager pacman = context.getPackageManager();
PackageInfo pacInfo = null;
try {
pacInfo = pacman.getPackageInfo("com.android.settings",
PackageManager.GET_RECEIVERS);
} catch (NameNotFoundException e) {
return false; // package not found
}
if (pacInfo != null) {
for (ActivityInfo actInfo : pacInfo.receivers) {
// test if recevier is exported. if so, we can toggle GPS.
if (actInfo.name
.equals("com.android.settings.widget.SettingsAppWidgetProvider")
&& actInfo.exported) {
return true;
}
}
}
return false; // default
}
public void turnGPSOn() {
Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", true);
this.context.sendBroadcast(intent);
String provider = Settings.Secure.getString(
context.getContentResolver(),
Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
if (!provider.contains("gps")) {
// if gps is disabled
final Intent poke = new Intent();
poke.setClassName("com.android.settings",
"com.android.settings.widget.SettingsAppWidgetProvider");
poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
poke.setData(Uri.parse("3"));
this.context.sendBroadcast(poke);
}
}
public void turnGPSOff() {
String provider = Settings.Secure.getString(
context.getContentResolver(),
Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
if (provider.contains("gps")) { // if gps is enabled
final Intent poke = new Intent();
poke.setClassName("com.android.settings",
"com.android.settings.widget.SettingsAppWidgetProvider");
poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
poke.setData(Uri.parse("3"));
this.context.sendBroadcast(poke);
}
}
}
如果可能,请在@neo
发表评论之后说明我应该更改的内容任何评论都是apreciated
非常感谢你。答案 0 :(得分:0)
您可以在跟踪中看到下面的例外行:
10-12 14:24:07.894: E/AndroidRuntime(1300): at com.example.newtrack.ToggleGPS.turnGPSOn(ToggleGPS.java:53)
之前的错误是让您通过发送广播启用设置(现在已修复)。因此,您需要让用户使用下面给出的意图手动启用GPS设置。
startActivity(context, new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));