繁体   English   中英

扩展到FragmentActivity时,Android应用程序崩溃

[英]Android App Crashes while extending to FragmentActivity

因此,我对Android开发非常陌生。 我一直在开发一个Android Prayer Times应用程序,并且在我想集成Google Play服务(用于位置定位)之前,它一直运行良好。 当我遵循《 访问位置指南》时 ,系统指示我首先进行设置(已经完成),然后再连接到Google Play服务 这就是问题所在。 我浏览了整个页面,介绍了如何连接到Google API,并正确遵循了说明。 然后我意识到我不得不改变自己的

public class MainActivity extends Activity

public class MainAcitvity extends FragmentActivity

按照developer.android.com上的指南进行操作。 之后,当我尝试使用手机时,我的应用将不再运行。

我对Android中的Fragment都不熟悉。 我需要在我的xml文件中放入一个Fragment吗?

这是我的MainActivity.java文件:

package com.ahmed.omar.tawheed;

import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationServices;

import android.support.v4.app.FragmentActivity;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

public class MainActivity extends FragmentActivity
        implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    private TextView txtPrayerNames;
    private TextView txtPrayerTimes;

    private GoogleApiClient mGoogleApiClient;

    // Request code to use when launching the resolution activity
    private static final int REQUEST_RESOLVE_ERROR = 1001;
    // Unique tag for the error dialog fragment
    private static final String DIALOG_ERROR = "dialog_error";
    // Bool to track whether the app is already resolving an error
    private boolean mResolvingError = false;

    private static final String STATE_RESOLVING_ERROR = "resolving_error";

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        txtPrayerNames = (TextView) findViewById(R.id.txtPrayerNames);
        txtPrayerTimes = (TextView) findViewById(R.id.txtPrayerTimes);

        getTimes();

        GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this) //used to connect
                .addConnectionCallbacks(this)                               // to Google Play Services
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();

        mResolvingError = savedInstanceState != null
                && savedInstanceState.getBoolean(STATE_RESOLVING_ERROR, false);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) { //Used to Create App Bar

        // Inflate the menu items for use in the action bar
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main_activity_actions, menu);

        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) { //Used to Handle Presses on App Bar Items
        // Handle presses on the action bar items
        switch (item.getItemId()) {
            case R.id.action_refresh:
                getTimes();
                return true;
            case R.id.action_settings:
                openSettings();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    private void openSettings() { //misc
        Toast.makeText(this, "Settings button pressed", Toast.LENGTH_SHORT).show();
    }

    /********************************************************************/

    @Override
    public void onConnected(Bundle connectionHint) {
        // Connected to Google Play services!
        // The good stuff goes here.
    }

    @Override
    public void onConnectionSuspended(int cause) {
        // The connection has been interrupted.
        // Disable any UI components that depend on Google APIs
        // until onConnected() is called.
    }

    @Override
    public void onConnectionFailed(ConnectionResult result) {
        // This callback is important for handling errors that
        // may occur while attempting to connect with Google.
        //
        if (mResolvingError) {
            // Already attempting to resolve an error.
            return;
        } else if (result.hasResolution()) {
            try {
                mResolvingError = true;
                result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
            } catch (IntentSender.SendIntentException e) {
                // There was an error with the resolution intent. Try again.
                mGoogleApiClient.connect();
            }
        } else {
            // Show dialog using GooglePlayServicesUtil.getErrorDialog()
            showErrorDialog(result.getErrorCode());
            mResolvingError = true;
        }

    }

    /**----------------------------------------------------------------**/

    /* Creates a dialog for an error message */
    private void showErrorDialog(int errorCode) {
        // Create a fragment for the error dialog
        ErrorDialogFragment dialogFragment = new ErrorDialogFragment();
        // Pass the error that should be displayed
        Bundle args = new Bundle();
        args.putInt(DIALOG_ERROR, errorCode);
        dialogFragment.setArguments(args);
        dialogFragment.show(getSupportFragmentManager(), "errordialog");
    }

    /* Called from ErrorDialogFragment when the dialog is dismissed. */
    public void onDialogDismissed() {
        mResolvingError = false;
    }

    /* A fragment to display an error dialog */
    public static class ErrorDialogFragment extends DialogFragment {
        public ErrorDialogFragment() { }

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            // Get the error code and retrieve the appropriate dialog
            int errorCode = this.getArguments().getInt(DIALOG_ERROR);
            return GooglePlayServicesUtil.getErrorDialog(errorCode,
                    this.getActivity(), REQUEST_RESOLVE_ERROR);
        }

        @Override
        public void onDismiss(DialogInterface dialog) {
            ((MainActivity)getActivity()).onDialogDismissed();
        }
    }

    /**----------------------------------------------------------------**/

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_RESOLVE_ERROR) {
            mResolvingError = false;
            if (resultCode == RESULT_OK) {
                // Make sure the app is not already connected or attempting to connect
                if (!mGoogleApiClient.isConnecting() &&
                        !mGoogleApiClient.isConnected()) {
                    mGoogleApiClient.connect();
                }
            }
        }
    }

    /**----------------------------------------------------------------**/

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean(STATE_RESOLVING_ERROR, mResolvingError);
    }

    /**----------------------------------------------------------------**/

    @Override
    protected void onStart() {
        super.onStart();
        if (!mResolvingError) {  // more about this later
            mGoogleApiClient.connect();
        }
    }

    @Override
    protected void onStop() {
        mGoogleApiClient.disconnect();
        super.onStop();
    }

    /********************************************************************/


    // method to append Updated prayer times into TextView in activity_main
    public void getTimes() {

        // Retrieve LATITUDE, LONGITUDE, and TIMEZONE using location API. Currently set for Detroit
        double latitude = 42.3314;
        double longitude = -83.0458;
        double timezone = -5;

        String sFajr, sSunrise, sDhuhr, sAsr, sSunset, sMaghrib, sIsha;

        PrayTime prayers = new PrayTime();

        prayers.setTimeFormat(prayers.Time12);
        prayers.setCalcMethod(prayers.ISNA);
        prayers.setAsrJuristic(prayers.Hanafi);
        prayers.setAdjustHighLats(prayers.None);
        int[] offsets = { 0, 0, 0, 0, 0, 0, 0 }; // {Fajr,Sunrise,Dhuhr,Asr,Sunset,Maghrib,Isha}
        prayers.tune(offsets);

        Date now = new Date();
        Calendar cal = Calendar.getInstance();
        cal.setTime(now);

        ArrayList prayerTimes = prayers.getPrayerTimes(cal, latitude,
                longitude, timezone);
        ArrayList prayerNames = prayers.getTimeNames();


        sFajr = ""+prayerTimes.get(0);
        sSunrise = ""+prayerTimes.get(1);
        sDhuhr = ""+prayerTimes.get(2);
        sAsr = ""+prayerTimes.get(3);
        sSunset = ""+prayerTimes.get(4);
        sMaghrib = ""+prayerTimes.get(5);
        sIsha = ""+prayerTimes.get(6);

        txtPrayerNames.setText("");
        txtPrayerTimes.setText("");

        for (int i = 0; i < 7; i++) {
            txtPrayerNames.append("\n"+prayerNames.get(i));
            txtPrayerTimes.append("\n"+prayerTimes.get(i));
        }

        Toast.makeText(this, "Prayer Times Updated", Toast.LENGTH_SHORT).show();

    }
}

