Android Studio: Custom Camera Preview won't display - java

I am trying to build a custom camera in Android Studio (and I am fairly new to it). I have been following this guide: https://developer.android.com/guide/topics/media/camera
I did manifest declarations for using camera in manifest-file
I've accessed the camera
I created preview class CameraPreview
I placed preview in layout
When I open the app I can only see my button "Capture" and no preview of the camera. Why?
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.customcamera">
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera2.full" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.CustomCamera">
<activity
android:name=".MainActivity"
android:exported="true"
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>
CameraPreview.java:
package com.example.customcamera;
import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.IOException;
/** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public static final String TAG = "TAG";
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
}
MainActivity.java:
package com.example.customcamera;
import androidx.appcompat.app.AppCompatActivity;
import android.hardware.Camera;
import android.os.Bundle;
import android.widget.FrameLayout;
public class MainActivity extends AppCompatActivity {
private Camera mCamera;
private CameraPreview mPreview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create an instance of Camera
mCamera = getCameraInstance();
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
}
/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance, int between 0 and 1?
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<FrameLayout
android:id="#+id/camera_preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
/>
<Button
android:id="#+id/button_capture"
android:text="Capture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
</LinearLayout>
I am using:
Xiaomi mi 9T, Android version: 10
Minimum SDK: API 21 (Android 5.0 Lollipop)
In addition, Kotlin (CameraX) is not an option for me.
Solution
After run, go to app settings -> locate your app -> enable camera permission

Solution
After run, go to app settings -> locate your app -> enable camera permission

Related

Exoplayer playing audio even when the PlayerView has been paused

I'm creating an Exoplayer video player which plays a mp4 file containing video and audio from a url. The video and audio plays properly but when the video player is paused, the audio is still being played. I don't know how I can fix this. I'm assuming that the problem occurs due to my android device. I'm leaving my code, app's info, android device info below and a video clip of my problem. If someone can use my code and tell me if they are experiencing the same problem, it will be thankful. Please Help Me.
The app's detail:
Using API 21: Android 5.0 (Lollipop). Contains Internet Permission. Importing implementation 'com.google.android.exoplayer:exoplayer:2.8.1'.
Device detail:
Type: Android Tablet. Android Version : 5.1.1
The MainActivity.java:
import android.content.pm.ActivityInfo;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MergingMediaSource;
import com.google.android.exoplayer2.source.SingleSampleMediaSource;
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity
{
SimpleExoPlayer video_player;
PlayerView player_screen;
DefaultTrackSelector track_selector;
DefaultBandwidthMeter band_width_meter = new DefaultBandwidthMeter();
MediaSource mediaSource_both;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
player_screen = findViewById (R.id.player_screen);
player_screen.requestFocus();
TrackSelection.Factory video_track_selection_factory = new AdaptiveTrackSelection.Factory(band_width_meter);
track_selector = new DefaultTrackSelector(video_track_selection_factory);
video_player = ExoPlayerFactory.newSimpleInstance(this, track_selector);
player_screen.setPlayer(video_player);
video_player.setPlayWhenReady(true);
DataSource.Factory data_source_factory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "Application Name"), new DefaultBandwidthMeter());
Uri url = Uri.parse("http://dash.akamaized.net/akamai/bbb/bbb_1280x720_60fps_6000k.mp4");
mediaSource_both = new ExtractorMediaSource.Factory(data_source_factory).createMediaSource(url);
video_player.prepare(mediaSource_both);
}
}
The activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.exoplayer2.ui.PlayerView
android:id="#+id/player_screen"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:use_controller="true" />
</android.support.constraint.ConstraintLayout>
Video Clip of the problem (The video has been uploaded on OpenLoad server):
https://openload.co/embed/NrlMUxUP0C4/problem.mp4
I made a very easy sample app to reproduce the issue
but yet too see any problem neither with the player or video
here is the code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
SimpleExoPlayerView simpleExoPlayerView = findViewById(R.id.player_view);
SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(this, new DefaultTrackSelector(new DefaultBandwidthMeter.Builder().build()));
SimpleCache downloadCache = new SimpleCache(new File(getCacheDir(), "exoCache"), new NoOpCacheEvictor());
String uri = "http://dash.akamaized.net/akamai/bbb/bbb_1280x720_60fps_6000k.mp4";
DataSource.Factory dataSourceFactory = new CacheDataSourceFactory(downloadCache, new DefaultDataSourceFactory(this, "seyed"));
MediaSource mediaSource = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(uri));
player.addListener(new Player.EventListener() {
#Override
public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {
Log.d("exo", "timeLine Changed");
}
#Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
}
#Override
public void onLoadingChanged(boolean isLoading) {
Log.d("exo", "loding changed= " + isLoading);
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
Log.d("exo", "state changed");
}
#Override
public void onRepeatModeChanged(int repeatMode) {
}
#Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
}
#Override
public void onPlayerError(ExoPlaybackException error) {
Log.e("exo", "exoplayer error", error);
}
#Override
public void onPositionDiscontinuity(int reason) {
}
#Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
}
#Override
public void onSeekProcessed() {
Log.d("exo", "seek processed");
}
});
player.prepare(mediaSource);
simpleExoPlayerView.setPlayer(player);
player.setPlayWhenReady(true);
}
here is the layout:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".MainActivity"
tools:showIn="#layout/activity_main">
<com.google.android.exoplayer2.ui.SimpleExoPlayerView
android:id="#+id/player_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.constraint.ConstraintLayout>
manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyDownloadService"
android:exported="false"/>
</application>
and lastly the build gradle file:
dependencies {
implementation 'com.android.support:appcompat-v7:27.0.2'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.android.support:design:27.0.2'
implementation 'com.google.android.exoplayer:exoplayer:2.8.2'
}
Update 17/18/2018
Actually the problem you are facing is because of this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); line.
when you run your activity it starts in portrait mode and everything is fine (without this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);) and one exoplayer is created and starts the playback.
but when you change the orientation during startup of the activity. android trys to destroy the activity and create another one here comes your problem:
first activity does not get destroyed because you forget to realease the ExoPlayer in onDestroy() and when the new activity is created a new exoplayer is also created and both of them keep the playback going. when you pause the playback you actually pausing the second one not the first one. this behavior is called memory leak.
first of all make sure you call .release() in onDestroy() of the activity.
and then for orientation you have couple of options:
1.specify the orientation of the activity in the manifest so android apply it before the creation of the activity
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar"
android:screenOrientation="sensorLandscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
2.prevent android from killing the activity on config changes:
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar"
android:configChanges="orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
hope it helps you
you can also chek out this sample (with a small and minor difference) on github:

How can I turn on and off mobile data using toggle button?

Today I have done a task using toggle button. The mobile data needs to be turned on when I press the enable toggle button, and it should be turned off when I press the same button. I had done everything and when I press the enable button, the mobile data remains off. In fact I have added all the manifest permissions. The mobile data should turn on when I press the toggle button. Please help me friends,and also let me know where I committed mistake. I hereby enclosed my XML and Java coding. Please help me friends, Many thanks in advance.
MainActivity.java:
import android.app.Activity;
import android.content.Context;
import android.net.ConnectivityManager;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
import android.os.Bundle;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MainActivity extends Activity{
// constants
static final String STATUS_ON = "Mobile Data: Enable";
static final String STATUS_OFF = "Mobile Data: Disable";
static final String TURN_ON = "Enable";
static final String TURN_OFF = "Disable";
// controls
TextView TVMobileData;
ToggleButton tBMobileData;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// load controls
TVMobileData=(TextView)findViewById(R.id.TVMobileData);
tBMobileData=(ToggleButton)findViewById(R.id.tBMobileData);
// set click event for button
tBMobileData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// check current state first
boolean state = isMobileDataEnable();
// toggle the state
if(state)toggleMobileDataConnection(false);
else toggleMobileDataConnection(true);
// update UI to new state
updateUI(!state);
}
});
}
public void updateUI(boolean state) {
//set text according to state
if(state) {
TVMobileData.setText(STATUS_ON);
tBMobileData.setText(TURN_OFF);
} else {
TVMobileData.setText(STATUS_OFF);
tBMobileData.setText(TURN_ON);
}
}
public boolean isMobileDataEnable() {
boolean mobileDataEnabled = false; // Assume disabled
ConnectivityManager cm = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
try {
Class cmClass = Class.forName(cm.getClass().getName());
Method method = cmClass.getDeclaredMethod("getMobileDataEnabled");
method.setAccessible(true); // Make the method callable
// get the setting for "mobile data"
mobileDataEnabled = (Boolean)method.invoke(cm);
} catch (Exception e) {
// Some problem accessible private API and do whatever error handling you want here
}
return mobileDataEnabled;
}
public boolean toggleMobileDataConnection(boolean ON)
{
try {
//create instance of connectivity manager and get system connectivity service
final ConnectivityManager conman = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
//create instance of class and get name of connectivity manager system service class
final Class conmanClass = Class.forName(conman.getClass().getName());
//create instance of field and get mService Declared field
final Field iConnectivityManagerField= conmanClass.getDeclaredField("mService");
//Attempt to set the value of the accessible flag to true
iConnectivityManagerField.setAccessible(true);
//create instance of object and get the value of field conman
final Object iConnectivityManager = iConnectivityManagerField.get(conman);
//create instance of class and get the name of iConnectivityManager field
final Class iConnectivityManagerClass= Class.forName(iConnectivityManager.getClass().getName());
//create instance of method and get declared method and type
final Method setMobileDataEnabledMethod= iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled",Boolean.TYPE);
//Attempt to set the value of the accessible flag to true
setMobileDataEnabledMethod.setAccessible(true);
//dynamically invoke the iConnectivityManager object according to your need (true/false)
setMobileDataEnabledMethod.invoke(iConnectivityManager, ON);
} catch (Exception e){
}
return true;
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="arun.com.togglebuttonexample.MainActivity">
<TextView
android:id="#+id/TVMobileData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="90dp"
android:text="Mobile Data: Disable"
android:textColor="#1BD6E0"
android:textSize="40sp" />
<ToggleButton
android:id="#+id/tBMobileData"
android:layout_width="225dp"
android:layout_height="225dp"
android:layout_centerInParent="true"
android:textSize="30sp"
android:textOff="Enable"
android:textOn="Disable" />
</RelativeLayout>
AndroidManifest.xml:
<?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="arun.com.togglebuttonexample">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
You can access mobile data on / off programmaticaly below android 4.4 but not above 4.4 as It's require MODIFY_PHONE_STATE permission check. This permission is only given to system or signature apps. so It wont work on non-rooted phone.

Android camera preview stay white, but no crash

I'm trying to create an application with the camera on Android. I used code I was able to found in the android doc, on internet etc. just as test.
The camera preview is still white, nothing crashes tho but no preview at all is showing up. Can't find if it comes from my emulator or my code ... I use integrated Webcam as camera in the emulator.
Any help please ?
here is my camera preview class:
package com.guillaimej.testapplication.app;
import java.io.IOException;
import android.content.Context;
import android.hardware.Camera;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class CameraInputView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraInputView(Context context, Camera camera) {
super(context);
mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
System.out.println("Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
System.out.println("Error starting camera preview: " + e.getMessage());
}
}
}
here is my layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.guillaimej.testapplication.app.CameraInputActivity">
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/camera_layout"
android:layout_weight="0.2">
</FrameLayout>
<ImageButton
android:layout_width="100dp"
android:layout_height="100dp"
android:id="#+id/domygif"
android:layout_gravity="center_horizontal"
android:background="#drawable/flask"
android:clickable="true"
android:onClick="snapIt"
android:layout_weight="0.0"/>
<ImageButton
android:layout_width="60dp"
android:layout_height="60dp"
android:id="#+id/returnButton"
android:layout_gravity="center_horizontal"
android:background="#drawable/return_button"
android:layout_weight="0.0"/>
</LinearLayout>
and here is my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.guillaimej.testapplication.app" >
<uses-sdk android:minSdkVersion="10"
android:targetSdkVersion="10"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".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=".ListOfFileActivity"
android:label="#string/title_activity_list_of_file" >
</activity>
<activity
android:name=".VideoActivity"
android:label="#string/title_activity_video" >
</activity>
<activity
android:name=".CameraInputActivity"
android:label="#string/title_activity_camera_input" >
</activity>
</application>
</manifest>
EDIT:
Here is the activity where I use the camera preview:
package com.guillaimej.testapplication.app;
import android.content.Intent;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.Toast;
import android.view.SurfaceView;
import android.view.SurfaceHolder;
public class CameraInputActivity extends Activity{
private ImageButton returnButton = null;
private ImageButton domygifButton = null;
//private Camera camera = null;
private CameraInputView cameraView;
private SurfaceHolder previewHolder;
private FrameLayout cameraLayout = null;
// Check if the camera is free and return it
private static Camera isCameraAvailable() {
Camera cam = null;
try {
cam = Camera.open(0);
} catch (Exception e) {
}
return cam;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera_input);
returnButton = (ImageButton) findViewById(R.id.returnButton);
returnButton.setOnTouchListener(new ReturnButtonListener());
domygifButton = (ImageButton) findViewById(R.id.domygif);
cameraLayout = (FrameLayout) findViewById(R.id.camera_layout);
Camera camera = isCameraAvailable();
// Create our Preview view and set it as the content of our activity.
cameraView = new CameraInputView(this, camera);
cameraLayout.addView(cameraView);
}
}

Android - Admob test ads not appearing in app

I want to integrate Google Mobile Ads into my app, but when I debug it, whenever using my own device, or using an emulator, no ads appear.
I am using the code from Google's developer page: https://developers.google.com/mobile-ads-sdk/docs/admob/fundamentals
When looking at logcat, I find that my app is not requesting any ads, and Admob is reporting no requests.
What am I missing?
Here is my code
AndroidManifest
<application android:icon="#drawable/ic_launcher">
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version"/>
android:label="#string/app_name" >
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
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>
<activity android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
</application>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
</manifest>
layout - main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/adBanner"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads">
<com.google.ads.AdView android:id="#+id/ad"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
ads:adUnitId="-omitted-"
ads:adSize="BANNER" />
</LinearLayout>
AdBanner.java (the class with Google's example test code)
package com.google.android.gms.ads.banner;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.AdView;
import -omitted-
import android.os.Bundle;
import android.widget.LinearLayout;
import -omitted-
public class AdBanner extends MainActivity{
/**
* A simple {#link Activity} that embeds an AdView.
*/
/** The view to show the ad. */
private AdView adView;
/* Your ad unit id. Replace with your actual ad unit id. */
private static final String AD_UNIT_ID = "-omitted-";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Create an ad.
adView = new AdView(this);
adView.setAdSize(AdSize.BANNER);
adView.setAdUnitId(AD_UNIT_ID);
// Add the AdView to the view hierarchy. The view will have no size
// until the ad is loaded.
LinearLayout layout = (LinearLayout) findViewById(R.id.adBanner);
layout.addView(adView);
// Create an ad request. Check logcat output for the hashed device ID to
// get test ads on a physical device.
AdRequest adRequest = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.addTestDevice("-omitted-")
.build();
// Start loading the ad in the background.
adView.loadAd(adRequest);
}
#Override
public void onResume() {
super.onResume();
if (adView != null) {
adView.resume();
}
}
#Override
public void onPause() {
if (adView != null) {
adView.pause();
}
super.onPause();
}
/** Called before the activity is destroyed. */
#Override
public void onDestroy() {
// Destroy the AdView.
if (adView != null) {
adView.destroy();
}
super.onDestroy();
}
}
I have seen something strange in your code:
In your AdBanner.java you use this:
import com.google.android.gms.ads.AdView;
but in your layout you use:
<com.google.ads.AdView
which corresponds to old Admob, but seems you may want to use com.google.android.gms.ads.AdView in your layout instead
I think you must check the android logs to see if any errors or warnings are given for your admob. For example: I was not able to see the ads too and when i check the logs i found the "not enough space" warning for my advertisement. I was using the size "SMART_BANNER" that uses the width as 360dp (you can check the sizes here). So i changed my AdView's width to exact 360dp to solve my problem and it is now working: Stil
I hope this information helps. Just check the logs and also console.
In addition, my adView:
<com.google.android.gms.ads.AdView
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:id="#+id/adView"
android:layout_width="360dp"
android:layout_height="wrap_content"
ads:adSize="SMART_BANNER"
ads:adUnitId="#string/banner_ad_unit_id" />
Best regards.

