2014-07-07 2 views
0

이 포럼의 다른 스레드를 참조하고 내 질문을 이중으로 표시하기 전에 친절하게 제 질문을 읽으십시오. 전역 응용 프로그램 시간 제한을 만들어야합니다. 어떤 활동이 사용자인지에 관계없이 일정한 시간이 지나면 AlertDialog에 세션이 만료되었으며 세션을 종료하거나 갱신 할 수 있습니다. 다른 솔루션을 읽고 내 솔루션으로 서비스를 사용했습니다.AlertDialog로 특정 시간 이후에 세션 시간 초과가 발생했습니다.

public class InActivityTimer extends Service { 

MyCounter timer; 

@Override 
public void onCreate() { 
    timer = new MyCounter(20 * 1000,1000); 
    super.onCreate(); 
} 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    timer.start(); 
    return super.onStartCommand(intent, flags, startId); 
} 

private class MyCounter extends CountDownTimer{ 

    public MyCounter(long millisInFuture, long countDownInterval) { 
     super(millisInFuture, countDownInterval); 
    } 

    @Override 
    public void onFinish() { 
     Intent intent = new Intent("timeout_action"); 
     sendBroadcast(intent); 

     stopSelf(); 
    } 

    @Override 
    public void onTick(long millisUntilFinished) { 

     // Need AlertDialog code here 

     Toast.makeText(getApplicationContext(), ("Time Remaining: " + millisUntilFinished/1000)+"", Toast.LENGTH_SHORT).show(); 
    } 
} 

@Override 
public void onDestroy() { 
    timer.cancel(); 
    super.onDestroy(); 

} 

@Override 
public IBinder onBind(Intent arg0) { 
    return null; 
} 

}

문제는 내가 아무 문제없이 토스트를 표시 할 수 있지만 onFinish 내에서 호출시에 AlertDialog가 표시되지 않습니다().

첫 번째 문제는 AlertDialog가 일부 컨텍스트에 대해 표시된다는 것을 염두에두고 전체 응용 프로그램에 대해 AlertDialog를 표시하는 것입니다. 또한 어떻게 든 AlertDialog가 표시되면 응용 프로그램을 닫는 방법. 액티비티에서는 finish()를 호출하여 액티비티를 종료하므로이 경우 액티비티 스택을 지워야하나요?

내가 직면 한 두 번째 복잡한 부분은 세션에서 시간이 초과 될 때까지 남은 시간을 표시하는 응용 프로그램에서 "남은 시간"링크를 클릭하면 팝업을 표시하는 것입니다. 이 시간은 서비스에 남아있는 시간과 정확히 동일해야합니다.

또한 BroadcastReceiver를 사용하여 시간이 끝나면 활동에 대한 업데이트를 보내지 만 사용자가 어떤 활동에 관계없이 타임 아웃이 동일하게 작동하기를 원하기 때문에 활동 특정이 아닙니다. 각 활동에 동일한 코드를 작성하는 것을 피하고 싶습니다.

몇 가지 해결책을 안내해 드리겠습니다.

+1

'AlertDialog'가 작동하려면'AlertDialog '에'Context '가 필요하다는 것을 알고있는 것처럼 들립니다. 그러나 더 구체적으로, AlertDialog는 표시하기 위해 첨부 할 Activity 나 윈도우를 필요로합니다. 만약 당신이'Service'에서'Context'를 넘겨 주면'AlertDialog'를 보여 주려고 할 때 크래쉬가 발생할 것입니다. 어떤 잘못된 윈도우 토큰 (또는 비슷한 것)에 대해 알려줍니다. 아마도 당신은'Activity'에서 방송 수신기를 등록하고 거기에서'AlertDialog'을 보낼 수 있습니다. 행운을 빕니다! – Brian

+0

