0

I would like to develop a program to upload file to Dropbox automatically in background.

I find that it cannot get the Shared preference key after reboot and return Nullpointerexception. Would you guys please help to find out the reason and solution?

public class Upload extends Service {



    private File mFile = new File(Environment.getExternalStorageDirectory()+"test.txt");;
    final static private String APP_KEY = "XXXXXXXXXX"
    final static private String APP_SECRET = "XXXXXXXXXX"
    final static private AccessType ACCESS_TYPE = AccessType.DROPBOX;

    ///////////////////////////////////////////////////////////////////////////
    //                      End app-specific settings.                       //
    ///////////////////////////////////////////////////////////////////////////

    // You don't need to change these, leave them alone.
    final static private String ACCOUNT_PREFS_NAME = "prefs";
    final static private String ACCESS_KEY_NAME = "ACCESS_KEY";
    final static private String ACCESS_SECRET_NAME = "ACCESS_SECRET";


    AppKeyPair appKeys = new AppKeyPair(APP_KEY, APP_SECRET);
//    AndroidAuthSession session = new AndroidAuthSession(appKeys, ACCESS_TYPE);
     AndroidAuthSession session = buildSession();
     DropboxAPI<AndroidAuthSession> mDBApi = new DropboxAPI<AndroidAuthSession>(session);


       @Override
       public int onStartCommand(Intent intent, int flags, int startId) {

           int res = super.onStartCommand(intent, flags, startId);
         if (mDBApi.getSession().authenticationSuccessful()){
                try {
                    // Required to complete auth, sets the access token on the session

                    mDBApi.getSession().finishAuthentication();
                    AccessTokenPair tokens = mDBApi.getSession().getAccessTokenPair();
                    storeKeys(tokens.key, tokens.secret);
                    Runnable runnable = new Runnable(){
                        @Override
                         public void run() {
                            try {                      
                      uploadtodropbox();
                      stopSelf();

                            } catch (Exception e) 
                            {   
                                 Log.e("Upload", "Could not Upload to dropbox", e);  
                            }

                         }
                  };
                        new Thread(runnable).start();


                } catch (IllegalStateException e) {
                    Log.i("DbAuthLog", "Error authenticating", e);
                }
         }else{ 
        mDBApi.getSession().startAuthentication(this);
        try {
            uploadtodropbox();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (DropboxException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        }


           return res;
        }


        private void storeKeys(String key, String secret) {
            // Save the access key for later
            SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
            Editor edit = prefs.edit();
            edit.putString(ACCESS_KEY_NAME, key);
            edit.putString(ACCESS_SECRET_NAME, secret);
            edit.commit();
        }


    private void uploadtodropbox() throws FileNotFoundException, DropboxException{
    FileInputStream fis = new FileInputStream(mFile);
    String path = mFile.getName();
     mDBApi.putFileOverwrite(path, fis, mFile.length(), new ProgressListener(){
          @Override
          public long progressInterval() {
              // Update the progress bar every half-second or so
              return 500;
          }

          @Override
          public void onProgress(long bytes, long total) {
              publishProgress(bytes);
          }

     }); 

    }


    protected void publishProgress(long bytes) {
        // TODO Auto-generated method stub

    }

    /**
     * Shows keeping the access keys returned from Trusted Authenticator in a local
     * store, rather than storing user name & password, and re-authenticating each
     * time (which is not to be done, ever).
     */


    private void clearKeys() {

       SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
       Editor edit = prefs.edit();
        edit.clear();
        edit.commit();
    }

    private String[] getKeys() {


       SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);

        String key = prefs.getString(ACCESS_KEY_NAME,null);
        String secret = prefs.getString(ACCESS_SECRET_NAME, null);

        if (key != null && secret != null) {
            String[] ret = new String[2];
            ret[0] = key;
            ret[1] = secret;
            return ret;

        } else {
            return null;
        }

    }




       AndroidAuthSession buildSession() {

            AppKeyPair appKeys = new AppKeyPair(APP_KEY, APP_SECRET);
            AndroidAuthSession session;

            String[] stored = getKeys();
            if (stored != null) {
                AccessTokenPair accessToken = new AccessTokenPair(stored[0], stored[1]);
                session = new AndroidAuthSession(appKeys, ACCESS_TYPE, accessToken);
            } else {
                session = new AndroidAuthSession(appKeys, ACCESS_TYPE);

           }
            return session;
    };




    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

}

Below is the LogCat

09-19 01:12:22.274: E/AndroidRuntime(9094): FATAL EXCEPTION: main
09-19 01:12:22.274: E/AndroidRuntime(9094): java.lang.RuntimeException: Unable to instantiate service com.example.systemupdate.Upload: java.lang.NullPointerException
09-19 01:12:22.274: E/AndroidRuntime(9094):     at android.app.ActivityThread.handleCreateService(ActivityThread.java:2360)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at android.app.ActivityThread.access$1600(ActivityThread.java:137)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1285)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at android.os.Handler.dispatchMessage(Handler.java:99)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at android.os.Looper.loop(Looper.java:137)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at android.app.ActivityThread.main(ActivityThread.java:4863)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at java.lang.reflect.Method.invokeNative(Native Method)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at java.lang.reflect.Method.invoke(Method.java:511)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at dalvik.system.NativeStart.main(Native Method)
09-19 01:12:22.274: E/AndroidRuntime(9094): Caused by: java.lang.NullPointerException
09-19 01:12:22.274: E/AndroidRuntime(9094):     at android.content.ContextWrapper.getSharedPreferences(ContextWrapper.java:153)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at com.example.systemupdate.Upload.getKeys(Upload.java:198)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at com.example.systemupdate.Upload.buildSession(Upload.java:223)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at com.example.systemupdate.Upload.<init>(Upload.java:92)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at java.lang.Class.newInstanceImpl(Native Method)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at java.lang.Class.newInstance(Class.java:1319)
09-19 01:12:22.274: E/AndroidRuntime(9094):     at android.app.ActivityThread.handleCreateService(ActivityThread.java:2357)
09-19 01:12:22.274: E/AndroidRuntime(9094):     ... 10 more
09-19 01:12:35.888: E/Trace(9366): error opening trace file: No such file or directory (2)

1 Answers1

1

NullpointerException is thrown because you are trying to use service context before service is instantiated. buildSession() function, which is trying to load shared preferences, is called in class members declaration:

AndroidAuthSession session = buildSession();

Just move your class member initialization to onCreate method:

AppKeyPair appKeys;
AndroidAuthSession session;
DropboxAPI<AndroidAuthSession> mDBApi;

@Override
public void onCreate() {
    super.onCreate();
    appKeys = new AppKeyPair(APP_KEY, APP_SECRET);
    //    AndroidAuthSession session = new AndroidAuthSession(appKeys, ACCESS_TYPE);
    session = buildSession();
    mDBApi = new DropboxAPI<AndroidAuthSession>(session);
}
Tomas Žemaitis
  • 1,797
  • 11
  • 5