这是我的activity_main.xml文件:

<RelativeLayout

    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Detroit, MI"
        android:gravity="center"
        android:layout_centerHorizontal="true"
        android:textSize="40sp"
        android:layout_margin="32dp"/>

    <TextView
        android:id="@+id/txtPrayerNames"
        android:gravity="left"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:textSize="35sp"
        android:layout_margin="32dp"/>

    <TextView
        android:id="@+id/txtPrayerTimes"
        android:gravity="right"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:textSize="35sp"
        android:layout_margin="32dp"/>


</RelativeLayout>

最后是logcat:

01-16 23:16:18.457    2030-2030/com.ahmed.omar.tawheed I/art﹕ Late-enabling -Xcheck:jni
01-16 23:16:18.643    2030-2030/com.ahmed.omar.tawheed D/AndroidRuntime﹕ Shutting down VM
01-16 23:16:18.644    2030-2030/com.ahmed.omar.tawheed E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.ahmed.omar.tawheed, PID: 2030
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ahmed.omar.tawheed/com.ahmed.omar.tawheed.MainActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'void com.google.android.gms.common.api.GoogleApiClient.connect()' on a null object reference
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
     Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'void com.google.android.gms.common.api.GoogleApiClient.connect()' on a null object reference
            at com.ahmed.omar.tawheed.MainActivity.onStart(MainActivity.java:201)
            at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1220)
            at android.app.Activity.performStart(Activity.java:5949)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2261)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

如果您需要其他文件,请告诉我。 提前致谢。

NullPointerException:尝试在空对象引用上调用接口方法'void com.google.android.gms.common.api.GoogleApiClient.connect()'

因为在调用connect()方法时mGoogleApiClient对象为null

您将在onCreate中创建mGoogleApiClient单独对象,并使用未初始化的对象来调用connect方法。 因此,请使用与在onCreate方法之前和onStart方法中声明的对象相同的对象:

  mGoogleApiClient = new GoogleApiClient.Builder(this)  
                .addConnectionCallbacks(this)   
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();

尽管已经在onCreate()方法中使用相同的名称初始化了该对象,但是您已经在声明部分中创建了GoogleApiClient的实例。

GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this) //used to connect
            .addConnectionCallbacks(this)                               // to Google Play Services
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();

因此,您需要像上面一样更改上面的代码

mGoogleApiClient = new GoogleApiClient.Builder(this) //used to connect
            .addConnectionCallbacks(this)                               // to Google Play Services
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();

您的全局变量mGoogleApiClient未定义。 oncreate()调用之后,它仍然为null。 所以mGoogleApiClient.connect(); 将抛出nullpointerexception

改变这个

GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this) //used to connect
                .addConnectionCallbacks(this)                               // to Google Play Services
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();

mGoogleApiClient = new GoogleApiClient.Builder(this) //used to connect
                .addConnectionCallbacks(this)                               // to Google Play Services
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM