【问题标题】:Android Studio: App crashes on some phonesAndroid Studio:某些手机上的应用程序崩溃
【发布时间】:2016-09-18 21:13:28
【问题描述】:

我是 android 开发的新手,对这个问题感到非常困惑。 我正在制作一个简单的应用程序,它有 3 个 TextViews:text、text2 和 text3。

  • 文本显示用户的纬度
  • text2 显示用户的经度和
  • text3 显示用户与名为“Azadi Square”的地方之间的距离。

应用程序在 Samsung Galaxy S4Samsung Galaxy Tab S 上正常运行,但在 Huawei Y511@987654324 之一@(我不知道确切的名称。),应用程序无法打开并显示 The App has unfortunately stopped

这是我的 Java 代码:

public class Map extends Activity implements LocationListener {

private TextView text,text2,text3;
private String provider;
private LocationManager locationManager;
private double latitude,longitude;
private Location azadiSquare;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_map);

    text = (TextView)findViewById(R.id.text);
    text2 = (TextView)findViewById(R.id.text2);
    text3 = (TextView)findViewById(R.id.text3);

    locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);

    Criteria criteria = new Criteria();
    provider = locationManager.getBestProvider(criteria,false);

    azadiSquare = new Location(provider);
    azadiSquare.setLatitude(35.6996540);
    azadiSquare.setLongitude(51.3379906);

    Location location = locationManager.getLastKnownLocation(provider);


    text.setText(location.getLatitude()+"");
    text2.setText(location.getLongitude()+"");
    text3.setText(distanceBetweenMeter(azadiSquare,location)+"");
}

@Override
protected void onResume() {
    super.onResume();

    locationManager.requestLocationUpdates(provider,400,1,this);
}

@Override
protected void onPause() {
    super.onPause();

    locationManager.removeUpdates(this);
}

@Override
public void onLocationChanged(Location location) {
    latitude = location.getLatitude();
    longitude = location.getLongitude();

    text.setText(latitude+"");
    text2.setText(longitude+"");

    text3.setText(distanceBetweenMeter(azadiSquare,location)+"");
}

@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
    // TODO Auto-generated method stub
}

@Override
public void onProviderEnabled(String s) {
    Toast.makeText(this,"Enabled new provider " + provider,Toast.LENGTH_LONG).show();
}

@Override
public void onProviderDisabled(String s) {
    Toast.makeText(this,"Disabled provider " + provider,Toast.LENGTH_LONG).show();
}


private double getDistanceFromLatLonInKm(double lat1,double lon1,double lat2,double lon2) {
    double R = 6371; // Radius of the earth in km
    double dLat = deg2rad(lat2-lat1);  // deg2rad below
    double dLon = deg2rad(lon2-lon1);
    double a =
            Math.sin(dLat/2) * Math.sin(dLat/2) +
                    Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
                            Math.sin(dLon/2) * Math.sin(dLon/2)
            ;
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    double d = R * c; // Distance in km
    return d;
}

private double deg2rad(double deg) {
    return deg * (Math.PI/180);
}

private int distanceBetweenMeter(Location location1, Location location2){
    double distanceKM = getDistanceFromLatLonInKm(location1.getLatitude(),location1.getLongitude(),
            location2.getLatitude(),location2.getLongitude());
    int distanceMeter = (int)(distanceKM*1000);
    return distanceMeter;
}
}

注意:我刚刚删除了导入!

清单文件:

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

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".Map" android:screenOrientation="landscape">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

注意:我在打开应用之前打开了手机的位置,所以这不是问题。我想说的另一件事是,所有的计算都没有问题,并且运行良好。

【问题讨论】:

  • 当它在屏幕上显示“不幸已停止”的消息时,那里一定有一些日志。在华为 y511 或索尼 Xperia 上以调试模式运行应用程序并获取日志。编辑您的原始问题并粘贴错误。
  • 你能分享你应用的 build.gradle 吗?

标签: java android android-studio location


【解决方案1】:

Android 6.0 (API level 23) 及更高版本上,您需要在运行时请求ACCESS_COARSE_LOCATIONACCESS_FINE_LOCATION 的权限。见,Requesting Permissions at Run Time。可能就是这样。

