mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
In demo-misc-vp9-opus-sw removed FilePickerActivity and copied demo player permissions bug fix
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=111689012
This commit is contained in:
parent
b9ec51dbed
commit
86c4fb3ac2
8 changed files with 69 additions and 215 deletions
|
|
@ -44,14 +44,11 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity android:name="com.google.android.exoplayer.demo.vp9opus.VideoPlayer"
|
<activity android:name=".PlayerActivity"
|
||||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:theme="@style/PlayerTheme"/>
|
android:theme="@style/PlayerTheme"/>
|
||||||
|
|
||||||
<activity android:name="com.google.android.exoplayer.demo.vp9opus.FilePickerActivity"
|
|
||||||
android:theme="@android:style/Theme.Dialog"/>
|
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
|
||||||
|
|
@ -57,9 +57,9 @@ public class DashRendererBuilder implements ManifestCallback<MediaPresentationDe
|
||||||
|
|
||||||
private final String manifestUrl;
|
private final String manifestUrl;
|
||||||
private final String userAgent;
|
private final String userAgent;
|
||||||
private final VideoPlayer player;
|
private final PlayerActivity player;
|
||||||
|
|
||||||
public DashRendererBuilder(String manifestUrl, String userAgent, VideoPlayer player) {
|
public DashRendererBuilder(String manifestUrl, String userAgent, PlayerActivity player) {
|
||||||
this.manifestUrl = manifestUrl;
|
this.manifestUrl = manifestUrl;
|
||||||
this.userAgent = userAgent;
|
this.userAgent = userAgent;
|
||||||
this.player = player;
|
this.player = player;
|
||||||
|
|
|
||||||
|
|
@ -1,95 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2014 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package com.google.android.exoplayer.demo.vp9opus;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.ListActivity;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Environment;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple file picker.
|
|
||||||
*/
|
|
||||||
public class FilePickerActivity extends ListActivity {
|
|
||||||
|
|
||||||
public static final String FILENAME_EXTRA_ID = "filename";
|
|
||||||
|
|
||||||
private List<String> listItems;
|
|
||||||
private List<File> itemPaths;
|
|
||||||
private TextView currentPathView;
|
|
||||||
private File root;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.file_picker_activity);
|
|
||||||
setResult(Activity.RESULT_CANCELED);
|
|
||||||
currentPathView = (TextView) findViewById(R.id.path);
|
|
||||||
root = new File(Environment.getExternalStorageDirectory().getPath());
|
|
||||||
setDirectory(root);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setDirectory(File directory) {
|
|
||||||
currentPathView.setText(getString(R.string.current_path, directory.getAbsolutePath()));
|
|
||||||
listItems = new ArrayList<>();
|
|
||||||
itemPaths = new ArrayList<>();
|
|
||||||
File[] files = directory.listFiles();
|
|
||||||
|
|
||||||
if (!directory.getAbsolutePath().equals(root.getAbsolutePath())) {
|
|
||||||
listItems.add(root.getAbsolutePath());
|
|
||||||
itemPaths.add(root);
|
|
||||||
listItems.add("../");
|
|
||||||
itemPaths.add(new File(directory.getParent()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (files != null) {
|
|
||||||
for (File file : files) {
|
|
||||||
if (!file.isHidden() && file.canRead()) {
|
|
||||||
itemPaths.add(file);
|
|
||||||
if (file.isDirectory()) {
|
|
||||||
listItems.add(file.getName() + File.separator);
|
|
||||||
} else {
|
|
||||||
listItems.add(file.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setListAdapter(new ArrayAdapter<>(this, R.layout.rows, listItems));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onListItemClick(ListView l, View v, int position, long id) {
|
|
||||||
File file = itemPaths.get(position);
|
|
||||||
if (file.isDirectory() && file.canRead()) {
|
|
||||||
setDirectory(itemPaths.get(position));
|
|
||||||
} else {
|
|
||||||
Intent intent = new Intent();
|
|
||||||
intent.putExtra(FILENAME_EXTRA_ID, file.getAbsolutePath());
|
|
||||||
setResult(Activity.RESULT_OK, intent);
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -30,8 +30,11 @@ import com.google.android.exoplayer.upstream.DefaultUriDataSource;
|
||||||
import com.google.android.exoplayer.util.PlayerControl;
|
import com.google.android.exoplayer.util.PlayerControl;
|
||||||
import com.google.android.exoplayer.util.Util;
|
import com.google.android.exoplayer.util.Util;
|
||||||
|
|
||||||
|
import android.Manifest.permission;
|
||||||
|
import android.annotation.TargetApi;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
|
@ -39,32 +42,23 @@ import android.view.MotionEvent;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
import android.view.SurfaceView;
|
import android.view.SurfaceView;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.view.View.OnTouchListener;
|
import android.view.View.OnTouchListener;
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.MediaController;
|
import android.widget.MediaController;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sample player that shows how to use ExoPlayer Extensions to playback VP9 Video and Opus Audio.
|
* Sample player that shows how to use ExoPlayer Extensions to playback VP9 Video and Opus Audio.
|
||||||
*/
|
*/
|
||||||
public class VideoPlayer extends Activity implements OnClickListener,
|
public class PlayerActivity extends Activity implements
|
||||||
LibvpxVideoTrackRenderer.EventListener, ExoPlayer.Listener {
|
LibvpxVideoTrackRenderer.EventListener, ExoPlayer.Listener {
|
||||||
|
|
||||||
public static final String DASH_MANIFEST_URL_ID_EXTRA = "manifest_url";
|
|
||||||
public static final String USE_OPENGL_ID_EXTRA = "use_opengl";
|
public static final String USE_OPENGL_ID_EXTRA = "use_opengl";
|
||||||
|
|
||||||
private static final int FILE_PICKER_REQUEST = 1;
|
|
||||||
private static final int BUFFER_SEGMENT_SIZE = 64 * 1024;
|
private static final int BUFFER_SEGMENT_SIZE = 64 * 1024;
|
||||||
private static final int BUFFER_SEGMENT_COUNT = 160;
|
private static final int BUFFER_SEGMENT_COUNT = 160;
|
||||||
|
|
||||||
private boolean isDash;
|
|
||||||
private String manifestUrl;
|
|
||||||
private boolean useOpenGL;
|
private boolean useOpenGL;
|
||||||
private String filename;
|
|
||||||
|
|
||||||
private ExoPlayer player;
|
private ExoPlayer player;
|
||||||
private Handler handler;
|
private Handler handler;
|
||||||
|
|
@ -75,14 +69,14 @@ public class VideoPlayer extends Activity implements OnClickListener,
|
||||||
private TextView debugInfoView;
|
private TextView debugInfoView;
|
||||||
private String debugInfo;
|
private String debugInfo;
|
||||||
private String playerState;
|
private String playerState;
|
||||||
|
private Uri contentUri;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
manifestUrl = intent.getStringExtra(DASH_MANIFEST_URL_ID_EXTRA);
|
contentUri = intent.getData();
|
||||||
isDash = manifestUrl != null;
|
|
||||||
useOpenGL = intent.getBooleanExtra(USE_OPENGL_ID_EXTRA, true);
|
useOpenGL = intent.getBooleanExtra(USE_OPENGL_ID_EXTRA, true);
|
||||||
|
|
||||||
handler = new Handler();
|
handler = new Handler();
|
||||||
|
|
@ -109,16 +103,17 @@ public class VideoPlayer extends Activity implements OnClickListener,
|
||||||
debugInfoView = (TextView) findViewById(R.id.debug_info);
|
debugInfoView = (TextView) findViewById(R.id.debug_info);
|
||||||
debugInfo = "";
|
debugInfo = "";
|
||||||
playerState = "";
|
playerState = "";
|
||||||
filename = "";
|
|
||||||
updateDebugInfoTextView();
|
updateDebugInfoTextView();
|
||||||
|
|
||||||
// Set the buttons' onclick listeners.
|
if (!maybeRequestPermission()) {
|
||||||
((Button) findViewById(R.id.choose_file)).setOnClickListener(this);
|
startPlayback();
|
||||||
((Button) findViewById(R.id.play)).setOnClickListener(this);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// In case of DASH, start playback right away.
|
private void startPlayback() {
|
||||||
if (isDash) {
|
if (Util.isLocalFileUri(contentUri)) {
|
||||||
findViewById(R.id.buttons).setVisibility(View.GONE);
|
startBasicPlayback();
|
||||||
|
} else {
|
||||||
startDashPlayback();
|
startDashPlayback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -129,44 +124,13 @@ public class VideoPlayer extends Activity implements OnClickListener,
|
||||||
stopPlayback();
|
stopPlayback();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
switch (v.getId()) {
|
|
||||||
case R.id.choose_file:
|
|
||||||
Intent intent = new Intent();
|
|
||||||
intent.setClass(this, FilePickerActivity.class);
|
|
||||||
startActivityForResult(intent, FILE_PICKER_REQUEST);
|
|
||||||
break;
|
|
||||||
case R.id.play:
|
|
||||||
startBasicPlayback();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
switch (requestCode) {
|
|
||||||
case FILE_PICKER_REQUEST:
|
|
||||||
if (resultCode == Activity.RESULT_OK) {
|
|
||||||
filename = data.getStringExtra(FilePickerActivity.FILENAME_EXTRA_ID);
|
|
||||||
updateDebugInfoTextView();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startBasicPlayback() {
|
private void startBasicPlayback() {
|
||||||
if (filename == null) {
|
|
||||||
Toast.makeText(this, "Choose a file!", Toast.LENGTH_SHORT).show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
findViewById(R.id.buttons).setVisibility(View.GONE);
|
|
||||||
player = ExoPlayer.Factory.newInstance(2);
|
player = ExoPlayer.Factory.newInstance(2);
|
||||||
player.addListener(this);
|
player.addListener(this);
|
||||||
mediaController.setMediaPlayer(new PlayerControl(player));
|
mediaController.setMediaPlayer(new PlayerControl(player));
|
||||||
mediaController.setEnabled(true);
|
mediaController.setEnabled(true);
|
||||||
ExtractorSampleSource sampleSource = new ExtractorSampleSource(
|
ExtractorSampleSource sampleSource = new ExtractorSampleSource(
|
||||||
Uri.fromFile(new File(filename)),
|
contentUri,
|
||||||
new DefaultUriDataSource(this, Util.getUserAgent(this, "ExoPlayerExtWebMDemo")),
|
new DefaultUriDataSource(this, Util.getUserAgent(this, "ExoPlayerExtWebMDemo")),
|
||||||
new DefaultAllocator(BUFFER_SEGMENT_SIZE), BUFFER_SEGMENT_SIZE * BUFFER_SEGMENT_COUNT,
|
new DefaultAllocator(BUFFER_SEGMENT_SIZE), BUFFER_SEGMENT_SIZE * BUFFER_SEGMENT_COUNT,
|
||||||
new WebmExtractor());
|
new WebmExtractor());
|
||||||
|
|
@ -192,7 +156,8 @@ public class VideoPlayer extends Activity implements OnClickListener,
|
||||||
updateDebugInfoTextView();
|
updateDebugInfoTextView();
|
||||||
final String userAgent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like"
|
final String userAgent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like"
|
||||||
+ " Gecko) Chrome/38.0.2125.104 Safari/537.36";
|
+ " Gecko) Chrome/38.0.2125.104 Safari/537.36";
|
||||||
DashRendererBuilder rendererBuilder = new DashRendererBuilder(manifestUrl, userAgent, this);
|
DashRendererBuilder rendererBuilder = new DashRendererBuilder(contentUri.toString(),
|
||||||
|
userAgent, this);
|
||||||
rendererBuilder.build();
|
rendererBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -269,6 +234,45 @@ public class VideoPlayer extends Activity implements OnClickListener,
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Permission management methods
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(int requestCode, String[] permissions,
|
||||||
|
int[] grantResults) {
|
||||||
|
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
startPlayback();
|
||||||
|
} else {
|
||||||
|
Toast.makeText(getApplicationContext(), R.string.storage_permission_denied,
|
||||||
|
Toast.LENGTH_LONG).show();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether it is necessary to ask for permission to read storage. If necessary, it also
|
||||||
|
* requests permission.
|
||||||
|
*
|
||||||
|
* @return true if a permission request is made. False if it is not necessary.
|
||||||
|
*/
|
||||||
|
@TargetApi(23)
|
||||||
|
private boolean maybeRequestPermission() {
|
||||||
|
if (requiresPermission(contentUri)) {
|
||||||
|
requestPermissions(new String[] {permission.READ_EXTERNAL_STORAGE}, 0);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(23)
|
||||||
|
private boolean requiresPermission(Uri uri) {
|
||||||
|
return Util.SDK_INT >= 23 && Util.isLocalFileUri(uri)
|
||||||
|
&& checkSelfPermission(permission.READ_EXTERNAL_STORAGE)
|
||||||
|
!= PackageManager.PERMISSION_GRANTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal methods
|
||||||
|
|
||||||
private void stopPlayback() {
|
private void stopPlayback() {
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
player.stop();
|
player.stop();
|
||||||
|
|
@ -295,7 +299,7 @@ public class VideoPlayer extends Activity implements OnClickListener,
|
||||||
debugInfoText.append(
|
debugInfoText.append(
|
||||||
getString(R.string.libopus_version, LibopusAudioTrackRenderer.getLibopusVersion()));
|
getString(R.string.libopus_version, LibopusAudioTrackRenderer.getLibopusVersion()));
|
||||||
debugInfoText.append("\n");
|
debugInfoText.append("\n");
|
||||||
debugInfoText.append(getString(R.string.current_path, filename));
|
debugInfoText.append(getString(R.string.current_path, contentUri.toString()));
|
||||||
debugInfoText.append(" ");
|
debugInfoText.append(" ");
|
||||||
debugInfoText.append(debugInfo);
|
debugInfoText.append(debugInfo);
|
||||||
debugInfoText.append(" ");
|
debugInfoText.append(" ");
|
||||||
|
|
@ -18,6 +18,7 @@ package com.google.android.exoplayer.demo.vp9opus;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
@ -41,9 +42,6 @@ public class SampleChooserActivity extends Activity {
|
||||||
ListView sampleList = (ListView) findViewById(R.id.sample_list);
|
ListView sampleList = (ListView) findViewById(R.id.sample_list);
|
||||||
final SampleAdapter sampleAdapter = new SampleAdapter(this);
|
final SampleAdapter sampleAdapter = new SampleAdapter(this);
|
||||||
|
|
||||||
sampleAdapter.add(new Header("Local VP9 Video only"));
|
|
||||||
sampleAdapter.add(new Sample("S/W Color Conversion - upto 720p", false));
|
|
||||||
sampleAdapter.add(new Sample("OpenGL", true));
|
|
||||||
sampleAdapter.add(new Header("DASH - VP9 Only"));
|
sampleAdapter.add(new Header("DASH - VP9 Only"));
|
||||||
sampleAdapter.add(new Sample("Google Glass",
|
sampleAdapter.add(new Sample("Google Glass",
|
||||||
"http://demos.webmproject.org/dash/201410/vp9_glass/manifest_vp9.mpd"));
|
"http://demos.webmproject.org/dash/201410/vp9_glass/manifest_vp9.mpd"));
|
||||||
|
|
@ -67,9 +65,9 @@ public class SampleChooserActivity extends Activity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onSampleSelected(Sample sample) {
|
private void onSampleSelected(Sample sample) {
|
||||||
Intent playerIntent = new Intent(this, VideoPlayer.class)
|
Intent playerIntent = new Intent(this, PlayerActivity.class)
|
||||||
.putExtra(VideoPlayer.DASH_MANIFEST_URL_ID_EXTRA, sample.uri)
|
.setData(Uri.parse(sample.uri))
|
||||||
.putExtra(VideoPlayer.USE_OPENGL_ID_EXTRA, sample.useOpenGL);
|
.putExtra(PlayerActivity.USE_OPENGL_ID_EXTRA, sample.useOpenGL);
|
||||||
startActivity(playerIntent);
|
startActivity(playerIntent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,33 +40,14 @@
|
||||||
</com.google.android.exoplayer.AspectRatioFrameLayout>
|
</com.google.android.exoplayer.AspectRatioFrameLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:background="#88000000">
|
android:background="#88000000">
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/buttons"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/choose_file"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/choose_file"/>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/play"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/play"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/debug_info"
|
android:id="@+id/debug_info"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"/>
|
android:layout_height="wrap_content"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2014 The Android Open Source Project
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/path"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
|
|
||||||
<ListView
|
|
||||||
android:id="@android:id/list"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
@ -28,5 +28,6 @@
|
||||||
<string name="libopus_version">
|
<string name="libopus_version">
|
||||||
Libopus: <xliff:g id="path">%1$s</xliff:g>
|
Libopus: <xliff:g id="path">%1$s</xliff:g>
|
||||||
</string>
|
</string>
|
||||||
|
<string name="storage_permission_denied">Permission to access storage was denied</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue