-2
以下のアクティビティから電話JIAYU J3にインストールされたチュートリアルアプリを起動するたびに致命的な例外が発生します。必要なすべてのアクセス許可とAPIキーが追加されます。 Gradleは視覚的な不具合なく仕上げられます。この問題は、アプリがメイン(カメラ)アクティビティを起動し、約1秒間保持してクラッシュするという問題を解決します。NullPointerExceptionが発生し、カメラビューアクティビティが起動したときに即座に終了します
トレース:
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アクティビティのライフサイクルコード:
@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);
}
}
NativeStartのクラッシュは、通常、layout.xmlに障害があることを意味します。それを投稿してください。 – Squirrelkiller
@MarlonRegenhardt、チップのおかげで!スタックトレースの下にカメラビューアクティビティの.xmlファイルを追加しました。 – kkaun
あなたのプロジェクトにproguardを使用しているようです。依存関係を難読化しないようにproguardのルールを追加しましたか? – Sanjeet