Admob + surfaceview don't play well

I'm running Admob 6.0.1 and trying to add the advert over the top of the surface view, I can say that the code below works great with a Android 3.2 (a real device), and also works fine with a android 4 device in the emulator but, when I try to test on pre api13, eg 2.3.3 or below the advert doesn't show. Now here's the weird part, if I change the visibility of the surfaceview (in xml) to invisible the advert will show!!!! what's going on?? Is this just the emulator being buggy or do I have a real problem?
I've tried to keep the code as simple as possible to reproduce the error. I've added a button just to show the surfaceview does allow other views to update, just not the Admob view...
package com.google.example.ads.fundamentals;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import com.google.ads.AdView;
public class BannerSample extends Activity {
/** The view to show the ad. */
private AdView adView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout);
adView = (AdView) findViewById(R.id.adView);
}
/** Called before the activity is destroyed. */
#Override
public void onDestroy() {
// Destroy the AdView.
if (adView != null) {
adView.destroy();
}
super.onDestroy();
}
}
class Panel extends SurfaceView implements SurfaceHolder.Callback {
private final TutorialThread _thread;
public Panel(Context context, AttributeSet att) {
super(context, att);
getHolder().addCallback(this);
_thread = new TutorialThread(getHolder(), this);
}
#Override
public void onDraw(Canvas canvas) {
canvas.drawColor(Color.BLUE);
Log.d("Hello", "drawing stuff");
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Log.d("HELLO", "surface changed" + holder.getSurfaceFrame().width()
+ "Height: " + holder.getSurfaceFrame().height());
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
_thread.setRunning(true);
_thread.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// simply copied from sample application LunarLander:
// we have to tell thread to shut down & wait for it to finish, or
// else
// it might touch the Surface after we return and explode
boolean retry = true;
_thread.setRunning(false);
while (retry) {
try {
_thread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
}
class TutorialThread extends Thread {
private final SurfaceHolder _surfaceHolder;
private final Panel _panel;
private boolean _run = false;
public TutorialThread(SurfaceHolder surfaceHolder, Panel panel) {
_surfaceHolder = surfaceHolder;
_panel = panel;
}
public void setRunning(boolean run) {
_run = run;
}
#Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
_panel.onDraw(c);
}
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
and the XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:layout_width="match_parent" android:layout_height="match_parent">
<com.google.example.ads.fundamentals.Panel
android:id="#+id/mainPanel" android:layout_width="match_parent"
android:layout_height="match_parent" android:visibility="invisible" />
<com.google.ads.AdView android:id="#+id/adView"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_gravity="top" ads:adSize="BANNER" ads:adUnitId="xxxxxxxxx"
ads:loadAdOnCreate="true" ads:testDevices="TEST_EMULATOR" />
<Button android:id="#+id/mybutton" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_below="#id/adView"
android:text="hello" />
</RelativeLayout>
And the manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.example.ads.fundamentals"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="3" android:targetSdkVersion="15" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".BannerSample"
android:screenOrientation="portrait"
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.google.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
Any ideas or help would be so great, I've tried to post on Google Groups for admob but I think it got lost in a void..
As it turns out it was a problem with the emulator, When the code was run on a real device it worked fine! crazy emulator...
Try placing the AdView outside of the SurfaceView instead of on top of it. You can do this by aligning the AdView ad the top, and setting the SurfaceView below it.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:layout_width="match_parent" android:layout_height="match_parent">
<com.google.example.ads.fundamentals.Panel
android:id="#+id/mainPanel" android:layout_width="match_parent"
android:layout_height="match_parent" android:visibility="invisible"
android:layout_below="#+id/adView" />
<com.google.ads.AdView android:id="#id/adView"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_gravity="top" ads:adSize="BANNER" ads:adUnitId="xxxxxxxxx"
ads:loadAdOnCreate="true" ads:testDevices="TEST_EMULATOR"
android:layout_alignParentTop="true" />
</RelativeLayout>

Categories