【讨论】:

  • 感谢您这么快回答。但我提到的所有手机都有 android 4 或 5...
【解决方案2】:

最好的办法是记录问题并回溯它,这样你就可以看到它哪里出了问题,或者至少有一个线索。如果 user35603 的回答无效,请尝试此操作并发布有关您的问题的 logcat 部分。

【讨论】:

  • 感谢您的回答。我如何在手机上登录?我想我应该说我构建 apk 并将其安装在手机上。所以我不知道如何登录...
  • 在 stackoverflow 上向您展示它的最佳方式是查看这些有用的链接:如果您还没有安装 ADB 驱动程序,您需要安装它们,但我假设您已经拥有它们,因为您有android studio:forum.xda-developers.com/showthread.php?p=48915118然后进入目录或者如果已经用CMD设置了路径然后按照google上的链接使用ADBdeveloper.android.com/studio/command-line/logcat.html
  • 如果你在我的第一条评论后不明白,本教程可以让你明白一点,因为 stackoverflow 不允许太长和太详细的故事:forum.xda-developers.com/showthread.php?t=2141817
  • 其实我知道如何使用 adb 但问题是 adb 没有位置。有什么问题吗?
  • 它不会造成任何问题,因为 adb 只是用作手机和电脑之间的桥梁。如果您成功进行 logcatting,您将看到可能与位置相关的问题发生在哪里。祝你好运
【解决方案3】:

问题终于解决了!这部分代码出了问题:

Location location = locationManager.getLastKnownLocation(provider);

text.setText(location.getLatitude()+"");
text2.setText(location.getLongitude()+"");

我想location 需要一点时间才能获得当前位置。实际上,当 app 想要运行下面这行代码时, location 仍然为 null 并且 app 崩溃了:

text1.setText(location.getLatitude()+"");

我用这样的方法解决了崩溃:

Location location = locationManager.getLastKnownLocation(provider);

while(location==null){}

text.setText(location.getLatitude()+"");
text2.setText(location.getLongitude() + "");
text3.setText(distanceBetweenMeter(azadiSquare,location)+"");

崩溃已解决,但应用程序冻结并出现白屏。我不确切知道,但我猜它被困在 while 循环中。谢谢!

【讨论】:

    【解决方案4】:
    public class MainActivity extends AppCompatActivity {
    
    pb=findViewById(R.id.progressbar);
    Example ex=new Example();//The subclass object is created here
    boolean stop=false;//a boolean variable to start or stop the thread to get location. 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (location== null) {
            showSettingDialog();//this will show your custom way of displaying 
                                  //the location setting intent
            new Thread(ex).start();//here the fetching location gets started
        }
        else{
           //here write code after your location is fetched
           //here to got some other base activity or stay in this
            finish();//if you wan to stay in this activity then omit this line.
        }
    }
    
    public class Example implements Runnable{ //This is a sub class in your main activity.
    
        @Override
        public void run() {//overriding run medthod
                try {
    
                    while(location==null) { //this part keeps on running whithout 
                                             //ui freeze
                         if (stop) {
                            return;
                        }
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                pb.setVisibility(View.VISIBLE);
                            }
                        });
    
                        getLastLocation();//this function will fetch location.
                        Thread.sleep(1500);
                        pb.setVisibility(View.INVISIBLE);
                        if (location != null) {
                            //do your code here
                            stop = true;
                            finish();
                        }
                    }
                }
    
    
                 catch(InterruptedException e){
                            e.printStackTrace();
                        }
                    }
    
                }
    
            }
    

    【讨论】:

    • 请解释您的答案,而不是简单地发布代码片段。其他用户应该能够从您的回答中学习。
    • 嘿,大卫!这里的问题是当您的位置未打开或您的 gps 由于 gps 信号低而无法获取位置时。为避免此问题,只需让您的应用在 ui 线程和后台线程中显示一些进度条,并使用 while 状态语句来获取位置,这样 ui 就不会看起来像冻结一样,您也会在后台线程中获得位置。
    • 很好,但请尝试以解释的方式更新您的答案。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2012-12-12
    • 1970-01-01
    • 1970-01-01
    • 2013-02-17
    • 2013-11-26
    • 2022-07-18
    • 1970-01-01
    • 2010-09-13
    相关资源
    最近更新 更多