每次启动教程应用程序时都会出现致命异常,该应用程序清楚地安装在手机JIAYU J3上,来自下面列出的活动。添加了所有必需的权限和api密钥。 Gradle构建完成而没有可视的失败。问题就是这样:应用程序启动主(摄像机)活动,保持约1秒钟并崩溃。
追踪:
10-13 15:44:55.881 10891-10891/es.esy.kkaun.procrastinant E/dalvikvm: Could not find class 'android.os.UserManager', referenced from method com.google.android.gms.common.l.k
10-13 15:44:55.927 10891-10891/es.esy.kkaun.procrastinant E/dalvikvm: Could not find class 'android.app.AppOpsManager', referenced from method com.google.android.gms.c.aw.a
10-13 15:44:57.240 10891-10891/es.esy.kkaun.procrastinant E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.NullPointerException
at android.support.v4.a.a.a(Unknown Source)
at es.esy.kkaun.procrastinant.c.a(Unknown Source)
at com.google.android.gms.common.internal.r.a(Unknown Source)
at com.google.android.gms.c.x.a(Unknown Source)
at com.google.android.gms.c.v.g(Unknown Source)
at com.google.android.gms.c.v.a(Unknown Source)
at com.google.android.gms.c.z.a(Unknown Source)
at com.google.android.gms.c.r.a(Unknown Source)
at com.google.android.gms.common.internal.q$1.a(Unknown Source)
at com.google.android.gms.common.internal.j$j.a(Unknown Source)
at com.google.android.gms.common.internal.j$a.a(Unknown Source)
at com.google.android.gms.common.internal.j$a.a(Unknown Source)
at com.google.android.gms.common.internal.j$e.c(Unknown Source)
at com.google.android.gms.common.internal.j$d.handleMessage(Unknown Source)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:4624)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:809)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:576)
at dalvik.system.NativeStart.main(Native Method)
Layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<SurfaceView
android:id="@+id/cameraview"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/icon"
android:layout_width="96dp"
android:layout_height="96dp"
android:src="@drawable/obj1"
android:visibility="invisible"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<TextView
android:id="@+id/cameraTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Large Text"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Map"
android:id="@+id/btnMap"
android:layout_marginBottom="23dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" />
<ImageView
android:layout_width="224dp"
android:layout_height="224dp"
android:id="@+id/imageView"
android:src="@drawable/reticle"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
清单文件:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<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"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@android:style/Theme.NoTitleBar"
android:name="android.support.multidex.MultiDexApplication">
<activity
android:name="es.esy.kkaun.procrastinant.CameraViewActivity"
android:label="@string/activity_camera_view">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="es.esy.kkaun.procrastinant.MapsActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="es.esy.kkaun.procrastinant.CameraViewActivity" />
</activity>
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="***api key added***" />
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"/>
</application>
Butched activity lifecycle code:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout. activity_camera_view);
setRequestedOrientation(ActivityInfo. SCREEN_ORIENTATION_PORTRAIT);
setupListeners();
setupLayout();
setAugmentedRealityPoint();
}
@Override
protected void onResume() {
super.onResume();
myCurrentAzimuth.start();
myCurrentLocation.start();
}
@Override
protected void onStop() {
myCurrentAzimuth.stop();
myCurrentLocation.stop();
super.onStop();
}
最后是完整的活动代码:
public class CameraViewActivity extends Activity implements
SurfaceHolder.Callback, OnLocationChangedListener, OnAzimuthChangedListener, View.OnClickListener {
private Camera mCamera;
private SurfaceHolder mSurfaceHolder;
private boolean isCameraviewOn = false ;
private MObject mPoi;
private double mAzimuthReal = 0 ;
private double mAzimuthTeoretical = 0 ;
private static final double DISTANCE_ACCURACY = 20 ;
private static final double AZIMUTH_ACCURACY = 10 ;
private double mMyLatitude = 0 ;
private double mMyLongitude = 0 ;
public static final double TARGET_LATITUDE = 27.590377 ;
public static final double TARGET_LONGITUDE = 14.425153 ;
private MyCurrentAzimuth myCurrentAzimuth;
private MyCurrentLocation myCurrentLocation;
TextView descriptionTextView;
ImageView pointerIcon;
Button btnMap;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout. activity_camera_view);
setRequestedOrientation(ActivityInfo. SCREEN_ORIENTATION_PORTRAIT);
setupListeners();
setupLayout();
setAugmentedRealityPoint();
}
private void setAugmentedRealityPoint() {
mPoi = new MObject(
getString(R.string. p_name ),
TARGET_LATITUDE, TARGET_LONGITUDE
);
}
public double calculateDistance() {
double dX = mPoi .getPoiLatitude() - mMyLatitude;
double dY = mPoi .getPoiLongtitude() - mMyLongitude;
double distance = (Math. sqrt(Math.pow (dX, 2 ) + Math.pow(dY, 2 )) * 100000 );
return distance;
}
public double calculateTeoreticalAzimuth() {
double dX = mPoi .getPoiLatitude() - mMyLatitude;
double dY = mPoi .getPoiLongtitude() - mMyLongitude ;
double phiAngle;
double tanPhi;
double azimuth = 0;
tanPhi = Math.abs (dY / dX);
phiAngle = Math.atan (tanPhi);
phiAngle = Math.toDegrees (phiAngle);
if (dX > 0 && dY > 0) { // I quater
return azimuth = phiAngle;
} else if (dX < 0 && dY > 0) { // II
return azimuth = 180 - phiAngle;
} else if (dX < 0 && dY < 0) { // III
return azimuth = 180 + phiAngle;
} else if (dX > 0 && dY < 0) { // IV
return azimuth = 360 - phiAngle;
}
return phiAngle;
}
private List<Double> calculateAzimuthAccuracy( double azimuth) {
double minAngle = azimuth - AZIMUTH_ACCURACY ;
double maxAngle = azimuth + AZIMUTH_ACCURACY ;
List<Double> minMax = new ArrayList<Double>();
if (minAngle < 0)
minAngle += 360;
if (maxAngle >= 360)
maxAngle -= 360;
minMax.clear();
minMax.add(minAngle);
minMax.add(maxAngle);
return minMax;
}
private boolean isBetween( double minAngle, double maxAngle, double azimuth) {
if (minAngle > maxAngle) {
if (isBetween( 0, maxAngle, azimuth) && isBetween(minAngle, 360 , azimuth))
return true ;
} else {
if (azimuth > minAngle && azimuth < maxAngle)
return true ;
}
return false;
}
private void updateDescription() {
long distance = ( long ) calculateDistance();
int tAzimut = ( int ) mAzimuthTeoretical ;
int rAzimut = ( int ) mAzimuthReal ;
String text = mPoi.getPoiName()
+ " location:"
+ "\n latitude: " + TARGET_LATITUDE + " longitude: " + TARGET_LONGITUDE
+ "\n Current location:"
+ "\n Latitude: " + mMyLatitude + " Longitude: " + mMyLongitude
+ "\n "
+ "\n Target azimuth: " + tAzimut
+ " \n Current azimuth: " + rAzimut
+ " \n Distance: " + distance;
descriptionTextView.setText(text);
}
public void onAzimuthChanged( float azimuthChangedFrom, float azimuthChangedTo) {
mAzimuthReal = azimuthChangedTo;
mAzimuthTeoretical = calculateTeoreticalAzimuth();
int distance = ( int ) calculateDistance();
pointerIcon = (ImageView) findViewById(R.id. icon );
Drawable myDrawable = getResources().getDrawable(R.drawable.obj1);
pointerIcon.setImageDrawable(myDrawable);
double minAngle = calculateAzimuthAccuracy(mAzimuthTeoretical ).get( 0);
double maxAngle = calculateAzimuthAccuracy(mAzimuthTeoretical ).get( 1);
if ((isBetween(minAngle, maxAngle, mAzimuthReal )) && distance <= DISTANCE_ACCURACY ) {
pointerIcon.setVisibility(View. VISIBLE );
} else {
pointerIcon.setVisibility(View. INVISIBLE );
}
updateDescription();
}
@Override
public void onLocationChanged(Location location) {
mMyLatitude = location.getLatitude();
mMyLongitude = location.getLongitude();
mAzimuthTeoretical = calculateTeoreticalAzimuth();
Toast.makeText (this , "latitude: "+location.getLatitude()+ " longitude: "+location.getLongitude(), Toast. LENGTH_SHORT ).show();
int distance = (int) calculateDistance();
if (mAzimuthReal == 0){
if ( distance <= DISTANCE_ACCURACY) {
pointerIcon.setVisibility(View.VISIBLE);
} else {
pointerIcon.setVisibility(View.INVISIBLE);
}
}
updateDescription();
}
@Override
protected void onResume() {
super.onResume();
myCurrentAzimuth.start();
myCurrentLocation.start();
}
@Override
protected void onStop() {
myCurrentAzimuth.stop();
myCurrentLocation.stop();
super.onStop();
}
private void setupListeners() {
myCurrentLocation = new MyCurrentLocation( this);
myCurrentLocation.buildGoogleApiClient( this );
myCurrentLocation.start();
myCurrentAzimuth = new MyCurrentAzimuth( this, this);
myCurrentAzimuth.start();
}
private void setupLayout() {
descriptionTextView = (TextView) findViewById(R.id.cameraTextView );
btnMap = (Button) findViewById(R.id. btnMap );
btnMap.setVisibility(View. VISIBLE );
btnMap.setOnClickListener( this );
getWindow().setFormat(PixelFormat. UNKNOWN);
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.cameraview );
mSurfaceHolder = surfaceView.getHolder();
mSurfaceHolder.addCallback( this );
mSurfaceHolder.setType(SurfaceHolder. SURFACE_TYPE_PUSH_BUFFERS );
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
if ( isCameraviewOn ) {
mCamera.stopPreview();
isCameraviewOn = false ;
}
if ( mCamera != null ) {
try {
mCamera .setPreviewDisplay( mSurfaceHolder);
mCamera .startPreview();
isCameraviewOn = true ;
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera. open();
mCamera.setDisplayOrientation( 90);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.release();
mCamera = null ;
isCameraviewOn = false ;
}
@Override
public void onClick(View v) {
Intent intent = new Intent( this , MapsActivity. class);
startActivity(intent);
}
}
答案 0 :(得分:0)
问题解决了:从跳跃看起来似乎是由于采用了不合适的目标SDK,appcompat和播放服务版本。