예 브로드 캐스트 수신기를 사용할 수는 있지만 특정 활동과 관련이 없습니다. 모든 활동에 동일하게 적용될 수 있습니까?경고를 의미하고 시간은 모든 활동에서 동일 할 것입니까? 전반적으로 좋은 접근 방법입니까? –

답변

0

나는 아주 간단한 접근 방식으로 내 문제를 해결했습니다.

@Override 
public void onFinish() { 
    Intent intent = new Intent(getBaseContext(), TimeoutActivity.class); 
    startActivity(intent);   

    stopSelf(); 
} 

이하는 내 TimeoutActivity의 onCreate 메소드입니다.

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    ContextThemeWrapper ctw = new ContextThemeWrapper(TimeoutDialogActivity.this, R.style.Theme_Base_AppCompat_Dialog_FixedSize); 
    final AlertDialog alertDialog = new AlertDialog.Builder(ctw).create(); 
    alertDialog.setCancelable(false); 
    alertDialog.setTitle("Session Timeout !"); 
    alertDialog.setTitle("Your session has expired."); 
    alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "Logout", new DialogInterface.OnClickListener() { 

     @Override 
     public void onClick(DialogInterface dialog, int which) { 
      alertDialog.dismiss(); 
finish(); 
     } 
    }); 

    alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "Exit", new DialogInterface.OnClickListener() { 

     @Override 
     public void onClick(DialogInterface dialog, int which) { 

      alertDialog.dismiss(); 
finish(); 
     } 
    }); 

    alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Renew Session", new DialogInterface.OnClickListener() { 

     @Override 
     public void onClick(DialogInterface dialog, int which) { 

       alertDialog.dismiss(); 
       finish(); 

    }); 

    alertDialog.show(); 
} 
1

앱에 조각 기반 디자인을 사용하는 경우 앱의 다른 모든 요소가 표시되는 루트 FragmentActivity를 유지할 수 있습니다. 이렇게하면 매번 루트 FragmentActivity 컨텍스트를 사용하여 대화 상자를 표시 할 수 있습니다.


추가 : 일반적인 아닙니다 당신이하고있는

를 "당신은 친절 .. 나에게 몇 가지 기사를 참조 할 수"와 유사한 기존의 예를 찾을처럼 나는 구글 검색으로 할 것이다 너의 경우. 그러나 내가 위에서 제안한 것에 대해 좀 더 자세하게 설명 할 수 있습니다.

조각 사용에 익숙하지 않은 경우 Developer Documentation을 읽어보십시오.

public class MainActivity extends FragmentActivity { 

    private static final int SPLASH_SCREEN_FRAGMENT = 0; 
    private static final int HOME_SCREEN_FRAGMENT = 1; 
    ... 

    @Override 
    protected void onCreate(Bundle. savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     // show your first fragment 
     Fragment splashFragment = new SplashFragment(); 
     getSupportFragmentManager().beginTransaction().replace(android.R.id.content, splashFragment).commit(); 

     // Start your service using the context of your FragmentActivity 
     // Your FragmentActivity will always be the current activity, and you will display 
     // all other elements of your app inside it as fragments 
     Intent intent = new Intent(this, InActivityTimer.class); 
     startService(intent); 
    } 

    // method for switching the displayed fragment 
    private void fragmentSwitcher(int fragmentType) { 

     Fragment currentFragment = new Fragment(); 

     switch (currentFragmentType) { 
      case SPLASH_SCREEN_FRAGMENT: 
       currentFragment = new SplashScreenFragment(); 
       break; 
      case HOME_SCREEN_FRAGMENT: 
       currentFragment = new HomeScreenFragment(); 
       break; 
      ... 
     } 
     getSupportFragmentManager().beginTransaction().replace(android.R.id.content, currentFragment).commit(); 
    } 
} 
+0

당신이 친절하게 나를 볼 수있는 몇 가지 기사 에서이 코드를 작성하는 아이디어를 얻을 수있는 믿을보고 더 도움이 될 것입니다. –

관련 문제