- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在 Android 上开发了一个 GPS 跟踪应用程序。我使用 AlarmManager 每 5 分钟唤醒一次设备。我开发了一个日志文件,显示该应用程序运行良好,直到我收到 public int onStartCommand(Intent intent, int flags, int startId) with startId = 1 again ....在这种情况下我注意到所有变量都被重置所以我再次初始化所有变量..问题是一旦发生这种情况我就会不断得到再次使用 startID = 1 的同一事件,几次调用后应用程序停止,直到我打开 ActivityForm 并再次与服务绑定(bind)!!!
错误事件的日志在这里:
@Jun 17, 2011 3:29:31 AM onStartCommand:flags:0:startId:3:intent:Intent { cmp=com.usegps2_1/.LocationService }
@Jun 17, 2011 3:34:10 AM onStartCommand:flags:0:startId:1:intent:Intent { cmp=com.usegps2_1/.LocationService }
@Jun 17, 2011 3:34:10 AM StartService with mbServiceStarted=TRUE
@Jun 17, 2011 3:34:11 AM call InitGPS
@Jun 17, 2011 3:34:11 AM lastKnownLocation: Location[mProvider=gps,mTime=1308274198000,mLatitude=30.10493179906883,mLongitude=31.379563305705755,mHasAltitude=true,mAltitude=85.0,mHasSpeed=true,mSpeed=0.0,mHasBearing=true,mBearing=313.8908,mHasAccuracy=true,mAccuracy=10.0,mExtras=Bundle[mParcelledData.dataSize=4]]
@Jun 17, 2011 4:48:17 AM onStartCommand:flags:0:startId:1:intent:Intent { cmp=com.usegps2_1/.LocationService }
@Jun 17, 2011 4:48:17 AM StartService with mbServiceStarted=TRUE
@Jun 17, 2011 4:48:17 AM call InitGPS
@Jun 17, 2011 4:48:17 AM lastKnownLocation: Location[mProvider=gps,mTime=1308274198000,mLatitude=30.10493179906883,mLongitude=31.379563305705755,mHasAltitude=true,mAltitude=85.0,mHasSpeed=true,mSpeed=0.0,mHasBearing=true,mBearing=313.8908,mHasAccuracy=true,mAccuracy=10.0,mExtras=Bundle[mParcelledData.dataSize=4]]
GPS 服务代码在这里:
import java.text.DateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.Location;
import android.location.LocationManager;
import android.os.Binder;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.SystemClock;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;
import android.media.*;
public class LocationService extends Service {
/* ------------------------------------- Attributes */
int NOTIFICATION_ID = 11283;
private NotificationManager mNotificationManager;
public MainActivity mMainActivity = null;
protected PowerManager.WakeLock mWakeLock;
protected AlarmManager mAlarMgr;
protected PendingIntent AlarmIntent ;
protected Notification mNotification;
protected PendingIntent mContentIntent;
protected static final double d2r = Math.PI / 180.0;
// Location Variables
protected static final int mAlarmRepeatRate = 5 * 60 * 1000;
protected static final int mLocationTimeMinUpdate = 20000; // minimum time for wait between signals.
protected static final int mLocationDistanceMinUpdate = 25; // minimum meters before call back
protected static final int TWO_MINUTES = 2 * 60 * 1000; // used to define old readings
// TODO : This should be a function in speed. with min & max value.
protected static final int MIN_MapRefreshRate= 10000 ; // rate used to send to webservice.
protected long mLocationNextSentTime;
public String mDeviceID=null;
public String mBatteryLevel=null;
protected String mMobileServiceURL = "http://locationbook.net/Tracking.asmx";
public Boolean mUseGPSOnly;
public Boolean mEnableBeeps ;
public Boolean mEnableDebug;
public String mSpeedText="0";
public boolean mbBeepStarted = false;
public boolean mbStarted = false;
public boolean mbServiceStarted = false;
public Location mLastLocation =null;
protected LocationManager mlocManager ;
protected MainGpsListener mMainGpsListener;
protected MainLocationListener mlocListenerGPS;
protected MainLocationListener mlocListenerNW;
protected ToneGenerator mTG;
protected float mSpeed;
// This is the object that receives interactions from clients. See
// RemoteService for a more complete example.
private final IBinder mBinder = new LocalBinder();
/* EOF Attributes */
/**
* Class for clients to access. Because we know this service always
* runs in the same process as its clients, we don't need to deal with
* IPC.
*/
public class LocalBinder extends Binder {
LocationService getService() {
return LocationService.this;
}
}
/**
* @see android.app.Service#onBind(Intent)
*/
@Override
public IBinder onBind(Intent intent) {
// TODO Put your code here
return mBinder;
}
/**
* @see android.app.Service#onCreate()
*/
@Override
public void onCreate() {
super.onCreate();
// TODO: Input this here to re-create when alarm calls.
mbServiceStarted = false;
com.usegps2_1.Logger.Log(getBaseContext(), "onCreate");
}
/**
* @see android.app.Service#onStart(Intent,int)
*/
@Override
public void onStart(Intent intent, int startId) {
// TODO Put your code here
super.onStart(intent, startId);
}
@Override
public void onDestroy() {
if (mEnableDebug)Logger.Log(getBaseContext(), "onDestroy");
mAlarMgr.cancel(AlarmIntent);
if (mEnableBeeps) mTG.startTone(android.media.ToneGenerator.TONE_DTMF_0,1500);
if (mEnableBeeps) mTG.startTone(android.media.ToneGenerator.TONE_DTMF_2,2500);
// Cancel the persistent notification.
mNotificationManager.cancel(NOTIFICATION_ID); // Remove Notification
if (mbStarted == true)
{
mlocListenerNW.mLocationService=null;
mlocListenerGPS.mLocationService=null;
mMainGpsListener.mLocationService=null;
mlocManager.removeUpdates(mlocListenerNW);
mlocManager.removeUpdates(mlocListenerGPS);
mlocManager=null;
}
/** I assume that this function will not be called except when I want to close
* as mWakeLock prevent it from closing. so we can allow closing the screen here.
*/
mWakeLock.release();
// Tell the user we stopped.
Toast.makeText(this, "Service Exit", Toast.LENGTH_SHORT).show();
super.onDestroy();
}
public int onStartCommand(Intent intent, int flags, int startId) {
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
/**
* http://android-developers.blogspot.com/2010/02/service-api-changes-starting-with.html
* 1- An application calls startService().
* 2- That service gets onCreate(), onStart(), and then spawns a background thread to do some work.
* 3- The system is tight on memory, so has to kill the currently running service.
* 4- Later when memory is free, the service is restarted, and gets onCreate() called but not onStart()
* because there has not been another call to startService() with a new Intent command to send it.
* START_STICKY is basically the same as the previous behavior,
*
* where the service is left "started" and will later be restarted by the system.
* The only difference from previous versions of the platform is that
* it if it gets restarted because its process is killed,
* onStartCommand() will be called on the next instance of the service with a null Intent instead of not being called at all.
* Services that use this mode should always check for this case and deal with it appropriately.
*
* from Android Book.
* [2] The flag parameter can be used to discover how the Service was started. In particular you can use the
* code snippet shown in Listing 9-2 to determine if either of the following cases is true:
* ? START_FLAG_REDELIVERY Indicates that the Intent parameter is a redelivery caused by the
* system run time’s having terminated the Service before it was explicitly stopped by a call to stopSelf.
* ? START_FLAG_RETRY Indicates that the Service has been restarted after an abnormal termination.
* Passed in when the Service was previously set to START_STICKY.
*/
com.usegps2_1.Logger.Log(getBaseContext(), "onStartCommand:flags:" + String.valueOf(flags) + ":startId:" + String.valueOf(startId)+ ":intent:" + intent.toString());
if (intent == null)
{
// TODO If it’s a restart, do something.
updateNotification("Restarted");
if (mTG != null)
{
if (mEnableBeeps) mTG.startTone(android.media.ToneGenerator.TONE_DTMF_5,2000);
}
}
//mAlarMgr.cancel(null);
// see [2]
if ((flags & START_FLAG_RETRY) == 0) {
// FROM DEBUGGING the above condition is wrong it should be != 0.
// PLease check and review before writing code here.
}
else {
// TODO Alternative background process.
}
StartService();
return START_STICKY;
}
/**
* Read preference settings and apply them.
*/
public void ApplyPreferenceSttings()
{
mMobileServiceURL = CustomPreferenceManager.GetServiceURL(getApplication());
mUseGPSOnly= CustomPreferenceManager.GetGPSOnly(getApplication());
mEnableBeeps= CustomPreferenceManager.GetBeepsEnabled(getApplication()) ;
mEnableDebug = CustomPreferenceManager.GetDebugEnabled(getApplication());
}
/**
* Called from outside to start service.
*/
public void StartService ()
{
if (mbServiceStarted == false)
{
mbServiceStarted = true;
// TODO: please remember to use PARTIAL_WAKE_LOCK instead of .SCREEN_DIM_WAKE_LOCK
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
mWakeLock.acquire();
ApplyPreferenceSttings();
if (mEnableDebug)Logger.Log(getBaseContext(), "StartService re-initialize=TRUE");
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
mDeviceID = telephonyManager.getDeviceId();
showNotification();
mTG = new ToneGenerator (1,80);
if (mAlarMgr != null)
if (mEnableDebug)Logger.Log(getBaseContext(), "mAlarMgr is true");
mAlarMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intentToFire = new Intent (GPSBroadcastReceiver.ReceiverName);
AlarmIntent = PendingIntent.getBroadcast(this, 0, intentToFire, 0);
mAlarMgr.cancel(AlarmIntent); //Remove any alarms with a matching Intent. [BUG] avoid creating many alarms ... caused multipl alarm call with mbServiceStarted=False when check debugging files.
mAlarMgr.setRepeating(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime() + mAlarmRepeatRate , mAlarmRepeatRate, AlarmIntent);
// Register in Battery
this.registerReceiver(this.mBatInfoReceiver,new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
StartLocation();
}
else
{
//updateNotification("called again while running");
}
// */
}
protected void showNotification ()
{
mNotificationManager = (NotificationManager) getSystemService (Context.NOTIFICATION_SERVICE);
// Define Notification
mNotification = new Notification(R.drawable.step, "Tracking on", System.currentTimeMillis());
mNotification.flags = Notification.FLAG_ONGOING_EVENT;
// Define Notification Action
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
mContentIntent = PendingIntent.getActivity(LocationService.this, 0,intent, PendingIntent.FLAG_CANCEL_CURRENT);
// Set Notification
mNotification.setLatestEventInfo(LocationService.this,getText(R.string.app_name),"click to display main screen",mContentIntent);
// Add it
mNotificationManager.notify(NOTIFICATION_ID, mNotification);
}
protected void updateNotification (CharSequence Description)
{
if (mNotification ==null) return ;
mNotification.when=System.currentTimeMillis();
// Set Notification
mNotification.setLatestEventInfo(LocationService.this,getText(R.string.app_name),Description,mContentIntent);
// Add it
mNotificationManager.notify(NOTIFICATION_ID, mNotification);
}
/*-------------------------------------------------GPS Methods*/
protected void StartLocation ()
{
if (mbStarted == true)
{
Toast.makeText( getApplicationContext(),"already running",Toast.LENGTH_SHORT).show();
return ;
}
if (mEnableDebug)Logger.Log(getBaseContext(), "InitGPS true");
mbStarted = true;
mLocationNextSentTime = 0 ; // Send once u get data
if (mEnableBeeps) mTG.startTone(android.media.ToneGenerator.TONE_DTMF_1,1000);
// Use the LocationManager class to obtain GPS locations
mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Toast.makeText( getApplicationContext(),"Started",Toast.LENGTH_SHORT).show();
Location loc= mlocManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
// try to read current position
if(loc != null){
mLastLocation=loc;
if (mEnableDebug)Logger.Log(getBaseContext(), "lastKnownLocation: " + loc.toString());
}
else
{
updateNotification ("getting location");
}
mlocListenerGPS = new MainLocationListener(this);
mlocListenerNW = new MainLocationListener(this);
mlocListenerGPS.mProvider="GPS";
mlocListenerNW.mProvider="NW";
mMainGpsListener = new MainGpsListener(this);
// Define a listener that responds to location updates
mlocManager.addGpsStatusListener(mMainGpsListener);
mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, mLocationTimeMinUpdate, mLocationDistanceMinUpdate, mlocListenerGPS);
mlocManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, mLocationTimeMinUpdate, mLocationDistanceMinUpdate, mlocListenerNW);
if (mEnableDebug)Logger.Log(getBaseContext(), "GPS reinitialized");
// */
}
public void UpdateLocation (Location loc, String Provider)
{
try
{
if (mUseGPSOnly && (Provider != "GPS")) return ;
if (mbStarted == false)
{
updateNotification("false");
}
if (mEnableBeeps) mTG.startTone(android.media.ToneGenerator.TONE_DTMF_9,200);
String E = loc.toString();
if (mEnableDebug)Logger.Log(getBaseContext(), "New Location");
if (mEnableDebug)Logger.Log(getBaseContext(), loc.toString());
if (isBetterLocation (loc,mLastLocation)==false)
{
updateNotification ("location ignored");
return ;
}
mLastLocation = loc;
mMainActivity.mtxtTime.setText(DateFormat.getDateInstance().format(new Date()));
mMainActivity.mtxtLatitude.setText(loc.getLatitude() + " lat");
mMainActivity.mtxtLongitude.setText(loc.getLongitude() + " lng");
float speed = loc.getSpeed(); // value if set by GetSpeed that is called insite isBetterLocation
mSpeedText=Float.toString(speed) ;
mMainActivity.mtxtSpeed.setText(mSpeedText + " km/s");
if ((loc.getTime() > mLocationNextSentTime))
{
mLocationNextSentTime = (long) (loc.getTime() + MIN_MapRefreshRate * ( 140 - speed)/ 140);
if (mEnableDebug)Logger.Log(getBaseContext(), "Next HTTP: " + String.valueOf(mLocationNextSentTime));
WebMethodProxy client = new WebMethodProxy(mMobileServiceURL + "/UpdateLocation");
client.AddParam("guid", mDeviceID);
client.AddParam("latitude",Double.toString(loc.getLatitude()));
client.AddParam("longitude", Double.toString(loc.getLongitude()));
client.AddParam("speed", mSpeedText);
client.AddParam("battery",mBatteryLevel);
//if (mEnableBeeps) mTG.startTone(android.media.ToneGenerator.TONE_DTMF_5,500);
try {
client.Execute(WebMethodProxy.RequestMethod.POST_JSON);
} catch (Exception e) {
e.printStackTrace();
// TODO : error message cannot connect to server
if (mEnableBeeps) mTG.startTone(android.media.ToneGenerator.TONE_DTMF_9,2500);
String err = (e.getMessage() == null)?"GPS Error":e.getMessage();
if (mEnableDebug)Logger.Log(getBaseContext(), "Failed: " + err);
Log.e("TrackGPS",err);
mMainActivity.mtxtMessage.setText("Cannot reach Internet to update location.");
return ;
}
String response = client.getResponse();
response = (response ==null)?"no web reply":response;
if (mEnableDebug)Logger.Log(getBaseContext(), "HTTP DONE: " + response );
Toast.makeText( getApplicationContext(),"Updated[" + Provider + "]:" + response,Toast.LENGTH_SHORT).show();
updateNotification ("location updated");
}
else
{
updateNotification ("location ignored.");
}
}
catch (Exception e)
{
if (mEnableBeeps) mTG.startTone(android.media.ToneGenerator.TONE_DTMF_2,2500);
String err = (e.getMessage() == null)?"GPS Error":e.getMessage();
Log.e("TrackGPS",err);
updateNotification ("DEBUG1: " + e.getMessage());
return ;
}
}
/**
* Returns distance in meters between two points.
* @param NewLocation
* @param CurrentLocation
* @return
*/
protected float CalculateSpeed (Location NewLocation, Location CurrentLocation) {
try
{
double dlong = (NewLocation.getLongitude() - CurrentLocation.getLongitude()) * d2r;
double dlat = (NewLocation.getLatitude() - CurrentLocation.getLatitude()) * d2r;
double a = Math.pow(Math.sin(dlat/2.0), 2) + Math.cos(CurrentLocation.getLatitude()*d2r) * Math.cos(NewLocation.getLatitude()*d2r) * Math.pow(Math.sin(dlong/2.0), 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
double d = 6367000 * c;
double TimeDelta = NewLocation.getTime() - CurrentLocation.getTime();
return (float) (d/TimeDelta) * 3600;
}
catch (Exception e)
{
if (mEnableBeeps) mTG.startTone(android.media.ToneGenerator.TONE_DTMF_2,2500);
Log.e("TrackGPS",e.getMessage());
updateNotification ("DEBUG2: " + e.getMessage());
return 0;
}
}
/** Determines whether one Location reading is better than the current Location fix
* Logic:
* if too old return FALSE.
* if too new return TRUE anyway as the current is too old.
* if more accurate then return TRUE
* if newer and same or more accurate then return TRUE.
* if newer and less accurate but same provider return TRUE.
* ------------------------------------------------------
* Time Accuracy Same Provider Return
* ------------------------------------------------------
* Too Old x x FALSE
* Too New x x TRUE
* Older Plus x TRUE
* Newer Plus x TRUE
* Newer Same x TRUE
* Newer Less TRUE TRUE
* ======================================================
* @param location The new Location that you want to evaluate
* @param currentBestLocation The current Location fix, to which you want to compare the new one
*/
protected boolean isBetterLocation(Location location, Location currentBestLocation) {
try
{
location.setSpeed(0); // preset
if (currentBestLocation == null) {
// A new location is always better than no location
if (mEnableDebug)Logger.Log(getBaseContext(), "Accepted: first location");
return true;
}
// Check whether the new location fix is newer or older
long timeDelta = location.getTime() - currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
boolean isNewer = timeDelta > 0;
// If it's been more than two minutes since the current location, use the new location
// because the user has likely moved
if (isSignificantlyNewer) {
if (mEnableDebug)Logger.Log(getBaseContext(), "Accepted: isSignificantlyNewer");
return true;
// If the new location is more than two minutes older, it must be worse
} else if (isSignificantlyOlder) {
if (mEnableDebug)Logger.Log(getBaseContext(), "Rejected: isSignificantlyOlder");
return false;
}
// Check whether the new location fix is more or less accurate
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0;
boolean isMoreAccurate = accuracyDelta < 0;
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
// Check if the old and new location are from the same provider
boolean isFromSameProvider = isSameProvider(location.getProvider(),
currentBestLocation.getProvider());
// Determine location quality using a combination of timeliness and accuracy
if (isMoreAccurate) {
location.setSpeed(CalculateSpeed (location,currentBestLocation));
if (mEnableDebug)Logger.Log(getBaseContext(), "Accepted: isMoreAccurate");
return true;
} else if (isNewer && !isLessAccurate) {
location.setSpeed(CalculateSpeed (location,currentBestLocation));
if (mEnableDebug)Logger.Log(getBaseContext(), "Accepted: isNewer and not isLessAccurate");
return true;
} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
location.setSpeed(CalculateSpeed (location,currentBestLocation));
if (mEnableDebug)Logger.Log(getBaseContext(), "Accepted: isNewer and LessAccurate but from same provider");
return true;
}
if (mEnableDebug)Logger.Log(getBaseContext(), "Rejected: ???");
return false;
}
catch (Exception e)
{
updateNotification ("Debug3: " + e.getMessage());
return false;
}
}
/** Checks whether two providers are the same */
protected boolean isSameProvider(String provider1, String provider2) {
if (provider1 == null) {
return provider2 == null;
}
return provider1.equals(provider2);
}
/*GPS Methods:EOF*/
/*-------------------------------------------------BAT Methods*/
protected BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver(){
@Override
public void onReceive(Context arg0, Intent intent) {
int level = intent.getIntExtra("level", 0);
double voltage= intent.getIntExtra("voltage", 0) ;
double batteryTemperature = intent.getIntExtra("temperature", 0);
// update battery level.
mBatteryLevel = String.valueOf(level);
if (level < 31)
{
mMainActivity.mtxtBatteryInfo.setText("level: " + Double.toString(level) + " pls connect to charger.");
mMainActivity.mtxtBatteryInfo.setTextColor(0xffff0033);
}
else
{
mMainActivity.mtxtBatteryInfo.setText("level: " + Double.toString(level) + "% voltage: " + String.valueOf(Double.toString(voltage / 1000.0)) + " Temp: " + Double.toString(batteryTemperature /10.0) + " c");
mMainActivity.mtxtBatteryInfo.setTextColor(0xff99ff33);
}
}
};
/*BAT Methods:EOF*/
}
最佳答案
我可以在这里看到许多问题。
首先,onStart(Intent intent, int startId) 已弃用,您不需要实现此方法(尤其是如果您只做super.onStart(intent, startId);
)。
其次,您无需在设置重复闹钟之前取消它,因为闹钟管理器会为您做这件事。
最重要的是,您应该只在 onStartCommand 方法执行期间获取唤醒锁。在开始时获取它,然后在结束时释放它 - 最好在 finally
block 内,以便在发生异常时仍然释放锁。在第一次收到 Intent 时获取锁,然后一直持有直到服务终止,防止 CPU 在无事时休眠 - 这会影响电池生命周期。
至于重复传递 Intent - 如果您的服务变量正在重新初始化,那么听起来您的服务正在被 Android 重新启动,因为它已经死了。您是否检查过 logcat(在连接运行时)是否有任何堆栈跟踪?也许将进程 ID 添加到您的日志输出中,以便您可以发现这种情况何时发生。
如果 Android 认为它已变得无响应,则它可能正在终止您的服务。您已经进行了相当多的处理,您可能想考虑将其分解为单独的类 - 这样会更容易理解服务在做什么以及哪里出了问题。
关于android - 报警管理器和 onStartCommand,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6385523/
我最近在/ drawable中添加了一些.gifs,以便可以将它们与按钮一起使用。这个工作正常(没有错误)。现在,当我重建/运行我的应用程序时,出现以下错误: Error: Gradle: Execu
Android 中有返回内部存储数据路径的方法吗? 我有 2 部 Android 智能手机(Samsung s2 和 s7 edge),我在其中安装了一个应用程序。我想使用位于这条路径中的 sqlit
这个问题在这里已经有了答案: What's the difference between "?android:" and "@android:" in an android layout xml f
我只想知道 android 开发手机、android 普通手机和 android root 手机之间的实际区别。 我们不能从实体店或除 android marketplace 以外的其他地方购买开发手
自Gradle更新以来,我正在努力使这个项目达到标准。这是一个团队项目,它使用的是android-apt插件。我已经进行了必要的语法更改(编译->实现和apt->注释处理器),但是编译器仍在告诉我存在
我是android和kotlin的新手,所以请原谅要解决的一个非常简单的问题! 我已经使用导航体系结构组件创建了一个基本应用程序,使用了底部的导航栏和三个导航选项。每个导航选项都指向一个专用片段,该片
我目前正在使用 Facebook official SDK for Android . 我现在正在使用高级示例应用程序,但我不知道如何让它获取应用程序墙/流/状态而不是登录的用户。 这可能吗?在那种情
我在下载文件时遇到问题, 我可以在模拟器中下载文件,但无法在手机上使用。我已经定义了上网和写入 SD 卡的权限。 我在服务器上有一个 doc 文件,如果用户单击下载。它下载文件。这在模拟器中工作正常但
这个问题在这里已经有了答案: What is the difference between gravity and layout_gravity in Android? (22 个答案) 关闭 9
任何人都可以告诉我什么是 android 缓存和应用程序缓存,因为当我们谈论缓存清理应用程序时,它的作用是,缓存清理概念是清理应用程序缓存还是像内存管理一样主存储、RAM、缓存是不同的并且据我所知,缓
假设应用程序 Foo 和 Eggs 在同一台 Android 设备上。任一应用程序都可以获取设备上所有应用程序的列表。一个应用程序是否有可能知道另一个应用程序是否已经运行以及运行了多长时间? 最佳答案
我有点困惑,我只看到了从 android 到 pc 或者从 android 到 pc 的例子。我需要制作一个从两部手机 (android) 连接的 android 应用程序进行视频聊天。我在想,我知道
用于使用 Android 以编程方式锁定屏幕。我从 Stackoverflow 之前关于此的问题中得到了一些好主意,并且我做得很好,但是当我运行该代码时,没有异常和错误。而且,屏幕没有锁定。请在这段代
文档说: android:layout_alignParentStart If true, makes the start edge of this view match the start edge
我不知道这两个属性和高度之间的区别。 以一个TextView为例,如果我将它的layout_width设置为wrap_content,并将它的width设置为50 dip,会发生什么情况? 最佳答案
这两个属性有什么关系?如果我有 android:noHistory="true",那么有 android:finishOnTaskLaunch="true" 有什么意义吗? 最佳答案 假设您的应用中有
我是新手,正在尝试理解以下 XML 代码: 查看 developer.android.com 上的文档,它说“starStyle”是 R.attr 中的常量, public static final
在下面的代码中,为什么当我设置时单选按钮的外观会发生变化 android:layout_width="fill_parent" 和 android:width="fill_parent" 我说的是
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 9
假设我有一个函数 fun myFunction(name:String, email:String){},当我调用这个函数时 myFunction('Ali', 'ali@test.com ') 如何
我是一名优秀的程序员,十分优秀!