Android 如果单击后退箭头关闭弹出菜单窗口,如何保持录音机运行
你能帮我做任何循环,直到我按stopRecording。如果我执行onBackPressed()以返回第二个活动,记录器将自动停止。我希望它继续,直到我返回RecorderActivity并自己按下stop 我实现了在PopupMenuWindow中录制的音频,当我单击开始录制并按下后退箭头时,我通过调用Android 如果单击后退箭头关闭弹出菜单窗口,如何保持录音机运行,android,Android,你能帮我做任何循环,直到我按stopRecording。如果我执行onBackPressed()以返回第二个活动,记录器将自动停止。我希望它继续,直到我返回RecorderActivity并自己按下stop 我实现了在PopupMenuWindow中录制的音频,当我单击开始录制并按下后退箭头时,我通过调用finish()使用了此函数onBackPressed()录音机停止录音 这是我使用的代码: //Init View btnPlay = (Button)findViewById
finish()使用了此函数onBackPressed()
代码>录音机停止录音
这是我使用的代码:
//Init View
btnPlay = (Button)findViewById(R.id.btnPlay);
btnStop = (Button) findViewById(R.id.btnStop);
btnStartRecorder = (Button) findViewById(R.id.startRecord);
btnStopRecorder = (Button) findViewById(R.id.stopRecord);
//implementing the actions
btnStartRecorder.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (checkPermissionFromDevice())
{
pathSave = Environment.getExternalStorageDirectory()
.getAbsolutePath()+"/"
+ UUID.randomUUID().toString()+"_audio_record.amr";
setupMediaRecorder();
try {
mediaRecorder.prepare();
mediaRecorder.start();
} catch (IOException e) {
e.printStackTrace();
}
btnPlay.setEnabled(false);
btnStop.setEnabled(false);
btnStopRecorder.setEnabled(true);
Toast.makeText(RecorderActivity.this, "Recording...", Toast.LENGTH_SHORT).show();
}
else {
requestPermission();
}
}
});
btnStopRecorder.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mediaRecorder.stop();
mediaRecorder.release();
btnStopRecorder.setEnabled(false);
btnPlay.setEnabled(true);
btnStartRecorder.setEnabled(true);
btnStop.setEnabled(false);
Toast.makeText(RecorderActivity.this, "Stop Record...", Toast.LENGTH_SHORT).show();
}
});
这是我的RecorderActivity.java,我在这里调用了MyService.java
public class RecorderActivity extends AppCompatActivity {
Button btnStartRecorder, btnStopRecorder, btnPlay, btnStop;
String pathSave = "";
MediaRecorder mediaRecorder;
MediaPlayer mediaPlayer;
final int REQUEST_PERMISSION_CODE = 1000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recorder);
final DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int width = displayMetrics.widthPixels;
int hight = displayMetrics.heightPixels;
getWindow().setLayout((int)(width*.8), (int)(hight*.5));
WindowManager.LayoutParams params = getWindow().getAttributes();
params.gravity = Gravity.CENTER;
params.x = 0;
params.y = -20;
getWindow().setAttributes(params);
// Dismiss popUpMenu Window
ImageButton backButton = (ImageButton) findViewById(R.id.back_arrow_record);
backButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
//Requesting Run-time permission
if (!checkPermissionFromDevice())
requestPermission();
//Init View
btnPlay = (Button)findViewById(R.id.btnPlay);
btnStop = (Button) findViewById(R.id.btnStop);
btnStartRecorder = (Button) findViewById(R.id.startRecord);
btnStopRecorder = (Button) findViewById(R.id.stopRecord);
//implementing the actions
btnStartRecorder.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (checkPermissionFromDevice())
{
Intent i = new Intent(getApplicationContext(), MyService.class);
i.setAction("C.ACTION_START_SERVICE");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(i);
}
else
{
startService(i);
}
Toast.makeText(RecorderActivity.this, "Recording...", Toast.LENGTH_SHORT).show();
}
else {
requestPermission();
}
}
});
btnStopRecorder.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
MyService.mediaRecorder.stop();
pathSave = MyService.pathSave;
stopService(new Intent(RecorderActivity.this, MyService.class));
btnStopRecorder.setEnabled(false);
btnPlay.setEnabled(true);
btnStartRecorder.setEnabled(true);
btnStop.setEnabled(false);
Toast.makeText(RecorderActivity.this, "Stop Record...", Toast.LENGTH_SHORT).show();
}
});
btnPlay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
btnStop.setEnabled(true);
btnStopRecorder.setEnabled(false);
btnStartRecorder.setEnabled(false);
mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(pathSave);
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
Toast.makeText(RecorderActivity.this, "Playing...", Toast.LENGTH_SHORT).show();
}
});
btnStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
btnStopRecorder.setEnabled(false);
btnStartRecorder.setEnabled(true);
btnStop.setEnabled(false);
btnPlay.setEnabled(true);
if (mediaPlayer != null){
mediaPlayer.stop();
mediaPlayer.release();
setupMediaRecorder();
Toast.makeText(RecorderActivity.this, "Stop Playing...", Toast.LENGTH_SHORT).show();
}
}
});
}
private void setupMediaRecorder() {
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setOutputFile(pathSave);
}
private void requestPermission() {
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.RECORD_AUDIO
}, REQUEST_PERMISSION_CODE);
}
//Press Ctr+O
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode){
case REQUEST_PERMISSION_CODE:
{
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show();
else {
Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show();
}
}
break;
}
}
private boolean checkPermissionFromDevice() {
int write_external_storage_result = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
int record_audio_result = ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO);
return write_external_storage_result == PackageManager.PERMISSION_GRANTED &&
record_audio_result == PackageManager.PERMISSION_GRANTED;
}
}
MyService.java代码实现
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import java.io.IOException;
import java.util.UUID;
public class MyService extends Service {
static MediaRecorder mediaRecorder;
static final int NOTIFICATION_ID = 543;
static String pathSave = "";
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O)
startMyOwnForeground();
else
startForeground(1, new Notification());
pathSave = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/"
+ UUID.randomUUID().toString() + "_audio_record.amr";
setupMediaRecorder(); // add this line in your service
try {
mediaRecorder.prepare();
mediaRecorder.start();
Toast.makeText(getApplicationContext(), "Recording...", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}
@RequiresApi(Build.VERSION_CODES.O)
private void startMyOwnForeground() {
String NOTIFICATION_CHANNEL_ID = "example.permanence";
String channelName = "Background Service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
Notification notification = notificationBuilder.setOngoing(true)
.setContentTitle("App is running in background")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
startForeground(2, notification);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
//return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
}
//add this function in your service
private void setupMediaRecorder() {
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setOutputFile(pathSave);
}
}
按照您的指示,我得到了NPE
--------- beginning of crash
2020-09-12 12:25:02.371 24116-24116/com.igbogree.ogneneE/AndroidRuntime: FATAL EXCEPTION: main
Process: com.igbogree.ognene, PID: 24116
java.lang.RuntimeException: Unable to create service com.igbogree.ognene.MyService: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.media.MediaRecorder.prepare()' on a null object reference
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3391)
at android.app.ActivityThread.-wrap4(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1712)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6549)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:888)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.media.MediaRecorder.prepare()' on a null object reference
at com.igbogree.ognene.MyService.onCreate(MyService.java:50)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3381)
at android.app.ActivityThread.-wrap4(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1712)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6549)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:888)
初始化清单中的服务,您必须在下面的开始按钮中调用该服务
Intent i = new Intent(this, AnotherService.class);
i.setAction("C.ACTION_START_SERVICE");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(i);
}
else
{
startService(i);
}
然后,您必须在服务中声明录音机,并按如下方式开始录音
public class AnotherService extends Service {
static MediaRecorder mediaRecorder;
static final int NOTIFICATION_ID = 543;
static String pathSave = "";
public AnotherService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O)
startMyOwnForeground();
else
startForeground(1, new Notification());
pathSave = Environment.getExternalStorageDirectory()
.getAbsolutePath()+"/"
+ UUID.randomUUID().toString()+"_audio_record.amr";
setupMediaRecorder();
try {
mediaRecorder.prepare();
mediaRecorder.start();
Toast.makeText(RecorderActivity.this, "Recording...", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}
@RequiresApi(Build.VERSION_CODES.O)
private void startMyOwnForeground() {
String NOTIFICATION_CHANNEL_ID = "example.permanence";
String channelName = "Background Service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
Notification notification = notificationBuilder.setOngoing(true)
.setContentTitle("App is running in background")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
startForeground(2, notification);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
//return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
}
如果您已经完成了服务,那么您必须在您想要停止的活动中更改停止按钮代码
AnotherService.mediaRecorder.stop();
pathSave = AnotherService.pathSave;
stopService(new Intent(YourActivity.this, AnotherService.class));
致以最诚挚的问候初始化清单中的服务,您必须按下面的“开始”按钮调用该服务
Intent i = new Intent(this, AnotherService.class);
i.setAction("C.ACTION_START_SERVICE");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(i);
}
else
{
startService(i);
}
然后,您必须在服务中声明录音机,并按如下方式开始录音
public class AnotherService extends Service {
static MediaRecorder mediaRecorder;
static final int NOTIFICATION_ID = 543;
static String pathSave = "";
public AnotherService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O)
startMyOwnForeground();
else
startForeground(1, new Notification());
pathSave = Environment.getExternalStorageDirectory()
.getAbsolutePath()+"/"
+ UUID.randomUUID().toString()+"_audio_record.amr";
setupMediaRecorder();
try {
mediaRecorder.prepare();
mediaRecorder.start();
Toast.makeText(RecorderActivity.this, "Recording...", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}
@RequiresApi(Build.VERSION_CODES.O)
private void startMyOwnForeground() {
String NOTIFICATION_CHANNEL_ID = "example.permanence";
String channelName = "Background Service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
Notification notification = notificationBuilder.setOngoing(true)
.setContentTitle("App is running in background")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
startForeground(2, notification);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
//return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
}
如果您已经完成了服务,那么您必须在您想要停止的活动中更改停止按钮代码
AnotherService.mediaRecorder.stop();
pathSave = AnotherService.pathSave;
stopService(new Intent(YourActivity.this, AnotherService.class));
致以最诚挚的问候我已经更新了关于我如何执行您指示的OP。当我测试时,我得到了Nul pointerException。请纠正我。把你的录音机放好;从您的活动到服务,您可以提交行以检查我已在OP上发布了完整代码。请检查并在您的答案中更正我。所以我会花时间去了解你是怎么做到的。感谢来到这里,因为梅可以离开承诺,这可以帮助你找到changingRafaqat,你很有学问!!你应该得到一瓶冰镇啤酒。非常感谢你!我欠你很多。上帝保佑你。我将尽我最大的努力在我的MediaPlayer上实现这项服务,它有13个播放按钮和1个停止按钮。我已经更新了关于我如何执行您的指令的OP。当我测试时,我得到了Nul pointerException。请纠正我。把你的录音机放好;从您的活动到服务,您可以提交行以检查我已在OP上发布了完整代码。请检查并在您的答案中更正我。所以我会花时间去了解你是怎么做到的。感谢来到这里,因为梅可以离开承诺,这可以帮助你找到changingRafaqat,你很有学问!!你应该得到一瓶冰镇啤酒。非常感谢你!我欠你很多。上帝保佑你。我会尽力在我的MediaPlayer上实现这项服务,它有13个播放按钮和1个停止按钮。