I'm working on a small piece of code using a TextureView to display the result of a MediaPlayer.
I'm facing an issue trying to mix managed code and native code using NDK.
If my Activity inherit from NativeActivity instead of Activity, my app is broken.
Is it a known limitation? Is it a related to the NDK glue?
Here is my Activity Code:
public class SurfaceActivity extends NativeActivity {
private static final boolean VERBOSE = true;
private static final String TAG = "native";
private static final String FILES_DIR = "/sdcard/";
private static final String INPUT_FILE = "video1.mp4";
TextureView mView = null;
MediaPlayer mPlayer = new MediaPlayer();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
File inputFile = new File(FILES_DIR, INPUT_FILE);
mPlayer.setDataSource(inputFile.toString());
} catch(Exception e) {
Log.e(TAG, "File Exception", e);
}
FrameLayout content = new FrameLayout(this);
content.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT));
mView = new TextureView(this);
mView.setSurfaceTextureListener( new TextureViewListener( ) );
mView.setOpaque(false);
mView.setLayoutParams(new FrameLayout.LayoutParams(200, 200));
mView.setBackgroundColor(Color.TRANSPARENT);
content.addView(mView);
addContentView(content, content.getLayoutParams());
}
public class TextureViewListener implements TextureView.SurfaceTextureListener
{
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
Log.i(TAG,"onSurfaceTextureAvailable");
mPlayer.setSurface(new Surface(surface));
mPlayer.prepareAsync();
mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
}
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return true;
}
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
}
}
And C++ side:
#include <jni.h>
#include <errno.h>
#include <android/log.h>
#include <android_native_app_glue.h>
#include <android/native_window_jni.h>
void android_main( android_app* state )
{
app_dummy();
__android_log_print(ANDROID_LOG_INFO, "native-lib", "android_main");
}
Finally in the manifest:
android:hardwareAccelerated="true"
EDIT:
Ok, after reading the logcat, it seem that the TextureView is not created:
W/TextureView( 571): A TextureView or a subclass can only be used with hardware acceleration enabled.
Complete manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.sample.surfaceview" android:versionCode="1" android:versionName="1.0">
<uses-sdk android:minSdkVersion="11" android:targetSdkVersion="19" />
<uses-feature android:glEsVersion="0x00020000">
</uses-feature>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
</uses-permission>
<application android:allowBackup="true" android:icon="#drawable/ic_launcher" android:label="#string/app_name" android:theme="#style/AppTheme" android:hasCode="true" android:hardwareAccelerated="true" android:debuggable="true">
<activity android:name="com.sample.surfaceview.SurfaceActivity" android:hardwareAccelerated="true" android:label="#string/app_name" android:configChanges="orientation|keyboardHidden">
<!-- Tell NativeActivity the name of or .so -->
<meta-data android:name="android.app.lib_name" android:value="native" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Related
I am making Music Player which downloads music from Firebase.
Its working fine but I cannot play music in background.
It works for like 1.5 minute (after locking screen) and it stops.
In logs after I lock screen it says "Inactivity, disconnecting from Service".
I think this may be main problem here.
Here code :
Fragment of Playing Music:
public class PlayerFragment extends Fragment {
private FirebaseStorage storage;
private ImageButton main_btn, next_btn, back_btn, fav_btn, settings_btn;
private Uri localSong;
private Intent myService;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view= inflater.inflate(R.layout.fragment_player, container, false);
storage = FirebaseStorage.getInstance();
main_btn= view.findViewById(R.id.player_main_btn);
next_btn= view.findViewById(R.id.player_next_btn);
back_btn= view.findViewById(R.id.player_back_btn);
fav_btn = view.findViewById(R.id.player_song_fav_btn);
settings_btn = view.findViewById(R.id.player_song_options_btn);
storage.getReference().child("songs/ni_bien_ni_mal.mp3").getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
localSong=uri;
}
});
MainActivity mainActivity = (MainActivity) getActivity();
myService = new Intent(getActivity(), BackgroundSoundService.class);
main_btn.setOnClickListener(v -> {
if( main_btn.getDrawable().getConstantState().equals( main_btn.getContext().getDrawable(R.drawable.ic_play).getConstantState()))
{
new Thread(new Runnable() {
#Override
public void run() {
myService.putExtra("uri",localSong.toString() );
mainActivity.startService(myService);
}
}).start();
main_btn.setImageResource(R.drawable.ic_pause);
}
else
{
new Thread(new Runnable() {
#Override
public void run() {
// mainActivity.stopService(myService);
main_btn.setImageResource(R.drawable.ic_play);
}
}).start();
}
});
fav_btn.setOnClickListener(v->{
if( fav_btn.getDrawable().getConstantState().equals( fav_btn.getContext().getDrawable(R.drawable.ic_heart_empty).getConstantState()))
{
fav_btn.setImageResource(R.drawable.ic_heart_full);
}else{
fav_btn.setImageResource(R.drawable.ic_heart_empty);
}
});
return view;
}
}
Manifest: ( Service declaration is at bottom)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.company.altasnotas">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<meta-data
android:name="preloaded_fonts"
android:resource="#array/preloaded_fonts" />
<application
android:allowBackup="true"
android:icon="#drawable/altas_notes"
android:label="#string/app_name"
android:roundIcon="#drawable/altas_notes"
android:supportsRtl="true"
android:testOnly="false"
android:theme="#style/Theme.AltasNotas">
<activity
android:name=".IntroActivity"
android:label="#string/app_name"
android:theme="#style/Theme.AltasNotas.NoActionBar"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/facebook_app_id"
tools:replace="android:value" />
<meta-data
android:name="preloaded_fonts"
android:resource="#array/preloaded_fonts" />
<activity
android:name="com.facebook.FacebookActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="#string/app_name" />
<activity
android:name="com.facebook.CustomTabActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="#string/fb_login_protocol_scheme" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:screenOrientation="portrait">
</activity>
<service android:enabled="true" android:name=".BackgroundSoundService" />
</application>
</manifest>
Service :
public class BackgroundSoundService extends Service {
String song_string;
int x;
private static final String TAG = "BackgroundSoundService";
MediaPlayer player;
public IBinder onBind(Intent arg0) {
Log.i(TAG, "onBind()" );
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
public int onStartCommand(Intent intent, int flags, int startId) {
song_string= intent.getStringExtra("uri");
if (song_string != null) {
System.out.println("Song string : " + song_string);
player = MediaPlayer.create(this, Uri.parse(song_string));
player.setLooping(false); // Set looping
player.setVolume(0.5f, 0.5f);
if (!(String.valueOf(x) == null || String.valueOf(x).isEmpty())) {
player.seekTo(x);
}
player.start();
}
return Service.START_STICKY;
}
public IBinder onUnBind(Intent arg0) {
Log.i(TAG, "onUnBind()");
return null;
}
public void onStop() {
Log.i(TAG, "onStop()");
}
public void onPause() {
Log.i(TAG, "onPause()");
x=player.getCurrentPosition();
player.pause();
}
#Override
public void onDestroy() {
if(player!=null) {
player.stop();
player.reset();
player.release();
Log.i(TAG, "onCreate() , service stopped...");
}
}
#Override
public void onLowMemory() {
Log.i(TAG, "onLowMemory()");
}
}
Despite Sticky and declaration in Manifest , it still doesnt work in background. Also I want to add pause button and I dont know exacly how can I do that.
Hi I'm integrating Chartboost in my game but the ads aren't showing in live and testing mode. I followed this tutorial in exact manner and there is no error in my code https://github.com/itsabhiaryan/AdService-LibGDX
In https://github.com/itsabhiaryan/AdService-LibGDX/blob/master/android/src/com/its/adservice/AndroidLauncher.java line 34 I changed to ad=new ChartBoostHelper(this); I removed the onSaveInstanceState and onRestoreInstanceState methods and also I made other changes. I called the show ads method in the right place but it does not show.
I registered Chartboost and added my appId and signature accordingly and also set the setting to landscape and interstitial ads. I have modified the AndroidManifest file as in the tutorial and added the jar file in /android/libs folder. Am I missing something or doing something wrong?
This is my android/AndroidLauncher.java and the ChartBoostHelper and the Ad class is the same as in the github link.
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.RelativeLayout;
import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
public class AndroidLauncher extends AndroidApplication implements ActionResolver {
private Ad ad;
public RelativeLayout layout;
View gameView;
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
config.useAccelerometer = false;
config.useCompass = false;
config.useImmersiveMode = true;
layout = new RelativeLayout(this);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
layout.setLayoutParams(params);
View gameView=initializeForView(new MyGame(this), config);
RelativeLayout.LayoutParams gameViewParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
gameViewParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
gameViewParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
gameView.setLayoutParams(gameViewParams);
layout.addView(gameView);
ad=new ChartBoostHelper(this);
ad.embedView(layout);
setContentView(layout);
#Override
public void onResume() {
super.onResume();
ad.resume();
}
#Override
public void onPause() {
ad.pause();
super.onPause();
}
#Override
public void onDestroy() {
ad.destroy();
super.onDestroy();
}
#Override
protected void onStart() {
super.onStart();
ad.start();
}
#Override
protected void onStop() {
super.onStop();
ad.stop();
}
#Override
public void showOrLoadInterstitial() {
ad.showOrLoadInterstitial();
}
#Override
public boolean showVideoAd(boolean isRewarded) {
return ad.showVideoAd(isRewarded);
}
#Override
protected void onActivityResult (int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
}
This is the core/ActionResolver.java
public interface ActionResolver {
void showOrLoadInterstitial();
boolean showVideoAd(boolean isRewarded);
}
This is the part where I call showOrLoadInterstitial(); in the render method inside of core/GameScreen.java
if((touchPos.x >= camera.position.x-(replaybutton.getWidth()/2 + 50) && touchPos.x <= (camera.position.x - (replaybutton.getWidth()/2 + 50))+replaybutton.getWidth()) && (touchPos.y>=55 && touchPos.y<=55+replaybutton.getHeight())){
if(SplashScreen.adcount >= 4 && prefs.getBoolean("ADBLOCK") == false){
game.actionResolver.showOrLoadInterstitial();
SplashScreen.adcount = 0;
}
game.setScreen(new MainMenu(game,this.asset));
dispose();
}
Here is my AndroidManifest.xml file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.robot1gamesfree.game"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/GdxTheme" >
<activity
android:name="com.robot1gamesfree.game.AndroidLauncher"
android:label="#string/app_name"
android:screenOrientation="sensorLandscape"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<activity android:name="com.chartboost.sdk.CBImpressionActivity"
android:excludeFromRecents="true"
android:hardwareAccelerated="true"
android:theme="#android:style/Theme.Translucent.NoTitleBar.Fullscreen"
android:configChanges="keyboardHidden|orientation|screenSize" />
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="com.android.vending.BILLING" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
i make a project which includes following jars.
in build path as follows
Main.java
public class Main extends Activity
{
public int welcomeScreenDisplay = 1000;
boolean ispr=false;
#Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.splash);
/** create a thread to show splash up to splash time */
Thread welcomeThread = new Thread() {
int wait = 0;
#Override
public void run() {
try {
super.run();
while (wait < welcomeScreenDisplay) {
sleep(100);
wait += 100;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
Intent mIntent=new Intent(getApplicationContext(), DrawerActivity .class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(mIntent);
finish();
}
}
};
welcomeThread.start();
}
}
DrawerActivity.java
package com.pkg.name;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
public class DrawerActivity extends FragmentActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.spinner_year);
}
}
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.pkg.name"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="11" />
<application
android:allowBackup="true"
android:icon="#drawable/app_icon"
android:label="#string/app_name"
android:theme="#style/CustomActionBarTheme" >
<activity
android:name="com.pkg.name.Splash"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden|stateVisible" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.pkg.name.DrawerActivity"
android:screenOrientation="portrait"
android:theme="#style/AppBaseTheme"
android:windowSoftInputMode="stateHidden|stateVisible" >
</activity>
</application>
</manifest>
When i run my application in device it give me error like
FATAL EXCEPTION: Thread-912
java.lang.NoClassDefFoundError:com.pkg.name.DrawerActivity
at com.pkg.name.Splash$1.run(Splash.java:53)
Any idea how can i solve this ?your all suggestions are appreciable.
Since 2 days I'm trying to get an UtteranceProgressListener to work. I've been trying a lot of codes from Stackoverflow and some other sites - nothing worked for me. Here is my current code:
This is my method for activating text-to-speech. It's called in onCreate.
private void activateTTS() {
tts=new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
int result=tts.setLanguage(Locale.getDefault());
if (result==TextToSpeech.LANG_MISSING_DATA ||
result==TextToSpeech.LANG_NOT_SUPPORTED) {
}
tts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
#Override
public void onDone(String utteranceId) {
if (utteranceId == "myId") {
//[...] all my code that is not being called
//when speaking is finished
}
}
#Override
public void onError(String utteranceId) {
}
#Override
public void onStart(String utteranceId) {
}
});
}
}
});
}
I know that there is the need of a HashMap with utteranceId to identify the utterance. Here my code (just a part of a method):
params = new HashMap<String, String>();
params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "myId");
tts.speak(myString, TextToSpeech.QUEUE_FLUSH, params);
My important variables (for tts and the HashMap) are:
private static TextToSpeech tts;
private HashMap<String, String> params;
Any code is a part of my class "TTSPlayer" that extends MainActivity but does not implement anything:
public class TTSPlayer extends MainActivity {
//[all my code]
}
Edit: Here is my manifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.saschaha.readit"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:configChanges="orientation|keyboardHidden|screenSize"
android:name="com.saschaha.readit.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.saschaha.readit.TTSPlayer"
android:label="#string/ReadIt" >
</activity>
</application>
</manifest>
The tts is working fine (text is beeing spoken) but UtteranceProgressListener does not work (my code is not being called). I don't know why. Any help?
Thanks a lot!!
The error is with the String comparison
if (utteranceId == "myId")
Change it to
if ("myId".equals(utteranceId))
i am unable to get the the front facing camera (camera id 1). open cam #1 failed appears on screen when i try to run the following code.
enclosed a snippet. any help will be appreciated (i am trying it on nexus 4).
Tester.java
package com.example.cam;
import java.util.HashMap;
import java.util.Iterator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.Menu;
import android.widget.Toast;
public class Tester extends Activity {
private static final int[] camIds = { Camera.CameraInfo.CAMERA_FACING_BACK, Camera.CameraInfo.CAMERA_FACING_FRONT };
#SuppressLint("UseSparseArrays")
private final HashMap<Integer, Camera> camMap = new HashMap<Integer, Camera>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
#Override
protected void onResume() {
super.onResume();
if (!checkCameraHardware())
finish();
getCameras();
releaseCamera();
}
#Override
protected void onPause() {
super.onPause();
releaseCamera();
}
#Override
protected void onStop() {
super.onStop();
releaseCamera();
}
#Override
protected void onDestroy() {
super.onDestroy();
releaseCamera();
}
private final void doToast(final String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
private final void getCameras() {
for (int camId : camIds)
try {
camMap.put(camId, Camera.open(camId));
doToast("open cam #" + camId + " succeeded");
} catch (Exception e) {
doToast("open cam #" + camId + " failed");
}
}
private final void releaseCamera() {
final Iterator<Integer> iter = camMap.keySet().iterator();
while (iter.hasNext())
camMap.remove(iter.next()).release();
}
private final boolean checkCameraHardware() {
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA))
return camIds.length <= Camera.getNumberOfCameras();
else
return false;
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.cam"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT" />
<uses-permission android:name="android.permission.CAPTURE_SECURE_VIDEO_OUTPUT" />
<uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.cam.Tester"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>