I've implemented the Google Play Games API in my game recently, but some issues appeared after that.
The problem is for some reason my game is not loading my Custom View class when I start the aplication and call the method setContentView() but this only happens when I build the release version of the apk.
gv = new GameView(this);
setContentView(gv); //not loading on release version or if the debuggable is set to true in build.gradle
I also tryied to put this line on build.gradle
debuggable false
the result was that the release version started working but with this line I cant upload it to playStore and the reason of this thread is obviusly because I need this working on the playStore.
Some Notes of test:
The Google play services connects well both release and debug apks, but in release a black screen appears isntead of my GameView Class
The setContentView() doesn't works when running the apk on release version or if the debuggable is set to true in build.gradle.
The setContentView() works fine when running the apk on debug version
The setContentView() works fine if I load a XML file in any situations (but my game doesnt uses any XMLs).
Main Activity Class
public class Main extends Activity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
GameView gv;
public static DBHandler db;
public static String version = "0.0.0";
public static GoogleApiClient mGoogleApiClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fullScreen(true); //PRE ESTABELECE O TAMANHO DA TELA DEIXANDO NO FULLSCREEN PRIMEIRAMENTE
(Toast.makeText(this, "inicializando GameView", Toast.LENGTH_SHORT)).show();
gv = new GameView(this);
setContentView(gv);
// Create the Google Api Client with access to the Play Games services
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Games.API).addScope(Games.SCOPE_GAMES)
// add other APIs and scopes here as needed
.setViewForPopups(gv)
.build();
// ...
//setContentView(R.layout.loading_screen);
db = new DBHandler(this);
Log.w("Main", ""+db.getPointsCount()+" - registros encontrados.");
//VERSAO ---
PackageInfo pInfo = null;
try {
pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
version = pInfo.versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}// ...
}
protected void onDestroy(){
super.onDestroy();
gv.relase();
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
fullScreen(hasFocus);
}
void fullScreen(boolean hasFocus){
if (hasFocus) {
final View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);}
}
#Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
Log.e("Main","Conectando ao Google Play...");
}
#Override
protected void onStop() {
super.onStop();
mGoogleApiClient.disconnect();
Log.e("Main","Desconectado da google API PlayGames!");
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.e("Main","onConnected");
Games.Achievements.unlock(mGoogleApiClient, "CgkI8au7i4oUEAIQAg");
(Toast.makeText(this, "Conectado ao Google Play Game", Toast.LENGTH_SHORT)).show();
}
#Override
public void onConnectionSuspended(int i) {
Log.e("Main","onConnectionSuspended");
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.e("Main","onConnectionFailed");
(Toast.makeText(this, "Não foi posivel conectar ao Google Play Services.", Toast.LENGTH_SHORT)).show();
}
}
Build.gradle
apply plugin: 'com.android.application'
android {
signingConfigs {
DannarkKey {
keyAlias 'dannark'
keyPassword '23021994'
storeFile file('C:/Users/Daniel/AndroidstudioProjects/DannarkKey.jks')
storePassword '23021994'
}
}
compileSdkVersion 23
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.jumpers.gamelogic"
minSdkVersion 14
targetSdkVersion 21
versionCode 24
versionName "2.7.4"
}
buildTypes {
release {
debuggable false
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.google.android.gms:play-services:9.0.0'
}
GameView.class
/**
* Created by Daniel on 19/03/2016.
*/
public class GameView extends View implements Runnable {
Context context;
private static final int INTERVAL = 10;
private boolean running = true;
private Paint p;
public static HUD hud;
public static PrintText pt;
public static ArrayList<SpawnMessageWindows> spawnMsgs = new ArrayList<>();
public static ScoreScreen scoreScreen;
public static HandleEventsTouchsSpawnedObjects handleEventsTouchs = new HandleEventsTouchsSpawnedObjects();
public static Load load;
public static Fase fase;
public static Player player;
public static Menu menu;
public static Camera cam;
Bitmap layerImg2;
public static Canvas layer2;
public static LaterCanvas laterCanvas;
public static int lar;
public static int alt;
public static int touchFocus = 0;
public static ArrayList<String> variaveisName = new ArrayList<>();
public static ArrayList<Float> variaveisValue = new ArrayList<>();
private long preTime = 0;
public static int timeInGame = 0;
public static boolean isPlaying = false;
// blocksIDsUsedForTutorial TEM O OBJETIVO DE MOSTRAR MENSSAGENS DE TUTORIAS PELA PRIMEIRA VES CASO VC NUNCA TENHA USADO
// UM SCRIPT, SE TIVER DENTRO DESSA LISTA, ENTÃO A MENSAGEM NAO APARECERA.
public static ArrayList<Integer> blocksIDsUsedForTutorial = new ArrayList<>();
public GameView(Context context) {
super(context);
this.context = context;
load = new Load(context);
p = new Paint();
Thread t = new Thread(this);
t.setPriority(Thread.MIN_PRIORITY);
t.start();
preTime = System.currentTimeMillis()/1000;
addVariavel("variavel1", 0); //TESTE
addVariavel("valor3", 0); //TESTE
addVariavel("valor4", 0); //TESTE
addVariavel("valor5", 0); //TESTE
addVariavel("valor6", 0); //TESTE
addVariavel("valor7", 0); //TESTE
addVariavel("valor8", 0); //TESTE
}
void init(){
while (getWidth() == 0){ }//aguarndando getWidth
lar = getWidth();
alt = getHeight();
player = new Player();
fase = new Tutorial_001(context);//new Fase1(context);
hud = new HUD();
pt = new PrintText();
menu = new Menu(context);
cam = new Camera(getWidth(), getHeight(), player);
layerImg2 = Bitmap.createBitmap(lar, alt, Bitmap.Config.ARGB_8888);
layer2 = new Canvas(layerImg2);
laterCanvas = new LaterCanvas(context);
setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
//int action = event.getActionMasked();
TextKeyBoard.handleTouch(v, event);
NumericKeyBoard.handleTouch(v, event);
hud.handleTouch(v, event);
menu.handleTouch(v, event);
cam.handleTouch(v, event);
handleEventsTouchs.handleTouch(v, event); //SEGURA TODOS OS EVENTOS DE OBJETOS CRIADOS POSTEIORMENTE
return true;
}
});
}
#Override
public void run() {
init();
while (running){
try {
Thread.sleep(INTERVAL);
}catch (Exception e){
Toast t = Toast.makeText(getContext(), "Game Loop:"+e.getMessage(), Toast.LENGTH_LONG);
t.show();
Log.e("GameLogic", "GameLoop erro Inesperado: "+e.getMessage());
}
update();
}
}
public void update(){
//dispara o metodo de desenho
postInvalidate();
timeInGame = (int)((System.currentTimeMillis()/1000)-preTime); //TEMPO JOGADO EM SEGUNDOS
}
public void draw(Canvas c){
super.draw(c);
if(c!=null && player != null && hud != null && menu != null && cam!=null) {
c.drawColor(Color.BLACK);
if(isPlaying) {
cam.draw(c, p);
hud.draw(c, p);
pt.draw(c, p);
if(scoreScreen != null) {
scoreScreen.draw(c);
}
laterCanvas.drawBeforeMsgs(c); //DESENHA TODOS OS DESENHOS SOBREPOSTOS NA MESMA CANVAS.
if(spawnMsgs.size() > 0){
spawnMsgs.get(0).draw(c, p);
}
laterCanvas.drawAfterMsgs(c); //DESENHA TODOS OS DESENHOS SOBREPOSTOS NA MESMA CANVAS.
//c.drawBitmap(layerImg2,0,0,p);
}else {
menu.draw(c, p);
}
}
}
public void relase(){
running = false;
}
public static void addVariavel(String variavelNome, float variavelValor){
if(variaveisName.contains(variavelNome) == false) {
variaveisName.add(variavelNome);
variaveisValue.add(variavelValor);
}
}
public static void removeVariavel(int index){
variaveisName.remove(index);
variaveisValue.remove(index);
}
public static void setVariavelValor(int valiavelIndex, float variavelValor){
variaveisValue.set(valiavelIndex, variavelValor);
}
}
Related
I am creating an android tv app in the app I am sliding infinity loop fragments (Image and Video URLs ). I use glide for image loading and exoplayer2 for video loading it's working perfectly in my emulator and other 2-3 devices but when I run it in my actual android tv it keeps crashing after some time with an error memory exception. I tested it In emulator using profiler how much memory it using but it is only using min 100 Mb not bigger than that I even check for a leak using leak cannery no leak was found I can't find any solution can someone please help me
Fragment:
`public class BannerFragment extends Fragment {
/*TODO TAGs*/
private String TAG = BannerFragment.class.getSimpleName();
/*TODO View Binding*/
private BannerFragmentBinding vb;
private PromotionalBanner promotionalBanner;
private int position;
private ArrayList<PromotionalBanner> promotionalBannerArrayList;
private CountDownTimer timer;
SimpleExoPlayer simpleExoPlayer;
private final String VIDEO_BUFFER_TIMER = "10000";
/*TODO Glide Listener*/
private RequestListener requestListener = new RequestListener<Drawable>() {
#Override
public boolean onLoadFailed(#Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
if (vb != null) {
ShowToast(" Can't load image ");
vb.avi.setVisibility(View.GONE);
slideNextItem();
}
return false;
}
#Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
if (vb != null) {
vb.avi.setVisibility(View.GONE);
}
return false;
}
};
/*TODO PlayerListener*/
private Player.Listener playerListener = new Player.Listener() {
#Override
public void onIsPlayingChanged(boolean isPlaying) {
Log.e(TAG, "onIsPlayingChanged: " + isPlaying);
}
#Override
public void onPlaybackStateChanged(int playbackState) {
if (playbackState == Player.STATE_ENDED) {
slideNextItem();
} else if (playbackState == Player.STATE_READY) {
vb.avi.setVisibility(View.GONE);
if (timer != null) {
timer.cancel();
timer = null;
}
Log.e("TimerCheck", "onPlaybackStateChanged: endTimer "+timer );
} else if (playbackState == Player.STATE_BUFFERING) {
vb.avi.setVisibility(View.VISIBLE);
setSlideTimer(VIDEO_BUFFER_TIMER);
Log.e("TimerCheck", "onPlaybackStateChanged: startTimer "+timer );
} else if (playbackState == Player.STATE_IDLE) {
slideNextItem();
}
}
#Override
public void onPlayWhenReadyChanged(boolean playWhenReady, int reason) {
}
};
/*TODO get Fragment Instant*/
public static Fragment getInstantFragment(PromotionalBanner promotionalBanner,
int index,
ArrayList<PromotionalBanner> promotionalBannerArrayList) {
BannerFragment fragment = new BannerFragment();
Bundle bundle = new Bundle();
bundle.putParcelable("promotionalBanner", promotionalBanner);
bundle.putInt("position", index);
bundle.putParcelableArrayList("list", promotionalBannerArrayList);
fragment.setArguments(bundle);
return fragment;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.promotionalBanner = getArguments().getParcelable("promotionalBanner");
this.position = getArguments().getInt("position");
this.promotionalBannerArrayList = getArguments().getParcelableArrayList("list");
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
vb = BannerFragmentBinding.inflate(getLayoutInflater());
return vb.getRoot();
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
public void onResume() {
super.onResume();
if (!isImageFile(promotionalBanner.getMedia())) {
showVideoViewContainer();
setVideo(promotionalBanner);
} else {
hideVideoViewContainer();
loadImage(promotionalBanner.getMedia(), promotionalBanner.getDuration());
/*TODo set image Timer*/
setSlideTimer(promotionalBanner.getDuration());
}
}
/*TODO setVideo*/
private void setVideo(PromotionalBanner promotionalBanner) {
Uri uri = Uri.parse(promotionalBanner.getMedia());
Log.e("dataUriTest", "setVideo: " + uri);
simplePlayer(uri);
}
/*TODO Simple Player*/
private void simplePlayer(Uri uri) {
simpleExoPlayer = new SimpleExoPlayer.Builder(getContext()).build();
simpleExoPlayer.addMediaItem(MediaItem.fromUri(uri));
setSlideTimer(VIDEO_BUFFER_TIMER);
Log.e("TimerCheck", "onPlaybackStateChanged:insideSimplePlayer startTimer "+timer );
vb.avi.setVisibility(View.VISIBLE);
vb.videoView.hideController();
vb.videoView.setPlayer(simpleExoPlayer);
simpleExoPlayer.prepare();
simpleExoPlayer.setPlayWhenReady(true);
simpleExoPlayer.addListener(playerListener);
}
/*TODO Go To next From vide Slide*/
private void slideNextItem() {
if(simpleExoPlayer != null){
simpleExoPlayer.release();
simpleExoPlayer = null;
}
int nextposition = position + 1;
goToNextItem(nextposition);
}
#Override
public void onPause() {
super.onPause();
Log.e("LogBannerFragment", "onPause: ");
if (timer != null) {
timer.cancel();
}
if (simpleExoPlayer != null) {
simpleExoPlayer.release();
simpleExoPlayer = null;
}
}
#Override
public void onDestroy() {
super.onDestroy();
Log.e("Destory", "onDestroy: " );
if (playerListener != null) {
playerListener = null;
}
if (requestListener != null) {
requestListener = null;
}
if (vb != null) {
vb = null;
}
}
#Override
public void onDestroyView() {
super.onDestroyView();
}
/*TODO load Image*/
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void loadImage(String media, String duration) {
vb.avi.setVisibility(View.VISIBLE);
Glide.with(getContext()).load(convert_http_https(media))
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.error(getContext().getDrawable(R.drawable.banner))
.addListener(requestListener)
.into(vb.imageView);
}
/*TODO convert url http to https in android studio*/
private String convert_http_https(String url) {
String original;
if (url.contains("https")) {
original = url;
} else {
original = url.replace("http", "https");
}
return original;
}
/*TODO set Image timer*/
private void setSlideTimer(String duration) {
timer = new CountDownTimer(Integer.parseInt(duration), 1000) {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
int nextPosition = position + 1;
// int nextPosition = DispolyActivity.vb.viewPager.getCurrentItem()+1;
goToNextItem(nextPosition);
}
};
timer.start();
}
/*TODO Next Position in arrayList*/
private void goToNextItem(int nextPosition) {
HandlerCompat.createAsync(Looper.getMainLooper())
.post(() ->
DispolyActivity.vb.viewPager.setCurrentItem(nextPosition)
);
}
/*TODO is image file*/
public static boolean isImageFile(String path) {
String mimeType = URLConnection.guessContentTypeFromName(path);
return mimeType != null && mimeType.startsWith("image");
}
/*TODO Video view Container*/
private void showVideoViewContainer() {
Log.e("datashow", "showVideoViewContainer: "+vb);
vb.videoContainer.setVisibility(View.VISIBLE);
vb.imageView.setVisibility(View.GONE);
}
/*TODO hide video view Container*/
private void hideVideoViewContainer() {
vb.videoContainer.setVisibility(View.GONE);
vb.imageView.setVisibility(View.VISIBLE);
}
/*TODO show Toast*/
private void ShowToast(String msg) {
Toast.makeText(getContext(), msg, Toast.LENGTH_LONG).show();
}
}
`
My Adapter for slide fragment :
public class SliderAdapter extends FragmentStatePagerAdapter {
private String TAG = SliderAdapter.class.getSimpleName();
private ArrayList<PromotionalBanner> promotionalBannerArrayList;
public SliderAdapter(#NonNull FragmentManager fm,ArrayList<PromotionalBanner> promotionalBannerArrayList) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
this.promotionalBannerArrayList = promotionalBannerArrayList;
}
#NonNull
#Override
public Fragment getItem(int position) {
PromotionalBanner promotionalBanner = DispolyActivity.promotionalBannerArrayList.get(position);
Log.e("positiondata", "dataPost: "+position );
return BannerFragment.getInstantFragment(promotionalBanner,
position,DispolyActivity.promotionalBannerArrayList);
}
#Override
public int getCount() {
return DispolyActivity.promotionalBannerArrayList.size();
}
#Override
public int getItemPosition(#NonNull Object object) {
return POSITION_UNCHANGED;
}
#Override
public void destroyItem(#NonNull ViewGroup container,
int position, #NonNull Object object) {
super.destroyItem(container, position, object);
Log.e("itemDestroy", "destroyItem: "+object );
}
/*TODO update Adapter Data*/
public void updateAdapter_Data(ArrayList<PromotionalBanner> promotionalBannersList){
this.promotionalBannerArrayList = promotionalBannersList;
// notifyDataSetChanged();
}
}
When working with the player, you need to carefully monitor the life cycle.
simpleExoPlayer.release();
simpleExoPlayer = null;
Try to use this not only in onPause(), try it also in onDestroy and onDestroyView.
If the problem goes away, then go through which life cycle methods are called and leave the release call in the right places
You have an issue not with memory, most likely you have an issue related to the codec.
Each device has its own limited number of codecs.
Some devices have more, some have less.
Therefore, on some devices, you can run the video more times, especially on emulators.
I am using Obtaining Consent with the User Messaging Platform in my application: https://developers.google.com/admob/ump/android/quick-start
The consent form is not shown on the screen at the start of the activity.
The logs show the triggering of the method after onResume, but the form does not appear on the eran. What's wrong with my code?
In run, I found the lines:
UserMessagingPlatform: No available form can be built.
D / UserMessagingPlatform: Stored info not exists: IDFA_freqCapNumViews
Stored info not exists: IABTCF_TCString
Stored info not exists: IABTCF_AddtlConsent
I / System.out: (HTTPLog) -Static: isSBSettingEnabled false
(HTTPLog) -Static: isSBSettingEnabled false
D / UserMessagingPlatform: Action [clear]: {"keys": ["IABTCF_CmpSdkID", "IABTCF_CmpSdkVersion", "IABTCF_PolicyVersion", "IABTCF_gdprApplies", "IABTCF_PublisherCC", "IABTCFreat_Streats" , "IABTCF_VendorLegitimateInterests", "IABTCF_PurposeConsents", "IABTCF_PurposeLegitimateInterests", "IABTCF_SpecialFeaturesOptIns", "IABTCF_PublisherConsent", "IABTCF_PublisherLegitimateInterests", "IABTCF_PublisherCustomPurposesConsents", "IABTCF_PublisherCustomPurposesLegitimateInterests", "IABTCF_AddtlConsent", "IABTCF_UserConsentRecordId", "IABTCF_idfaFlowControl"]}
D / UserMessagingPlatform: Action [write]: {"IABTCF_idfaFlowControl": 2}
What's wrong with my code?
public abstract class BaseActivity extends AppCompatActivity {
private final String TAG = "ART_APP";
private SharedPreferences sp;
private ConsentInformation consentInformation;
private ConsentForm consentForm;
final String LOG_TAG = "myLogs";
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.sp = getSharedPreferences(Sp.SP_KEY, Context.MODE_PRIVATE);
ConsentDebugSettings debugSettings = new ConsentDebugSettings.Builder(this)
.setDebugGeography(ConsentDebugSettings
.DebugGeography
.DEBUG_GEOGRAPHY_EEA)
.addTestDeviceHashedId("C258BF9BE13D842B973A20309A39C080")
.build();
ConsentRequestParameters params = new ConsentRequestParameters
.Builder()
.setConsentDebugSettings(debugSettings)
.build();
consentInformation = UserMessagingPlatform.getConsentInformation(this);
consentInformation.requestConsentInfoUpdate(
this,
params,
new ConsentInformation.OnConsentInfoUpdateSuccessListener() {
#Override
public void onConsentInfoUpdateSuccess() {
// The consent information state was updated.
// You are now ready to check if a form is available.
if (consentInformation.isConsentFormAvailable()) {
loadForm();
}
}
},
new ConsentInformation.OnConsentInfoUpdateFailureListener() {
#Override
public void onConsentInfoUpdateFailure(FormError formError) {
// Handle the error.
}
});
}
public SharedPreferences getSp() {
return sp;
}
public void loadForm(){
Log.d(LOG_TAG, "showconsent");
UserMessagingPlatform.loadConsentForm(
this,
new UserMessagingPlatform.OnConsentFormLoadSuccessListener() {
#Override
public void onConsentFormLoadSuccess(ConsentForm consentForm) {
BaseActivity.this.consentForm = consentForm;
if(consentInformation.getConsentStatus() == ConsentInformation.ConsentStatus.UNKNOWN) {
consentForm.show(
BaseActivity.this,
new ConsentForm.OnConsentFormDismissedListener() {
#Override
public void onConsentFormDismissed(#Nullable FormError formError) {
// Handle dismissal by reloading form.
loadForm();
}
});
}
}
},
new UserMessagingPlatform.OnConsentFormLoadFailureListener() {
#Override
public void onConsentFormLoadFailure(FormError formError) {
/// Handle Error.
}
}
);
}
/**
* Достать строку из переменных
*
* #param stringId
* #return
*/
public String getSpString(String stringId) {
return getResources().getString(sp.getInt(stringId, 0));
}
/**
* #param stringId
* #return
*/
public String getSpStringSt(String stringId) {
return sp.getString(stringId, "");
}
public void log(String msg) {
Log.d(TAG, msg);
}
/**
* Открываем ссылку в баузере
*
* #param url
*/
public void showLink(String url) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
}
/**
* Есть ли подписка ?
*
* #return
*/
}
public class CategoryActivity extends BaseActivity implements RVAdapter.ItemClickListener,
View.OnClickListener, BarMenu.OnItemClick {
private static final String TAG = CategoryActivity.class.getSimpleName();
private RecyclerView rv;
private List<Item> items;
private List<Modal> modals;
private BarMenu barMenu;
private HashMap<Integer, MoreApp> moreApps;
private AdView adView;
private FrameLayout adContainerView;
private ConsentInformation consentInformation;
private ConsentForm consentForm;
final String LOG_TAG = "myLogs";
private SliderView sliderView;
private SliderPromoAdapter adapter;
private ArrayList<SliderItem> sliderViewArrayList = new ArrayList<>();
private View banner;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_category);
Log.d(LOG_TAG, "CategoryCreate");
initRateMe();
showRateMe();
MobileAds.initialize(this, new OnInitializationCompleteListener() {
#Override
public void onInitializationComplete(InitializationStatus initializationStatus) { }
});
//StartAppSDK.init(this, "202286925", true);
//------------
this.barMenu = new BarMenu(this, R.menu.top_bar_menu);
barMenu.setOnItemClick(this);
//------------
adapter = new SliderPromoAdapter(this);
SliderItem sliderItem = new SliderItem();
sliderItem.setSource(R.drawable.banner_premium);
sliderItem.setType(GlobalData.TYPE_PREMIUM);
sliderViewArrayList.add(sliderItem);
sliderView = findViewById(R.id.slider_view);
sliderView.setIndicatorAnimation(IndicatorAnimations.WORM); //set indicator animation by using SliderLayout.IndicatorAnimations. :WORM or THIN_WORM or COLOR or DROP or FILL or NONE or SCALE or SCALE_DOWN or SLIDE and SWAP!!
sliderView.setSliderTransformAnimation(SliderAnimations.SIMPLETRANSFORMATION);
sliderView.setAutoCycleDirection(SliderView.AUTO_CYCLE_DIRECTION_BACK_AND_FORTH);
sliderView.setIndicatorSelectedColor(Color.WHITE);
sliderView.setIndicatorUnselectedColor(Color.GRAY);
sliderView.setScrollTimeInSec(4); //set scroll delay in seconds :
sliderView.startAutoCycle();
sliderView.setSliderAdapter(adapter);
adapter.renewItems(sliderViewArrayList);
///get the reference to your FrameLayout
adContainerView = findViewById(R.id.adView_container);
//Create an AdView and put it into your FrameLayout
adView = new AdView(this);
adContainerView.addView(adView);
String adUnitId = getResources().getString(getSp().getInt(Sp.SP_ADS_BANNER_ID, 0));
adView.setAdUnitId(adUnitId);
//start requesting banner ads
loadBanner();
//------------
((TextView) findViewById(R.id.top_bar_title)).setText(
getSp().getInt(Sp.SP_APP_NAME, 0)
);
this.items = new ArrayList<>();
this.moreApps = new HashMap<>();
/*
if (!getSp().getBoolean(Sp.SP_MORE_APP_UP, false)) {
readJson();
}*/
//TODO Есть ли вообще другие приложения ?)
try {
if (!getSpStringSt(Sp.SP_MORE_APPS).equals("")) {
Gson gson = new Gson();
Type type = new TypeToken<List<MoreApp>>() {
}.getType();
List<MoreApp> ma = gson.fromJson(getSpStringSt(Sp.SP_MORE_APPS), type);
for (MoreApp m : ma) {
moreApps.put(m.getPosition(), m);
}
}
} catch (Exception e) {
e.printStackTrace();
}
// Баннер
this.banner = findViewById(R.id.custom_banner);
banner.setOnClickListener(this);
if (getSp().getBoolean(Sp.SP_IS_FREE5DAY, false)) {
banner.setVisibility(View.VISIBLE);
}
//if (getSp().getBoolean(Sp.SP_MORE_APP_UP, false)) {
readJson();
//}
this.rv = findViewById(R.id.category_recycler);
LinearLayoutManager llm = new GridLayoutManager(getApplicationContext(), 2);
rv.setLayoutManager(llm);
rv.setHasFixedSize(true);
RVAdapter adapter = new RVAdapter(items, this, true);
rv.setAdapter(adapter);
adapter.setmClickListener(this);
findViewById(R.id.top_bar_check).setVisibility(View.GONE);
findViewById(R.id.top_bar_menu).setOnClickListener(this);
findViewById(R.id.top_bar_back).setOnClickListener(this);
}
#Override
protected void onResume() {
super.onResume();
Log.d(LOG_TAG, "onResume");
loadForm();
if (getSp().getBoolean(Sp.SP_IS_FAQ, true)) {
// startActivity(new Intent(this, FaqActivity.class));
getSp().edit().putBoolean(Sp.SP_IS_FAQ, false).commit();
}
if (getSp().getBoolean(Sp.SP_IS_FREE5DAY, false)) {
}
hideSystemUI();
}
}
The problem might be that you call
super.onCreate(savedInstanceState);
before
setContentView(R.layout.activity_category);
I moved all Consent-Related code to a separate method initializeConsent() in the base class, and I called initializeConsent() as last method in my subclass's onCreate() method.
Additionally, I call
MobileAds.initialize
only in method onConsentFormLoadSuccess, it then looks like this:
#Override
public void onConsentFormLoadSuccess(ConsentForm consentForm) {
DisplayNumberActivity.this.consentForm = consentForm;
if(consentInformation.getConsentStatus() == ConsentInformation.ConsentStatus.REQUIRED) {
consentForm.show(
DisplayNumberActivity.this,
new ConsentForm.OnConsentFormDismissedListener() {
#Override
public void onConsentFormDismissed(#Nullable FormError formError) {
//reset all DSGVO information for next trial
// Handle dismissal by reloading form.
loadForm(); //neuerlicher Aufruf, sollte nun ConsentStatus == ConsentInformation.ConsentStatus.OBTAINED haben. Dort wird dann initializeMobileAds() aufgerufen
}
});
} else if (consentInformation.getConsentStatus() == ConsentInformation.ConsentStatus.OBTAINED
|| consentInformation.getConsentStatus() == ConsentInformation.ConsentStatus.NOT_REQUIRED) {
//Form muss nicht mehr angezeigt werden, Ads können geladen werden
if (consentInformation.getConsentStatus() == ConsentInformation.ConsentStatus.OBTAINED) {
logInfo("DSGVO Consent obtained");
} else {
logInfo("DSGVO Consent not required");
}
//ads können jedenfalls geladen werden, Admob checkt ob es personalisierte werbung sein darf
initializeMobileAds();
} else {
Toast.makeText(DisplayNumberActivity.this, "DSGVO Consent status: " + consentInformation.getConsentStatus(), Toast.LENGTH_LONG).show();
logInfo("unexpected DSGVO Consent: " + consentInformation.getConsentStatus());
initializeMobileAds();
}
}
I am trying to create a video calling Android application using Agora SDK but I'm running into a problem. I want to capture the video frames and process it before displaying it.
I am using the lib-raw-data from API Examples to capture the raw video frame. I have followed the steps from the documentation https://docs.agora.io/en/Video/raw_data_video_android?platform=Android and checked the examples as well. However, I cannot seem to capture the frame in methods onRenderVideoFrame and onCaptureVideoFrame.
The video calling works perfectly but the callback function does not seem to work. I don't get anything in onRenderVideoFrame or onCaptureVideoFrame.
Below is the code for the Activity:
public class MainActivity extends AppCompatActivity implements MediaDataVideoObserver,
MediaDataAudioObserver {
private static final String TAG = MainActivity.class.getSimpleName();
private static final int PERMISSION_REQ_ID = 22;
private static final String[] REQUESTED_PERMISSIONS = {
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
private RtcEngine mRtcEngine;
private boolean mCallEnd;
private boolean mMuted;
private FrameLayout mLocalContainer;
private RelativeLayout mRemoteContainer;
private VideoCanvas mLocalVideo;
private VideoCanvas mRemoteVideo;
private ImageView mCallBtn;
private ImageView mMuteBtn;
private ImageView mSwitchCameraBtn;
private MediaDataObserverPlugin mediaDataObserverPlugin;
private final IRtcEngineEventHandler mRtcHandler = new IRtcEngineEventHandler() {
#Override
public void onJoinChannelSuccess(String channel, int uid, int elapsed) {
super.onJoinChannelSuccess(channel, uid, elapsed);
runOnUiThread(new Runnable() {
#Override
public void run() {
Log.i("Agora", "Join channel success, uid: " + (uid & 0xFFFFFFFFL));
}
});
}
#Override
public void onFirstRemoteVideoFrame(int uid, int width, int height, int elapsed) {
super.onFirstRemoteVideoFrame(uid, width, height, elapsed);
runOnUiThread(new Runnable() {
#Override
public void run() {
Log.i("Agora", "First remote video decoded, uid: " + (uid & 0xFFFFFFFFL));
setupRemoteVideo(uid);
}
});
}
#Override
public void onUserOffline(int uid, int reason) {
super.onUserOffline(uid, reason);
runOnUiThread(new Runnable() {
#Override
public void run() {
if (mediaDataObserverPlugin != null) {
mediaDataObserverPlugin.removeDecodeBuffer(uid);
}
Log.i("Agora", "User offline, uid: " + (uid & 0xFFFFFFFFL));
onRemoteUserLeft(uid);
}
});
}
#Override
public void onUserJoined(int uid, int elapsed) {
super.onUserJoined(uid, elapsed);
runOnUiThread(new Runnable() {
#Override
public void run() {
Log.i("agora", "Remote user joined, uid: " + (uid & 0xFFFFFFFFL));
setupRemoteVideo(uid);
}
});
}
};
private void onRemoteUserLeft(int uid) {
if (mRemoteVideo != null && mRemoteVideo.uid == uid) {
removeFromParent(mRemoteVideo);
// Destroys remote view
mRemoteVideo = null;
}
}
private ViewGroup removeFromParent(VideoCanvas canvas) {
if (canvas != null) {
ViewParent parent = canvas.view.getParent();
if (parent != null) {
ViewGroup group = (ViewGroup) parent;
group.removeView(canvas.view);
return group;
}
}
return null;
}
private void showButtons(boolean show) {
int visibility = show ? View.VISIBLE : View.GONE;
mMuteBtn.setVisibility(visibility);
mSwitchCameraBtn.setVisibility(visibility);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initUI();
Log.e(TAG, "Media Data Observer registered");
// Ask for permissions at runtime.
if (checkSelfPermission(REQUESTED_PERMISSIONS[0], PERMISSION_REQ_ID) &&
checkSelfPermission(REQUESTED_PERMISSIONS[1], PERMISSION_REQ_ID) &&
checkSelfPermission(REQUESTED_PERMISSIONS[2], PERMISSION_REQ_ID)) {
initEngineAndJoinChannel();
}
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onStop() {
super.onStop();
if (mediaDataObserverPlugin != null) {
mediaDataObserverPlugin.removeVideoObserver(this);
mediaDataObserverPlugin.removeAllBuffer();
}
}
private void initUI() {
mLocalContainer = findViewById(R.id.local_video_view_container);
mRemoteContainer = findViewById(R.id.remote_video_view_container);
mCallBtn = findViewById(R.id.btn_call);
mMuteBtn = findViewById(R.id.btn_mute);
mSwitchCameraBtn = findViewById(R.id.btn_switch_camera);
}
private boolean checkSelfPermission(String permission, int requestCode) {
if (ContextCompat.checkSelfPermission(this, permission) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, REQUESTED_PERMISSIONS, requestCode);
return false;
}
return true;
}
private void initEngineAndJoinChannel() {
initializeEngine();
setupVideoConfig();
setupLocalVideo();
joinChannel();
}
private void joinChannel() {
String token = "<access token>";
mediaDataObserverPlugin = MediaDataObserverPlugin.the();
MediaPreProcessing.setCallback(mediaDataObserverPlugin);
MediaPreProcessing.setVideoCaptureByteBuffer(mediaDataObserverPlugin.byteBufferCapture);
mediaDataObserverPlugin.addVideoObserver(this);
if (TextUtils.isEmpty(token)) {
token = null;
}
mRtcEngine.setChannelProfile(Constants.CHANNEL_PROFILE_COMMUNICATION);
mRtcEngine.joinChannel(token, "channel1", "", 0);
}
private void setupRemoteVideo(int uid) {
ViewGroup parent = mRemoteContainer;
if (mLocalVideo != null && parent.indexOfChild(mLocalVideo.view) > -1) {
parent = mLocalContainer;
}
if (mRemoteVideo != null) {
return;
}
if (mediaDataObserverPlugin != null) {
mediaDataObserverPlugin.addDecodeBuffer(uid);
}
SurfaceView view = RtcEngine.CreateRendererView(getBaseContext());
view.setZOrderMediaOverlay(parent == mLocalContainer);
parent.addView(view);
mRemoteVideo = new VideoCanvas(view, VideoCanvas.RENDER_MODE_HIDDEN, uid);
// Initializes the video view of a remote user.
mRtcEngine.setupRemoteVideo(mRemoteVideo);
}
private void setupLocalVideo() {
SurfaceView view = RtcEngine.CreateRendererView(getBaseContext());
view.setZOrderMediaOverlay(true);
mLocalContainer.addView(view);
// Initializes the local video view.
// RENDER_MODE_HIDDEN: Uniformly scale the video until it fills the visible boundaries. One dimension of the video may have clipped contents.
VideoCanvas localVideoCanvas = new VideoCanvas(view, VideoCanvas.RENDER_MODE_HIDDEN, 0);
mRtcEngine.setupLocalVideo(localVideoCanvas);
//mRtcEngine.setVideoSource(new CustomVideoSource());
}
private void setupVideoConfig() {
// In simple use cases, we only need to enable video capturing
// and rendering once at the initialization step.
// Note: audio recording and playing is enabled by default.
mRtcEngine.enableVideo();
mRtcEngine.setVideoEncoderConfiguration(new VideoEncoderConfiguration(
VideoEncoderConfiguration.VD_640x360,
VideoEncoderConfiguration.FRAME_RATE.FRAME_RATE_FPS_15,
VideoEncoderConfiguration.STANDARD_BITRATE,
VideoEncoderConfiguration.ORIENTATION_MODE.ORIENTATION_MODE_FIXED_PORTRAIT));
}
private void initializeEngine() {
try {
mRtcEngine = RtcEngine.create(getBaseContext(), getString(R.string.agora_app_id), mRtcHandler);
} catch (Exception e) {
Log.e("Agora", Log.getStackTraceString(e));
throw new RuntimeException("Check rtc sdk init fatal error - " + Log.getStackTraceString(e));
}
}
private void startCall() {
setupLocalVideo();
joinChannel();
}
private void endCall() {
removeFromParent(mLocalVideo);
mLocalVideo = null;
removeFromParent(mRemoteVideo);
mRemoteVideo = null;
leaveChannel();
}
private void leaveChannel() {
if (mediaDataObserverPlugin != null) {
mediaDataObserverPlugin.removeVideoObserver(this);
mediaDataObserverPlugin.removeAllBuffer();
}
mRtcEngine.leaveChannel();
}
public void onLocalAudioMuteClicked(View view) {
mMuted = !mMuted;
// Stops/Resumes sending the local audio stream.
mRtcEngine.muteLocalAudioStream(mMuted);
int res = mMuted ? R.drawable.btn_mute : R.drawable.btn_unmute;
mMuteBtn.setImageResource(res);
}
public void onSwitchCameraClicked(View view) {
// Switches between front and rear cameras.
mRtcEngine.switchCamera();
}
public void onCallClicked(View view) {
if (mCallEnd) {
startCall();
mCallEnd = false;
mCallBtn.setImageResource(R.drawable.btn_endcall);
} else {
endCall();
mCallEnd = true;
mCallBtn.setImageResource(R.drawable.btn_startcall);
}
showButtons(!mCallEnd);
}
#Override
protected void onDestroy() {
super.onDestroy();
if (!mCallEnd) {
leaveChannel();
}
/*
Destroys the RtcEngine instance and releases all resources used by the Agora SDK.
This method is useful for apps that occasionally make voice or video calls,
to free up resources for other operations when not making calls.
*/
RtcEngine.destroy();
}
#Override
public void onRecordAudioFrame(byte[] data, int audioFrameType, int samples, int bytesPerSample, int channels, int samplesPerSec, long renderTimeMs, int bufferLength) {
}
#Override
public void onPlaybackAudioFrame(byte[] data, int audioFrameType, int samples, int bytesPerSample, int channels, int samplesPerSec, long renderTimeMs, int bufferLength) {
}
#Override
public void onPlaybackAudioFrameBeforeMixing(int uid, byte[] data, int audioFrameType, int samples, int bytesPerSample, int channels, int samplesPerSec, long renderTimeMs, int bufferLength) {
}
#Override
public void onMixedAudioFrame(byte[] data, int audioFrameType, int samples, int bytesPerSample, int channels, int samplesPerSec, long renderTimeMs, int bufferLength) {
}
#Override
public void onCaptureVideoFrame(byte[] data, int frameType, int width, int height, int bufferLength, int yStride, int uStride, int vStride, int rotation, long renderTimeMs) {
Log.d(TAG, "onCaptureVideoFrame called");
}
#Override
public void onRenderVideoFrame(int uid, byte[] data, int frameType, int width, int height, int bufferLength, int yStride, int uStride, int vStride, int rotation, long renderTimeMs) {
Log.d(TAG, "onRenderVideoFrame called");
}
#Override
public void onPreEncodeVideoFrame(byte[] data, int frameType, int width, int height, int bufferLength, int yStride, int uStride, int vStride, int rotation, long renderTimeMs) {
Log.d(TAG, "onPreEncodeVideoFrame0");
}
}
Not sure what I'm doing wrong. Any help would be appreciated. Thanks!
Gradle
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.2"
ndkVersion '21.4.7075529'
defaultConfig {
applicationId "com.example.agoratest"
minSdkVersion 26
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation 'io.agora.rtc:full-sdk:3.3.1'
implementation project(path: ':lib-raw-data')
}
I used this library: https://github.com/johannilsson/android-pulltorefresh
works well, but in a ListView simple (simple is what I say in the pattern of cell android).
I wore a Adpter put in my custom ListView to cells with image, title and description.
my class with adpter:
public class extends Main_podcast ListActivity implements {OnItemClickListener
private Bitmap pathImgSmal;
/ ** Called When the activity is first created. * /
# Override
public void onCreate (Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
Mybundle bundle = new Bundle ();
mybundle.putString ("podcastnumber", "0");
/ / Check for connection and starts downloading the XML
Connected conected Boolean = (this);
if (conected == true) {
DoInBackground new (). execute ();
Else {}
new AlertDialog.Builder (Main_podcast.this)
. SetTitle ("Alert!")
. SetMessage ("Unable to connect to the Internet," +
"Check your network or try again later.")
. SetNeutralButton ("OK"
new DialogInterface.OnClickListener () {
public void onClick (DialogInterface dialog,
int which) {}
}). Show ();
}
}
/ / Method calls the XML Parser
public void do_update ()
{
PodcastParser.parse ();
}
/ / Method that populates the list view with XML parameters
public void populate_listview ()
{
List <Itens> podcastList <Itens> = new ArrayList ();
for (int i = 0; i <arraysPodcast.PodcastTitle.length; i + +) {
end item Items = new Items ();
item.setTitle (arraysPodcast.PodcastTitle [i]);
item.setData (arraysPodcast.PodcastData [i]);
item.setImage (arraysPodcast.ArrayIMGPodcast [i]);
podcastList.add (item);
}
setListAdapter (new PodcastAdapter (this, podcastList));
ListView shot getListView = ();
shot.setOnItemClickListener ((OnItemClickListener) this);
}
public void onItemClick (AdapterView <?> arg0, View v, int position, long id) {
/ / Start the Activity podcast regarding your number from the list
Myintent intent = new Intent ("com.example.player.PODCAST");
Mybundle bundle = new Bundle ();
mybundle.putInt ("podcastnumber" position);
myintent.putExtras (mybundle);
startActivity (myintent);
}
private class extends DoInBackground AsyncTask <Void, Void, Void>
implements DialogInterface.OnCancelListener
{
ProgressDialog private dialog;
protected void OnPreExecute ()
{
dialog = ProgressDialog.show (Main_podcast.this, "", "Loading Podcasts ...", true);
}
protected void doInBackground (Void. unused ..)
{
do_update ();
return null;
}
OnPostExecute protected void (Void unused)
{
dialog.dismiss ();
populate_listview ();
}
public void onCancel (DialogInterface dialog)
{
cancel (true);
dialog.dismiss ();
}
}
public static boolean Connected (Context context) {
try {
= ConnectivityManager cm (ConnectivityManager)
context.getSystemService (Context.CONNECTIVITY_SERVICE);
LogSync String = null;
LogToUserTitle String = null;
if (cm.getNetworkInfo (ConnectivityManager.TYPE_MOBILE). isConnected ()) {
LogSync + = "\ nConectado 3G Internet";
LogToUserTitle + = "Connected to 3G Internet";
return true;
} Else if (cm.getNetworkInfo (ConnectivityManager.TYPE_WIFI). IsConnected ()) {
LogSync + = "\ nConectado WIFI Internet";
LogToUserTitle + = "Connected to Wireless Internet";
return true;
Else {}
LogSync + = "\ nYou have internet connection";
LogToUserTitle + = "Do not have an internet connection";
return false;
}
} Catch (Exception e) {
return false;
}
}
} / / Class
the question is, how do I implement my class with a custom cell library johannilsson?
any help is welcome!
decided as follows:
public class PullToRefreshActivity extends ListActivity implements OnItemClickListener {
private LinkedList<String> mListItems;
private List<Itens> podcastList;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pull_to_refresh);
// Set a listener to be invoked when the list should be refreshed.
// ======================================================
Bundle mybundle = new Bundle();
mybundle.putString("podcastnumber", "0");
//verifica se há conexao e inicia download do XML
Boolean conected = Conectado(this);
if(conected == true){
new DoInBackground().execute();
}else{
new AlertDialog.Builder(PullToRefreshActivity.this)
.setTitle("Alerta!")
.setMessage("Não foi possível estabelecer uma conexão com a Internet," +
"verifique sua rede ou tente novamente mais tarde.")
.setNeutralButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {}
}).show();
}
// ======================================================
((PullToRefreshListView) getListView()).setOnRefreshListener(new OnRefreshListener() {
#Override
public void onRefresh() {
// Do work to refresh the list here.
new DoInBackground().execute();
}
});
}
// ==================================================================
public void do_update()
{
PodcastParser.parse();
}
//metodo que preenche a list view com parametros do XML
public void populate_listview()
{
podcastList = new ArrayList<Itens>();
for (int i = 0; i < arraysPodcast.PodcastTitle.length; i++) {
final Itens item = new Itens();
item.setTitle(arraysPodcast.PodcastTitle[i]);
item.setData(arraysPodcast.PodcastData[i]);
item.setImage(arraysPodcast.ArrayIMGPodcast[i]);
podcastList.add(item);
}
setListAdapter(new PodcastAdapter(this, podcastList));
((PullToRefreshListView) getListView()).setOnItemClickListener((OnItemClickListener) this);
}
public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
//Inicia Activity da podcast referente a seu numero da lista
Intent myintent = new Intent("com.example.player.PODCAST");
Bundle mybundle = new Bundle();
mybundle.putInt("podcastnumber", (position-1));
Log.e("posicao na lista",""+position);
myintent.putExtras(mybundle);
startActivity(myintent);
}
private class DoInBackground extends AsyncTask<Void, Void, Void>
implements DialogInterface.OnCancelListener
{
private ProgressDialog dialog;
protected void onPreExecute()
{
dialog = ProgressDialog.show(PullToRefreshActivity.this, "", "Carregando Podcasts...", true);
}
protected Void doInBackground(Void... unused)
{
PodcastAdapter.topBar=true;
do_update();
return null;
}
protected void onPostExecute(Void unused)
{
((PullToRefreshListView) getListView()).onRefreshComplete();
dialog.dismiss();
populate_listview();
}
public void onCancel(DialogInterface dialog)
{
cancel(true);
dialog.dismiss();
}
}
public static boolean Conectado(Context context) {
try {
ConnectivityManager cm = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
String LogSync = null;
String LogToUserTitle = null;
if (cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isConnected()) {
LogSync += "\nConectado a Internet 3G ";
LogToUserTitle += "Conectado a Internet 3G ";
return true;
} else if(cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnected()){
LogSync += "\nConectado a Internet WIFI ";
LogToUserTitle += "Conectado a Internet WIFI ";
return true;
} else {
LogSync += "\nNão possui conexão com a internet ";
LogToUserTitle += "Não possui conexão com a internet ";
return false;
}
} catch (Exception e) {
return false;
}
}
}
What should I do to call thread's pause() method from showExitDialog() here ?
Here's Start Game class
package game.mainmenu;
import game.view.ViewPanel;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Window;
import android.view.WindowManager;
public class StartGame extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN );
setContentView(new ViewPanel(this));
}
#Override
protected void onPause() {
super.onPause();
//saveScores();
this.finish();
System.exit(1);// pause game when Activity pauses
}
#Override
public boolean onKeyDown(final int pKeyCode, final KeyEvent pEvent) {
if (pKeyCode == KeyEvent.KEYCODE_BACK
&& pEvent.getAction() == KeyEvent.ACTION_DOWN) {
showExitDialog();
return true;
}
return super.onKeyDown(pKeyCode, pEvent);
}
public void showExitDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(StartGame.this);
builder.setMessage("Are you sure you want to exit?")
.setCancelable(false)
.setTitle("EXIT")
.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
StartGame.this.finish();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
//alert.setIcon(android.R.drawable.star_on);
alert.show();
}
}
Here's class with main thread
public class ViewManager extends Thread
{
//some states here
public static final int STATE_LOSE = 1;
public static final int STATE_PAUSE = 2;
public static final int STATE_READY = 3;
public static final int STATE_RUNNING = 4;
public static final int STATE_WIN = 5;
//..some not mention code here../
public ViewManager(SurfaceHolder surfaceHolder, Context context)
{
mSurfaceHolder = surfaceHolder;
mRunning = false;
mHealthBar = new Rect(0,0,0,0);
mLinePaint = new Paint();
mLinePaint.setAntiAlias(true);
mLinePaint.setARGB(255, 0, 255, 0);
mLinePaint.setTextSize(16);
mLinePaint.setStrokeWidth(3);
mContext = context;
Resources res = context.getResources();
//..some not mention code here../
InitElements(res);
mHero = new PlayerAnimated(mPlayerImage, FIELD_WIDTH/2, 600, 64, 64, 3, 3, context, mEnemiesList);
//mBoom = new Explosion(mExplosionImage, 200, 500, 64, 64, 7, 7);
mEnemyImage = BitmapFactory.decodeResource(res, R.drawable.enemyone);
setState(STATE_RUNNING);
}
/**
* threads state
* #param running
*/
public void setRunning(boolean running)
{
mRunning = running;
}
//..some not mention code here../
public void run()
{
while (mRunning)
{
Canvas canvas = null;
try
{
// подготовка Canvas-а
canvas = mSurfaceHolder.lockCanvas();
synchronized (mSurfaceHolder)
{
if(mMode == STATE_RUNNING){
// draw if not paused
addEneimes(mContext);
updateStuff();
doDraw(canvas);
}
else
{
pauseDraw(canvas);
}
ViewPanel.displayFps(canvas, aString);
aString = Integer.toString(hudscore.getScore());
}
}
catch (Exception e) { }
finally
{
if (canvas != null)
{
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
//..some not mention code here../
public void pause() {
synchronized (mSurfaceHolder) {
setState(STATE_PAUSE);
mLastFiredTime = System.currentTimeMillis() + 100;
}
}
public void unpause() {
//
synchronized (mSurfaceHolder) {
setState(STATE_RUNNING);
mLastFiredTime = System.currentTimeMillis() + 100;
}
}
public void setState(int mode)
{
mMode = mode;
}
public void pauseDraw(Canvas canvas)
{
canvas.drawBitmap(Bitmap.createBitmap(FIELD_WIDTH, FIELD_HEIGHT, Bitmap.Config.RGB_565), 0, 0, null);
}
}
Not really a clear question, since you are not telling us where you want to create and start the Thread in the main code. Let's assume it's inside onCreate:
public class StartGame extends Activity {
private ViewManager viewManager = new ViewManager();
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN );
setContentView(new ViewPanel(this));
viewManager.start(); // start viewManager thread
}
// other methods
public void showExitDialog() {
viewManager.pause(); // call pause
// rest of code
}
}